Compare commits
373 commits
feature/tr
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
503e66a500 | ||
|
acfd46aa60 | ||
|
48e4132996 | ||
|
887143a14e | ||
|
76f3181891 | ||
|
37449fabd9 | ||
|
f2650e5b94 | ||
|
6c993f96fb | ||
|
b9879e1a98 | ||
|
15d224e417 | ||
|
cc24111c05 | ||
|
4b2ca1d0b9 | ||
|
bc979883c2 | ||
|
dbef6a2c93 | ||
|
53fa634908 | ||
|
92fc3e8bcb | ||
|
d02b40dce8 | ||
|
8f378b41c8 | ||
|
3ca6b84edf | ||
|
7d2a1d4af6 | ||
|
5ab0d05768 | ||
|
05da9151ee | ||
|
25e155be4e | ||
|
b4e9ceabd5 | ||
|
a487762b2a | ||
|
92baec5cfa | ||
|
494cc554b2 | ||
|
89746cf1fc | ||
|
6c459dc746 | ||
|
71b6354cd0 | ||
|
c2267a1d55 | ||
|
2d9c701c37 | ||
|
bceb096e69 | ||
|
d0373af5c0 | ||
|
bbc22571ec | ||
|
b6b0e5da13 | ||
|
a721fb0bc7 | ||
|
d70e48eb24 | ||
|
2cded08ce4 | ||
|
253ac0790a | ||
|
1a348179dd | ||
|
f82a420b87 | ||
|
b5b05286e9 | ||
|
47cc1770c5 | ||
|
d627251a32 | ||
|
9353f06df6 | ||
|
13d78403fd | ||
|
014025df5a | ||
|
d848620975 | ||
|
e104409d52 | ||
|
46499c0f26 | ||
|
b80a00065b | ||
|
81fb2d4cae | ||
|
a8c60e0960 | ||
|
8bec6e0e81 | ||
|
59cb689a45 | ||
|
4d072e20ed | ||
|
7a8ee567b6 | ||
|
07772c643d | ||
|
f89ba44f6e | ||
|
88ff263f92 | ||
|
e3a7ee66cd | ||
|
14c9e8ae6a | ||
|
6db65e8a7a | ||
|
56f7fd2229 | ||
|
024fbd0cf2 | ||
|
5fb2e94fed | ||
|
c8c7f97290 | ||
|
c4fbd770ad | ||
|
fdd3b6e20c | ||
|
a16997dee1 | ||
|
af52af782f | ||
|
b4271792b9 | ||
|
d9c5f2eaa2 | ||
|
c3b7a01891 | ||
|
eed96df5dd | ||
|
090db8da5e | ||
|
182258e2c3 | ||
|
6be0b6b20e | ||
|
93d43d7825 | ||
|
4dc7d825bc | ||
|
10f361c8ca | ||
|
2985d1d11e | ||
|
233f9a6a31 | ||
|
ee001e0231 | ||
|
efff445a03 | ||
|
5830e001cf | ||
|
6db5525fbb | ||
|
61d3f5b445 | ||
|
a8c0e44cc7 | ||
|
2b818ab6e3 | ||
|
c183804aa2 | ||
|
46559496c6 | ||
|
cec6b7c19f | ||
|
782eaabb97 | ||
|
3b5510dce1 | ||
|
4581999feb | ||
|
b43c3cee2d | ||
|
0fa4213577 | ||
|
de426c08b6 | ||
|
9277bea8c9 | ||
|
524a98ed1a | ||
|
1ef7e85e05 | ||
|
94047dd765 | ||
|
ace502a533 | ||
|
05af33fe0d | ||
|
a6fa0ee497 | ||
|
e43329cbc7 | ||
|
8cb769d55d | ||
|
6dde352842 | ||
|
a89417e26e | ||
|
5c18d42c8d | ||
|
f296f4d91e | ||
|
7707f4f905 | ||
|
4bc6032fa6 | ||
|
b77380bad1 | ||
|
33082ba2c9 | ||
|
f9ae521710 | ||
|
4a1b600be4 | ||
|
ed1a6cc6f3 | ||
|
8d4b4aa7a3 | ||
|
dccf3fc7b9 | ||
|
49343e9c68 | ||
|
33147ae77f | ||
|
8fc06b9b57 | ||
|
875aaabebe | ||
|
a3d94f168b | ||
|
4b6513f5a1 | ||
|
59c3ae3e5d | ||
|
5750b9d91f | ||
|
3c81f7d587 | ||
|
5f8b3d43c7 | ||
|
6b43a1caa1 | ||
|
c31d392f9a | ||
|
c3eaaa7043 | ||
|
63af6f4cc4 | ||
|
42e342e3dd | ||
|
13db675ac6 | ||
|
8325bb87c5 | ||
|
37230b2de6 | ||
|
a4de9dd4f1 | ||
|
812794f7d9 | ||
|
f5bbff8b87 | ||
|
39957e6203 | ||
|
7fed013453 | ||
|
4715d5e8ff | ||
|
9dee6f3fff | ||
|
c3dbac37ef | ||
|
524f8b953f | ||
|
4ec3659a04 | ||
|
e5e902589c | ||
|
2d22be9bac | ||
|
3dd347ca55 | ||
|
3b2e0773ca | ||
|
132391752e | ||
|
126fbc20a7 | ||
|
a922ea0383 | ||
|
543b4198b2 | ||
|
131da5b4f2 | ||
|
f671f31b96 | ||
|
ff18dead52 | ||
|
fa5fe85d3a | ||
|
342ba29b63 | ||
|
59a4d85663 | ||
|
ca0b5da905 | ||
|
f0425e7abd | ||
|
07f3c08244 | ||
|
aa0b7f5005 | ||
|
c3ae04c93f | ||
|
642e98e0b3 | ||
|
48a33e6c2e | ||
|
f0d2c34399 | ||
|
8ae8019045 | ||
|
724bf797b1 | ||
|
f27bc0f452 | ||
|
c1937ea754 | ||
|
36322def89 | ||
|
95ff7ef378 | ||
|
e9d9201527 | ||
|
7f010ef1fe | ||
|
89c6c410ff | ||
|
0a07fe11e5 | ||
|
85338ee672 | ||
|
61f23d0cf4 | ||
|
2f62c6e9df | ||
|
d178d36e0e | ||
|
44d44a2cc5 | ||
|
c4dcfb1cac | ||
|
1d77f3ec1f | ||
|
d41c0f1d72 | ||
|
4ae2a6cdf0 | ||
|
776656d79b | ||
|
c2eed89318 | ||
|
69220ee866 | ||
|
a7f7f5c01c | ||
|
d05d3020eb | ||
|
6faf7c569d | ||
|
f67495f4f0 | ||
|
3214c13fbc | ||
|
962196ef1d | ||
|
a0f846013c | ||
|
8354c03a12 | ||
|
9b4a58c8e1 | ||
|
0e6694144f | ||
|
8a9c3fd9e8 | ||
|
691cf4ed62 | ||
|
e0410b2c5d | ||
|
1d3ca574f1 | ||
|
f9d639f7f4 | ||
|
f8c87c3d6c | ||
|
7cd1afc52d | ||
|
09b8b8087c | ||
|
d36e9d65a0 | ||
|
ac6797e916 | ||
|
5fa48d0298 | ||
|
8a474d749d | ||
|
ebdd2f983b | ||
|
60b671ea44 | ||
|
87a3503f93 | ||
|
b520735d20 | ||
|
62d99e1554 | ||
|
715bc8148c | ||
|
cb4ea206fa | ||
|
260dd1bde8 | ||
|
b58cd12f85 | ||
|
e3403eb5db | ||
|
e24b6579ff | ||
|
68cc1451b2 | ||
|
546cc47121 | ||
|
70aa7a90a5 | ||
|
6080bb6ef2 | ||
|
1e76ce25d5 | ||
|
5e92d55af5 | ||
|
0a1fd09459 | ||
|
893f715852 | ||
|
730a0f40c7 | ||
|
49f7951013 | ||
|
f5817aef01 | ||
|
b83c2629b9 | ||
|
d100f42b1f | ||
|
1bfa6c4364 | ||
|
fea8a3f4e7 | ||
|
29da4e9279 | ||
|
87994d3bb4 | ||
|
0d5e3bb663 | ||
|
b79da1f1f1 | ||
|
5aabd643da | ||
|
56a73454dd | ||
|
55958b8bc3 | ||
|
b6fc58b743 | ||
|
3dbf129fa1 | ||
|
326708c903 | ||
|
8b0a1ae362 | ||
|
af4ac44cb5 | ||
|
cd23acaa4a | ||
|
1cfded6389 | ||
|
17eb160be7 | ||
|
5583543f14 | ||
|
ec5dabd237 | ||
|
4838072ecf | ||
|
42ccb47eb3 | ||
|
674c450416 | ||
|
077fe622da | ||
|
8ce00cdf21 | ||
|
f51becd0a7 | ||
|
9347a6b165 | ||
|
30920ce4ec | ||
|
afa834a805 | ||
|
9523e872f8 | ||
|
29b9054cb1 | ||
|
1544768025 | ||
|
3c050bc4d1 | ||
|
6a0da03809 | ||
|
9e302c59ed | ||
|
e17b1a5db6 | ||
|
ee7bd87011 | ||
|
497b4e607b | ||
|
11ea727efa | ||
|
178d0e381c | ||
|
4737e3b438 | ||
|
a0297eb3af | ||
|
c1747fb8da | ||
|
67cd7bc031 | ||
|
49a0a74ae2 | ||
|
ca110fa645 | ||
|
abe3b8fd68 | ||
|
91e89001c3 | ||
|
ce298e1e23 | ||
|
5e3e69ba02 | ||
|
857b8002e0 | ||
|
577d5e6895 | ||
|
c3482a8c01 | ||
|
5e04c890d1 | ||
|
dbcb707c1c | ||
|
4b0acbe8bf | ||
|
c90362621a | ||
|
b982a132ae | ||
|
55e08de21c | ||
|
852ed2f1ad | ||
|
b3f658bdbf | ||
|
31ef50c9a9 | ||
|
a91ec6eb61 | ||
|
07ca0d2e9e | ||
|
67a0cfbf8e | ||
|
8b5ee93b55 | ||
|
813477aa8a | ||
|
1575bac0c7 | ||
|
03597d9162 | ||
|
32328713f5 | ||
|
9300729533 | ||
|
1457a3ed19 | ||
|
20674f8470 | ||
|
65a0c95b13 | ||
|
6b0547b963 | ||
|
fda5d0b942 | ||
|
f51a2109b1 | ||
|
eb5fa3d405 | ||
|
c415d49f1e | ||
|
398ed46776 | ||
|
54ce6bbe1c | ||
|
87b4befd87 | ||
|
c21f70366f | ||
|
3b5397f2a4 | ||
|
bce2139f06 | ||
|
f64935eb1d | ||
|
ebfbc1144c | ||
|
2b915c11c7 | ||
|
5eae1664e5 | ||
|
14c8ff57ca | ||
|
0b063730f3 | ||
|
b675ae6f29 | ||
|
34d783a289 | ||
|
44124409e4 | ||
|
8f5d49de81 | ||
|
e96fb4242e | ||
|
97268eff29 | ||
|
dc9b6a2988 | ||
|
7432c019f7 | ||
|
61c3d509e5 | ||
|
8767a8a0a9 | ||
|
47cd73ae02 | ||
|
762f73515b | ||
|
61caf8c9f4 | ||
|
1662892196 | ||
|
d50294b590 | ||
|
199237ec6e | ||
|
c3b6aff41d | ||
|
a61af52d96 | ||
|
53f85d0a2c | ||
|
b807eefeaf | ||
|
2d933cf0e4 | ||
|
20ab2176fb | ||
|
f19fdc37be | ||
|
71bce674a0 | ||
|
4d00566421 | ||
|
3ea18e74da | ||
|
5c885c7722 | ||
|
e7e6df6358 | ||
|
df76e77598 | ||
|
ca6c6e1d3e | ||
|
4f58059472 | ||
|
0d9094e443 | ||
|
690a4793a6 | ||
|
6bd2d15d23 | ||
|
ec4368d9ae | ||
|
16b38f94b0 | ||
|
f10c6ed4ce | ||
|
b39df7f91e | ||
|
438a7582bf | ||
|
6481f71ce0 | ||
|
1728ef3dfc | ||
|
0dadda86de | ||
|
e48910ea3b |
637 changed files with 231932 additions and 50497 deletions
29
.gitmodules
vendored
29
.gitmodules
vendored
|
@ -1,6 +1,6 @@
|
|||
[submodule "lwip/lwip"]
|
||||
path = lwip/lwip
|
||||
url = https://github.com/SuperHouse/esp-lwip.git
|
||||
url = https://github.com/ourairquality/lwip.git
|
||||
[submodule "extras/mbedtls/mbedtls"]
|
||||
path = extras/mbedtls/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
|
@ -19,3 +19,30 @@
|
|||
[submodule "tests/fs-test"]
|
||||
path = tests/fs-test
|
||||
url = https://github.com/sheinz/fs-test
|
||||
[submodule "extras/bearssl/BearSSL"]
|
||||
path = extras/bearssl/BearSSL
|
||||
url = https://www.bearssl.org/git/BearSSL
|
||||
[submodule "extras/http-parser/http-parser"]
|
||||
path = extras/http-parser/http-parser
|
||||
url = https://github.com/nodejs/http-parser
|
||||
[submodule "extras/crc_generic/crc_lib"]
|
||||
path = extras/crc_generic/crc_lib
|
||||
url = https://github.com/Zaltora/crc_generic_lib.git
|
||||
[submodule "extras/libesphttpd/libesphttpd"]
|
||||
path = extras/libesphttpd/libesphttpd
|
||||
url = https://github.com/nochkin/libesphttpd
|
||||
[submodule "extras/libesphttpd/libesphttpd/lib/heatshrink"]
|
||||
path = extras/libesphttpd/libesphttpd/lib/heatshrink
|
||||
url = https://github.com/atomicobject/heatshrink
|
||||
[submodule "extras/multipwm"]
|
||||
path = extras/multipwm
|
||||
url = https://github.com/nochkin/multipwm
|
||||
[submodule "lvgl/lvgl"]
|
||||
path = lvgl/lvgl
|
||||
url = https://github.com/littlevgl/lvgl.git
|
||||
[submodule "lvgl/lv_drivers"]
|
||||
path = lvgl/lv_drivers
|
||||
url = https://github.com/littlevgl/lv_drivers.git
|
||||
[submodule "lvgl/lv_examples"]
|
||||
path = lvgl/lv_examples
|
||||
url = https://github.com/littlevgl/lv_examples.git
|
||||
|
|
15
.travis.yml
15
.travis.yml
|
@ -2,7 +2,7 @@ language: c
|
|||
sudo: false
|
||||
env:
|
||||
# Target commit for https://github.com/pfalcon/esp-open-sdk/
|
||||
OPENSDK_COMMIT=a48b12f
|
||||
OPENSDK_COMMIT=b069537
|
||||
CROSS_ROOT="${HOME}/toolchain-${OPENSDK_COMMIT}"
|
||||
CROSS_BINDIR="${CROSS_ROOT}/bin"
|
||||
CROSS="ccache xtensa-lx106-elf-"
|
||||
|
@ -12,7 +12,6 @@ cache:
|
|||
directories:
|
||||
- ${CROSS_ROOT}
|
||||
addons:
|
||||
ssh_known_hosts: 195.138.84.66
|
||||
apt:
|
||||
packages:
|
||||
- make
|
||||
|
@ -30,17 +29,15 @@ addons:
|
|||
- libncurses5-dev
|
||||
- libexpat1-dev
|
||||
- python
|
||||
- python-serial
|
||||
- python-pip
|
||||
- sed
|
||||
- git
|
||||
- help2man
|
||||
- vim-common
|
||||
- zlib1g-dev
|
||||
|
||||
before_install:
|
||||
- openssl aes-256-cbc -K $encrypted_709d8233e262_key -iv $encrypted_709d8233e262_iv
|
||||
-in utils/travis_tests/sheinz_rsa.enc -out /tmp/sheinz_rsa -d
|
||||
- eval "$(ssh-agent -s)"
|
||||
- chmod 600 /tmp/sheinz_rsa
|
||||
- ssh-add /tmp/sheinz_rsa
|
||||
- pip install --user pyserial
|
||||
- travis_wait 30 utils/travis_build/install_toolchain.sh
|
||||
|
||||
script:
|
||||
|
@ -51,5 +48,3 @@ script:
|
|||
- ( ${MAKE_CMD} ) || ( ${MAKE_CMD} V=1 )
|
||||
# build bootloader
|
||||
- make -C bootloader/
|
||||
# run tests
|
||||
- ./utils/travis_tests/run_tests.sh
|
||||
|
|
|
@ -1,440 +1,37 @@
|
|||
The FreeRTOS.org source code is licensed by the *modified* GNU General Public
|
||||
License (GPL), text provided below. A special exception to the GPL is
|
||||
included to allow you to distribute a combined work that includes FreeRTOS
|
||||
without being obliged to provide the source code for any proprietary
|
||||
components. See the licensing section of http://www.FreeRTOS.org for full
|
||||
details. The exception text is also included at the bottom of this file.
|
||||
The FreeRTOS kernel is released under the MIT open source license, the text of
|
||||
which is provided below.
|
||||
|
||||
This license covers the FreeRTOS kernel source files, which are located in the
|
||||
/FreeRTOS/Source directory of the official FreeRTOS kernel download. It also
|
||||
covers most of the source files in the demo application projects, which are
|
||||
located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The
|
||||
demo projects may also include third party software that is not part of FreeRTOS
|
||||
and is licensed separately to FreeRTOS. Examples of third party software
|
||||
includes header files provided by chip or tools vendors, linker scripts,
|
||||
peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS
|
||||
directory is either open source or distributed with permission, and is free for
|
||||
use. For the avoidance of doubt, refer to the comments at the top of each
|
||||
source file.
|
||||
|
||||
|
||||
License text:
|
||||
-------------
|
||||
|
||||
Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
The FreeRTOS download also includes demo application source code, some of
|
||||
which is provided by third parties AND IS LICENSED SEPARATELY FROM FREERTOS.
|
||||
|
||||
For the avoidance of any doubt refer to the comment included at the top
|
||||
of each source and header file for license and copyright information.
|
||||
|
||||
This is a list of files for which Real Time Engineers Ltd are not the
|
||||
copyright owner and are NOT COVERED BY THE GPL.
|
||||
|
||||
|
||||
1) Various header files provided by silicon manufacturers and tool vendors
|
||||
that define processor specific memory addresses and utility macros.
|
||||
Permission has been granted by the various copyright holders for these
|
||||
files to be included in the FreeRTOS download. Users must ensure license
|
||||
conditions are adhered to for any use other than compilation of the
|
||||
FreeRTOS demo applications.
|
||||
|
||||
2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
|
||||
Users must ensure the open source license conditions stated at the top
|
||||
of each uIP source file is understood and adhered to.
|
||||
|
||||
3) The lwIP TCP/IP stack the copyright of which is held by the Swedish
|
||||
Institute of Computer Science. Users must ensure the open source license
|
||||
conditions stated at the top of each lwIP source file is understood and
|
||||
adhered to.
|
||||
|
||||
4) Various peripheral driver source files and binaries provided by silicon
|
||||
manufacturers and tool vendors. Permission has been granted by the
|
||||
various copyright holders for these files to be included in the FreeRTOS
|
||||
download. Users must ensure license conditions are adhered to for any
|
||||
use other than compilation of the FreeRTOS demo applications.
|
||||
|
||||
5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code,
|
||||
which are slightly modified versions of code provided by and copyright to
|
||||
Tern Inc.
|
||||
|
||||
Errors and omissions should be reported to Richard Barry, contact details for
|
||||
whom can be obtained from http://www.FreeRTOS.org.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The GPL license text follows.
|
||||
|
||||
A special exception to the GPL is included to allow you to distribute a
|
||||
combined work that includes FreeRTOS without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details. The exception text is also
|
||||
included at the bottom of this file.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License** as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
The FreeRTOS GPL Exception Text:
|
||||
|
||||
Any FreeRTOS source code, whether modified or in it's original release form,
|
||||
or whether in whole or in part, can only be distributed by you under the terms
|
||||
of the GNU General Public License plus this exception. An independent module is
|
||||
a module which is not derived from or based on FreeRTOS.
|
||||
|
||||
Clause 1:
|
||||
|
||||
Linking FreeRTOS statically or dynamically with other modules is making a
|
||||
combined work based on FreeRTOS. Thus, the terms and conditions of the GNU
|
||||
General Public License cover the whole combination.
|
||||
|
||||
As a special exception, the copyright holder of FreeRTOS gives you permission
|
||||
to link FreeRTOS with independent modules that communicate with FreeRTOS
|
||||
solely through the FreeRTOS API interface, regardless of the license terms of
|
||||
these independent modules, and to copy and distribute the resulting combined
|
||||
work under terms of your choice, provided that
|
||||
|
||||
+ Every copy of the combined work is accompanied by a written statement that
|
||||
details to the recipient the version of FreeRTOS used and an offer by yourself
|
||||
to provide the FreeRTOS source code (including any modifications you may have
|
||||
made) should the recipient request it.
|
||||
|
||||
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
|
||||
|
||||
+ The independent modules add significant and primary functionality to FreeRTOS
|
||||
and do not merely extend the existing functionality already present in FreeRTOS.
|
||||
|
||||
Clause 2:
|
||||
|
||||
FreeRTOS may not be used for any competitive or comparative purpose, including the
|
||||
publication of any form of run time or compile time metric, without the express
|
||||
permission of Real Time Engineers Ltd. (this is the norm within the industry and
|
||||
is intended to ensure information accuracy).
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
@ -302,7 +260,7 @@ CRCB_t *pxCRCB;
|
|||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||
|
||||
/* Is the co-routine waiting on an event also? */
|
||||
if( pxCRCB->xEventListItem.pvContainer )
|
||||
if( pxCRCB->xEventListItem.pxContainer )
|
||||
{
|
||||
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||
}
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
@ -81,11 +39,11 @@ task.h is included from an application file. */
|
|||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
||||
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
||||
header files above, but not in this file, in order to generate the correct
|
||||
privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
for the header files above, but not in this file, in order to generate the
|
||||
correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
||||
|
||||
/* The following bit fields convey control information in a task's event list
|
||||
item value. It is important they don't clash with the
|
||||
|
@ -102,7 +60,7 @@ taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
|||
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||
#endif
|
||||
|
||||
typedef struct xEventGroupDefinition
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
EventBits_t uxEventBits;
|
||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||
|
@ -139,8 +97,18 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
|||
/* A StaticEventGroup_t object must be provided. */
|
||||
configASSERT( pxEventGroupBuffer );
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
variable of type StaticEventGroup_t equals the size of the real
|
||||
event group structure. */
|
||||
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* The user has provided a statically allocated event group - use it. */
|
||||
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
|
@ -160,10 +128,13 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
|||
}
|
||||
else
|
||||
{
|
||||
/* xEventGroupCreateStatic should only ever be called with
|
||||
pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||
allocated) StaticEventGroup_t variable. */
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
}
|
||||
|
||||
return ( EventGroupHandle_t ) pxEventBits;
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
@ -175,8 +146,20 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
|||
{
|
||||
EventGroup_t *pxEventBits;
|
||||
|
||||
/* Allocate the event group. */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
||||
/* Allocate the event group. Justification for MISRA deviation as
|
||||
follows: pvPortMalloc() always ensures returned memory blocks are
|
||||
aligned per the requirements of the MCU stack. In this case
|
||||
pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||
alignment requirements of the EventGroup_t structure - which (if you
|
||||
follow it through) is the alignment requirements of the TickType_t type
|
||||
(EventBits_t being of TickType_t itself). Therefore, whenever the
|
||||
stack alignment requirements are greater than or equal to the
|
||||
TickType_t alignment requirements the cast is safe. In other cases,
|
||||
where the natural word size of the architecture is less than
|
||||
sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
||||
or more reads operations, and the alignment requirements is only that
|
||||
of each individual read. */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
|
@ -196,10 +179,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
|||
}
|
||||
else
|
||||
{
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
|
||||
}
|
||||
|
||||
return ( EventGroupHandle_t ) pxEventBits;
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
@ -208,7 +191,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
|||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||
{
|
||||
EventBits_t uxOriginalBitValue, uxReturn;
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
BaseType_t xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
||||
|
@ -259,6 +242,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
/* The rendezvous bits were not set, but no block time was
|
||||
specified - just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,13 +301,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
|
||||
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||
{
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn, uxControlBits = 0;
|
||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
@ -368,6 +355,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
/* The wait condition has not been met, but no block time was
|
||||
specified, so just return the current value. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -449,11 +437,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -465,13 +451,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
|||
}
|
||||
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||
{
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
/* Check the user is not attempting to clear the bits used by the kernel
|
||||
|
@ -503,7 +492,7 @@ EventBits_t uxReturn;
|
|||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
@ -514,7 +503,7 @@ EventBits_t uxReturn;
|
|||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t const * const pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
@ -524,16 +513,16 @@ EventBits_t uxReturn;
|
|||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
||||
{
|
||||
ListItem_t *pxListItem, *pxNext;
|
||||
ListItem_t const *pxListEnd;
|
||||
List_t *pxList;
|
||||
List_t const * pxList;
|
||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
BaseType_t xMatchFound = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to set the bits used by the kernel
|
||||
|
@ -542,7 +531,7 @@ BaseType_t xMatchFound = pdFALSE;
|
|||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
@ -602,7 +591,7 @@ BaseType_t xMatchFound = pdFALSE;
|
|||
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||
that is was unblocked due to its required bits matching, rather
|
||||
than because it timed out. */
|
||||
( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||
|
@ -623,7 +612,7 @@ BaseType_t xMatchFound = pdFALSE;
|
|||
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
|
||||
vTaskSuspendAll();
|
||||
|
@ -634,8 +623,8 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
|||
{
|
||||
/* Unblock the task, returning 0 as the event list is being deleted
|
||||
and cannot therefore have any bits set. */
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
|
@ -667,7 +656,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
|||
an interrupt. */
|
||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||
{
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -675,7 +664,7 @@ void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet
|
|||
an interrupt. */
|
||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
||||
{
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -721,7 +710,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
|||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
@ -734,7 +723,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
|||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
||||
{
|
||||
UBaseType_t xReturn;
|
||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
|
||||
if( xEventGroup == NULL )
|
||||
{
|
||||
|
@ -748,5 +737,17 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
|||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
||||
{
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#define INC_FREERTOS_H
|
||||
|
@ -126,6 +84,10 @@ extern "C" {
|
|||
#error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#if configMAX_PRIORITIES < 1
|
||||
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_PREEMPTION
|
||||
#error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
@ -142,10 +104,6 @@ extern "C" {
|
|||
#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||
#endif
|
||||
|
||||
#ifndef configMAX_PRIORITIES
|
||||
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_CO_ROUTINES
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#endif
|
||||
|
@ -198,6 +156,10 @@ extern "C" {
|
|||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_uxTaskGetStackHighWaterMark2
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_eTaskGetState
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#endif
|
||||
|
@ -396,6 +358,14 @@ extern "C" {
|
|||
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_QUEUE_PEEK
|
||||
/* Task is about to block because it cannot read from a
|
||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||
task that attempted the read. */
|
||||
#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_QUEUE_SEND
|
||||
/* Task is about to block because it cannot write to a
|
||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
|
@ -408,6 +378,14 @@ extern "C" {
|
|||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#endif
|
||||
|
||||
#ifndef configRECORD_STACK_HIGH_ADDRESS
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 0
|
||||
#endif
|
||||
|
||||
#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H
|
||||
#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0
|
||||
#endif
|
||||
|
||||
/* The following event macros are embedded in the kernel API calls. */
|
||||
|
||||
#ifndef traceMOVED_TASK_TO_READY_STATE
|
||||
|
@ -474,6 +452,10 @@ extern "C" {
|
|||
#define traceQUEUE_PEEK( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceQUEUE_PEEK_FAILED
|
||||
#define traceQUEUE_PEEK_FAILED( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceQUEUE_PEEK_FROM_ISR
|
||||
#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
|
||||
#endif
|
||||
|
@ -658,6 +640,58 @@ extern "C" {
|
|||
#define traceTASK_NOTIFY_GIVE_FROM_ISR()
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_CREATE_FAILED
|
||||
#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
|
||||
#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_CREATE
|
||||
#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_DELETE
|
||||
#define traceSTREAM_BUFFER_DELETE( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_RESET
|
||||
#define traceSTREAM_BUFFER_RESET( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND
|
||||
#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_SEND
|
||||
#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_SEND_FAILED
|
||||
#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR
|
||||
#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
|
||||
#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_RECEIVE
|
||||
#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED
|
||||
#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
|
||||
#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength )
|
||||
#endif
|
||||
|
||||
#ifndef configGENERATE_RUN_TIME_STATS
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#endif
|
||||
|
@ -708,6 +742,10 @@ extern "C" {
|
|||
#define configUSE_TICKLESS_IDLE 0
|
||||
#endif
|
||||
|
||||
#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING
|
||||
#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x )
|
||||
#endif
|
||||
|
||||
#ifndef configPRE_SLEEP_PROCESSING
|
||||
#define configPRE_SLEEP_PROCESSING( x )
|
||||
#endif
|
||||
|
@ -724,6 +762,10 @@ extern "C" {
|
|||
#define portTASK_USES_FLOATING_POINT()
|
||||
#endif
|
||||
|
||||
#ifndef portALLOCATE_SECURE_CONTEXT
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_TIME_SLICING
|
||||
#define configUSE_TIME_SLICING 1
|
||||
#endif
|
||||
|
@ -768,6 +810,10 @@ extern "C" {
|
|||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_POSIX_ERRNO
|
||||
#define configUSE_POSIX_ERRNO 0
|
||||
#endif
|
||||
|
||||
#ifndef portTICK_TYPE_IS_ATOMIC
|
||||
#define portTICK_TYPE_IS_ATOMIC 0
|
||||
#endif
|
||||
|
@ -782,6 +828,19 @@ extern "C" {
|
|||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#endif
|
||||
|
||||
#ifndef configSTACK_DEPTH_TYPE
|
||||
/* Defaults to uint16_t for backward compatibility, but can be overridden
|
||||
in FreeRTOSConfig.h if uint16_t is too restrictive. */
|
||||
#define configSTACK_DEPTH_TYPE uint16_t
|
||||
#endif
|
||||
|
||||
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE
|
||||
/* Defaults to size_t for backward compatibility, but can be overridden
|
||||
in FreeRTOSConfig.h if lengths will always be less than the number of bytes
|
||||
in a size_t. */
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
#endif
|
||||
|
||||
/* Sanity check the configuration. */
|
||||
#if( configUSE_TICKLESS_IDLE != 0 )
|
||||
#if( INCLUDE_vTaskSuspend != 1 )
|
||||
|
@ -797,6 +856,10 @@ extern "C" {
|
|||
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
|
||||
#endif
|
||||
|
||||
#ifndef configINITIAL_TICK_COUNT
|
||||
#define configINITIAL_TICK_COUNT 0
|
||||
#endif
|
||||
|
||||
#if( portTICK_TYPE_IS_ATOMIC == 0 )
|
||||
/* Either variables of tick type cannot be read atomically, or
|
||||
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
||||
|
@ -820,6 +883,32 @@ V8 if desired. */
|
|||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#endif
|
||||
|
||||
#ifndef configPRINTF
|
||||
/* configPRINTF() was not defined, so define it away to nothing. To use
|
||||
configPRINTF() then define it as follows (where MyPrintFunction() is
|
||||
provided by the application writer):
|
||||
|
||||
void MyPrintFunction(const char *pcFormat, ... );
|
||||
#define configPRINTF( X ) MyPrintFunction X
|
||||
|
||||
Then call like a standard printf() function, but placing brackets around
|
||||
all parameters so they are passed as a single parameter. For example:
|
||||
configPRINTF( ("Value = %d", MyVariable) ); */
|
||||
#define configPRINTF( X )
|
||||
#endif
|
||||
|
||||
#ifndef configMAX
|
||||
/* The application writer has not provided their own MAX macro, so define
|
||||
the following generic implementation. */
|
||||
#define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
#ifndef configMIN
|
||||
/* The application writer has not provided their own MAX macro, so define
|
||||
the following generic implementation. */
|
||||
#define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
#if configENABLE_BACKWARD_COMPATIBILITY == 1
|
||||
#define eTaskStateGet eTaskGetState
|
||||
#define portTickType TickType_t
|
||||
|
@ -847,6 +936,10 @@ V8 if desired. */
|
|||
#define pdTASK_CODE TaskFunction_t
|
||||
#define xListItem ListItem_t
|
||||
#define xList List_t
|
||||
|
||||
/* For libraries that break the list data hiding, and access list structure
|
||||
members directly (which is not supposed to be done). */
|
||||
#define pxContainer pvContainer
|
||||
#endif /* configENABLE_BACKWARD_COMPATIBILITY */
|
||||
|
||||
#if( configUSE_ALTERNATIVE_API != 0 )
|
||||
|
@ -861,6 +954,75 @@ point support. */
|
|||
#define configUSE_TASK_FPU_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is
|
||||
currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_MPU
|
||||
#define configENABLE_MPU 0
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is
|
||||
currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_FPU
|
||||
#define configENABLE_FPU 1
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it.
|
||||
This is currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_TRUSTZONE
|
||||
#define configENABLE_TRUSTZONE 1
|
||||
#endif
|
||||
|
||||
/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on
|
||||
the Secure Side only. */
|
||||
#ifndef configRUN_FREERTOS_SECURE_ONLY
|
||||
#define configRUN_FREERTOS_SECURE_ONLY 0
|
||||
#endif
|
||||
|
||||
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
||||
* dynamically allocated RAM, in which case when any task is deleted it is known
|
||||
* that both the task's stack and TCB need to be freed. Sometimes the
|
||||
* FreeRTOSConfig.h settings only allow a task to be created using statically
|
||||
* allocated RAM, in which case when any task is deleted it is known that neither
|
||||
* the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h
|
||||
* settings allow a task to be created using either statically or dynamically
|
||||
* allocated RAM, in which case a member of the TCB is used to record whether the
|
||||
* stack and/or TCB were allocated statically or dynamically, so when a task is
|
||||
* deleted the RAM that was allocated dynamically is freed again and no attempt is
|
||||
* made to free the RAM that was allocated statically.
|
||||
* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a
|
||||
* task to be created using either statically or dynamically allocated RAM. Note
|
||||
* that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with
|
||||
* a statically allocated stack and a dynamically allocated TCB.
|
||||
*
|
||||
* The following table lists various combinations of portUSING_MPU_WRAPPERS,
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and
|
||||
* when it is possible to have both static and dynamic allocation:
|
||||
* +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
|
||||
* | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free |
|
||||
* | | | | | | Static Possible | |
|
||||
* +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
|
||||
* | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No |
|
||||
* +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
|
||||
* | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes |
|
||||
* +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
|
||||
* | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes |
|
||||
* | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | |
|
||||
* +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
|
||||
* | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No |
|
||||
* | | | | xTaskCreateRestrictedStatic | | | |
|
||||
* +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
|
||||
* | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes |
|
||||
* | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | |
|
||||
* +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------|
|
||||
* | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes |
|
||||
* | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | |
|
||||
* | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | |
|
||||
* | | | | xTaskCreateRestrictedStatic | | | |
|
||||
* +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
|
||||
*/
|
||||
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \
|
||||
( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) )
|
||||
|
||||
/*
|
||||
* In line with software engineering best practice, FreeRTOS implements a strict
|
||||
* data hiding policy, so the real structures used by FreeRTOS to maintain the
|
||||
|
@ -873,25 +1035,40 @@ point support. */
|
|||
*/
|
||||
struct xSTATIC_LIST_ITEM
|
||||
{
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
|
||||
TickType_t xDummy1;
|
||||
void *pvDummy2[ 4 ];
|
||||
#endif
|
||||
TickType_t xDummy2;
|
||||
void *pvDummy3[ 4 ];
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
|
||||
TickType_t xDummy4;
|
||||
#endif
|
||||
};
|
||||
typedef struct xSTATIC_LIST_ITEM StaticListItem_t;
|
||||
|
||||
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */
|
||||
struct xSTATIC_MINI_LIST_ITEM
|
||||
{
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
|
||||
TickType_t xDummy1;
|
||||
void *pvDummy2[ 2 ];
|
||||
#endif
|
||||
TickType_t xDummy2;
|
||||
void *pvDummy3[ 2 ];
|
||||
};
|
||||
typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t;
|
||||
|
||||
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */
|
||||
typedef struct xSTATIC_LIST
|
||||
{
|
||||
UBaseType_t uxDummy1;
|
||||
void *pvDummy2;
|
||||
StaticMiniListItem_t xDummy3;
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
|
||||
TickType_t xDummy1;
|
||||
#endif
|
||||
UBaseType_t uxDummy2;
|
||||
void *pvDummy3;
|
||||
StaticMiniListItem_t xDummy4;
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
|
||||
TickType_t xDummy5;
|
||||
#endif
|
||||
} StaticList_t;
|
||||
|
||||
/*
|
||||
|
@ -917,7 +1094,7 @@ typedef struct xSTATIC_TCB
|
|||
UBaseType_t uxDummy5;
|
||||
void *pxDummy6;
|
||||
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
|
||||
void *pxDummy8;
|
||||
#endif
|
||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||
|
@ -945,10 +1122,16 @@ typedef struct xSTATIC_TCB
|
|||
uint32_t ulDummy18;
|
||||
uint8_t ucDummy19;
|
||||
#endif
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
|
||||
uint8_t uxDummy20;
|
||||
#endif
|
||||
|
||||
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||
uint8_t ucDummy21;
|
||||
#endif
|
||||
#if ( configUSE_POSIX_ERRNO == 1 )
|
||||
int iDummy22;
|
||||
#endif
|
||||
} StaticTask_t;
|
||||
|
||||
/*
|
||||
|
@ -1043,18 +1226,42 @@ typedef struct xSTATIC_TIMER
|
|||
void *pvDummy1;
|
||||
StaticListItem_t xDummy2;
|
||||
TickType_t xDummy3;
|
||||
UBaseType_t uxDummy4;
|
||||
void *pvDummy5[ 2 ];
|
||||
void *pvDummy5;
|
||||
TaskFunction_t pvDummy6;
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxDummy6;
|
||||
#endif
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucDummy7;
|
||||
UBaseType_t uxDummy7;
|
||||
#endif
|
||||
uint8_t ucDummy8;
|
||||
|
||||
} StaticTimer_t;
|
||||
|
||||
/*
|
||||
* In line with software engineering best practice, especially when supplying a
|
||||
* library that is likely to change in future versions, FreeRTOS implements a
|
||||
* strict data hiding policy. This means the stream buffer structure used
|
||||
* internally by FreeRTOS is not accessible to application code. However, if
|
||||
* the application writer wants to statically allocate the memory required to
|
||||
* create a stream buffer then the size of the stream buffer object needs to be
|
||||
* know. The StaticStreamBuffer_t structure below is provided for this purpose.
|
||||
* Its size and alignment requirements are guaranteed to match those of the
|
||||
* genuine structure, no matter which architecture is being used, and no matter
|
||||
* how the values in FreeRTOSConfig.h are set. Its contents are somewhat
|
||||
* obfuscated in the hope users will recognise that it would be unwise to make
|
||||
* direct use of the structure members.
|
||||
*/
|
||||
typedef struct xSTATIC_STREAM_BUFFER
|
||||
{
|
||||
size_t uxDummy1[ 4 ];
|
||||
void * pvDummy2[ 3 ];
|
||||
uint8_t ucDummy3;
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxDummy4;
|
||||
#endif
|
||||
} StaticStreamBuffer_t;
|
||||
|
||||
/* Message buffers are built on stream buffers. */
|
||||
typedef StaticStreamBuffer_t StaticMessageBuffer_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,31 @@
|
|||
/* Default esp-open-sdk FreeRTOSConfig file.
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
You can override settings in here by creating your own
|
||||
FreeRTOSConfig.h file in your program directory.
|
||||
|
||||
You could just copy this file there and edit it, but it's
|
||||
recommended you instead define whatever you want to override and
|
||||
then use #include_next<FreeRTOSConfig.h> to pick up these defaults.
|
||||
|
||||
The "blink" example in "examples/blink" provides an example of how
|
||||
to do this.
|
||||
*/
|
||||
#ifndef __DEFAULT_FREERTOS_CONFIG_H
|
||||
#define __DEFAULT_FREERTOS_CONFIG_H
|
||||
|
||||
|
@ -47,7 +63,7 @@
|
|||
#define configTICK_RATE_HZ ( ( TickType_t ) 100 )
|
||||
#endif
|
||||
#ifndef configMAX_PRIORITIES
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 )
|
||||
#define configMAX_PRIORITIES ( 15 )
|
||||
#endif
|
||||
#ifndef configMINIMAL_STACK_SIZE
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short )256 )
|
||||
|
@ -81,6 +97,9 @@
|
|||
#ifndef configCHECK_FOR_STACK_OVERFLOW
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#endif
|
||||
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#endif
|
||||
#ifndef configUSE_MUTEXES
|
||||
#define configUSE_MUTEXES 1
|
||||
#endif
|
||||
|
@ -108,6 +127,10 @@
|
|||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_NEWLIB_REENTRANT
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#endif
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#ifndef INCLUDE_vTaskPrioritySet
|
||||
|
@ -144,5 +167,10 @@ to exclude the API function. */
|
|||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
#endif
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
void vAssertCalled(const char * pcFile, unsigned long ulLine);
|
||||
#define configASSERT(x) if((x) == 0) vAssertCalled(__FILE__, __LINE__);
|
||||
|
||||
#endif /* __DEFAULT_FREERTOS_CONFIG_H */
|
||||
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef CO_ROUTINE_H
|
||||
#define CO_ROUTINE_H
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef DEPRECATED_DEFINITIONS_H
|
||||
#define DEPRECATED_DEFINITIONS_H
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef EVENT_GROUPS_H
|
||||
#define EVENT_GROUPS_H
|
||||
|
@ -120,7 +78,8 @@ extern "C" {
|
|||
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
typedef void * EventGroupHandle_t;
|
||||
struct EventGroupDef_t;
|
||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||
|
||||
/*
|
||||
* The type that holds event bits always matches TickType_t - therefore the
|
||||
|
@ -446,7 +405,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
|||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
||||
#endif
|
||||
|
@ -786,6 +745,7 @@ void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToCl
|
|||
|
||||
#if (configUSE_TRACE_FACILITY == 1)
|
||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the list implementation used by the scheduler. While it is tailored
|
||||
|
@ -178,6 +136,7 @@ use of FreeRTOS.*/
|
|||
/*
|
||||
* Definition of the only type of object that a list can contain.
|
||||
*/
|
||||
struct xLIST;
|
||||
struct xLIST_ITEM
|
||||
{
|
||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
|
@ -185,7 +144,7 @@ struct xLIST_ITEM
|
|||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
};
|
||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||
|
@ -205,7 +164,7 @@ typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
|||
typedef struct xLIST
|
||||
{
|
||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
|
||||
volatile UBaseType_t uxNumberOfItems;
|
||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
|
@ -288,7 +247,7 @@ typedef struct xLIST
|
|||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||
|
||||
/*
|
||||
* Access macro to return the number of items in the list.
|
||||
|
@ -356,7 +315,7 @@ List_t * const pxConstList = ( pxList ); \
|
|||
* @param pxListItem The list item we want to know if is in the list.
|
||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||
*/
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
||||
|
||||
/*
|
||||
* Return the list a list item is contained within (referenced from).
|
||||
|
@ -364,7 +323,7 @@ List_t * const pxConstList = ( pxList ); \
|
|||
* @param pxListItem The list item being queried.
|
||||
* @return A pointer to the List_t object that references the pxListItem
|
||||
*/
|
||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
||||
|
||||
/*
|
||||
* This provides a crude means of knowing if a list has been initialised, as
|
||||
|
|
798
FreeRTOS/Source/include/message_buffer.h
Normal file
798
FreeRTOS/Source/include/message_buffer.h
Normal file
|
@ -0,0 +1,798 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Message buffers build functionality on top of FreeRTOS stream buffers.
|
||||
* Whereas stream buffers are used to send a continuous stream of data from one
|
||||
* task or interrupt to another, message buffers are used to send variable
|
||||
* length discrete messages from one task or interrupt to another. Their
|
||||
* implementation is light weight, making them particularly suited for interrupt
|
||||
* to task and core to core communication scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* timeout to 0.
|
||||
*
|
||||
* Message buffers hold variable length messages. To enable that, when a
|
||||
* message is written to the message buffer an additional sizeof( size_t ) bytes
|
||||
* are also written to store the message's length (that happens internally, with
|
||||
* the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so writing a 10 byte message to a message buffer on a 32-bit
|
||||
* architecture will actually reduce the available space in the message buffer
|
||||
* by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
|
||||
* of the message).
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||
#define FREERTOS_MESSAGE_BUFFER_H
|
||||
|
||||
/* Message buffers are built onto of stream buffers. */
|
||||
#include "stream_buffer.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Type by which message buffers are referenced. For example, a call to
|
||||
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
|
||||
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||
* etc.
|
||||
*/
|
||||
typedef void * MessageBufferHandle_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||
</pre>
|
||||
*
|
||||
* Creates a new message buffer using dynamically allocated memory. See
|
||||
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xMessageBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes (not messages) the message
|
||||
* buffer will be able to hold at any one time. When a message is written to
|
||||
* the message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||
* take up 14 bytes of message buffer space.
|
||||
*
|
||||
* @return If NULL is returned, then the message buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the message buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the message buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created message
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
void vAFunction( void )
|
||||
{
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
const size_t xMessageBufferSizeBytes = 100;
|
||||
|
||||
// Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||
// both the message buffer structure and the messages themselves is allocated
|
||||
// dynamically. Each message added to the buffer consumes an additional 4
|
||||
// bytes which are used to hold the lengh of the message.
|
||||
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||
|
||||
if( xMessageBuffer == NULL )
|
||||
{
|
||||
// There was not enough heap memory space available to create the
|
||||
// message buffer.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The message buffer was created successfully and can now be used.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
uint8_t *pucMessageBufferStorageArea,
|
||||
StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||
</pre>
|
||||
* Creates a new message buffer using statically allocated memory. See
|
||||
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucMessageBufferStorageArea parameter. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to store
|
||||
* the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so on most 32-bit architecture a 10 byte message will take up
|
||||
* 14 bytes of message buffer space. The maximum number of bytes that can be
|
||||
* stored in the message buffer is actually (xBufferSizeBytes - 1).
|
||||
*
|
||||
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes + 1 big. This is the array to which messages are
|
||||
* copied when they are written to the message buffer.
|
||||
*
|
||||
* @param pxStaticMessageBuffer Must point to a variable of type
|
||||
* StaticMessageBuffer_t, which will be used to hold the message buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @return If the message buffer is created successfully then a handle to the
|
||||
* created message buffer is returned. If either pucMessageBufferStorageArea or
|
||||
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
// Used to dimension the array used to hold the messages. The available space
|
||||
// will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
|
||||
// Defines the memory that will actually hold the messages within the message
|
||||
// buffer.
|
||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
|
||||
// The variable used to hold the message buffer structure.
|
||||
StaticMessageBuffer_t xMessageBufferStruct;
|
||||
|
||||
void MyFunction( void )
|
||||
{
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
|
||||
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||
ucBufferStorage,
|
||||
&xMessageBufferStruct );
|
||||
|
||||
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||
// reference the created message buffer in other message buffer API calls.
|
||||
|
||||
// Other code that uses the message buffer can go here.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
<pre>
|
||||
*
|
||||
* Sends a discrete message to the message buffer. The message can be any
|
||||
* length that fits within the buffer's free space, and is copied into the
|
||||
* buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the calling task should remain
|
||||
* in the Blocked state to wait for enough space to become available in the
|
||||
* message buffer, should the message buffer have insufficient space when
|
||||
* xMessageBufferSend() is called. The calling task will never block if
|
||||
* xTicksToWait is zero. The block time is specified in tick periods, so the
|
||||
* absolute time it represents is dependent on the tick frequency. The macro
|
||||
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
|
||||
* a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause
|
||||
* the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the message buffer. If the call to
|
||||
* xMessageBufferSend() times out before there was enough space to write the
|
||||
* message into the message buffer then zero is returned. If the call did not
|
||||
* time out then xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
char *pcStringToSend = "String to send";
|
||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
|
||||
// Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||
// wait for enough space to be available in the message buffer.
|
||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
|
||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
{
|
||||
// The call to xMessageBufferSend() times out before there was enough
|
||||
// space in the buffer for the data to be written.
|
||||
}
|
||||
|
||||
// Send the string to the message buffer. Return immediately if there is
|
||||
// not enough space in the buffer.
|
||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The string could not be added to the message buffer because there was
|
||||
// not enough free space in the buffer.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
<pre>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a discrete message to
|
||||
* the message buffer. The message can be any length that fits within the
|
||||
* buffer's free space, and is copied into the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xMessageBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xMessageBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the message buffer. If the
|
||||
* message buffer didn't have enough free space for the message to be stored
|
||||
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A message buffer that has already been created.
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
char *pcStringToSend = "String to send";
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Attempt to send the string to the message buffer.
|
||||
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||
( void * ) pcStringToSend,
|
||||
strlen( pcStringToSend ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The string could not be added to the message buffer because there was
|
||||
// not enough free space in the buffer.
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xMessageBufferSendFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Receives a discrete message from a message buffer. Messages can be of
|
||||
* variable length and are copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for a message, should the message buffer be empty.
|
||||
* xMessageBufferReceive() will return immediately if xTicksToWait is zero and
|
||||
* the message buffer is empty. The block time is specified in tick periods, so
|
||||
* the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any. If xMessageBufferReceive() times out before a message became available
|
||||
* then zero is returned. If the length of the message is greater than
|
||||
* xBufferLengthBytes then the message will be left in the message buffer and
|
||||
* zero is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
|
||||
// Receive the next message from the message buffer. Wait in the Blocked
|
||||
// state (so not using any CPU processing time) for a maximum of 100ms for
|
||||
// a message to become available.
|
||||
xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
xBlockTime );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
// the message here....
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* An interrupt safe version of the API function that receives a discrete
|
||||
* message from a message buffer. Messages can be of variable length and are
|
||||
* copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xMessageBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A message buffer that has already been created.
|
||||
MessageBuffer_t xMessageBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Receive the next message from the message buffer.
|
||||
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
// the message here....
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Deletes a message buffer that was previously created using a call to
|
||||
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||
* buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A message buffer handle must not be used after the message buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||
*
|
||||
*/
|
||||
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
*
|
||||
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||
* cannot accept any more messages, of any size, until space is made available
|
||||
* by a message being removed from the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*/
|
||||
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
*
|
||||
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is empty then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*
|
||||
*/
|
||||
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Resets a message buffer to its initial empty state, discarding any message it
|
||||
* contained.
|
||||
*
|
||||
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||
*
|
||||
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||
* message buffer could not be reset because either there was a task blocked on
|
||||
* the message queue to wait for space to become available, or to wait for a
|
||||
* a message to be available, then pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* Returns the number of bytes of free space in the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the message buffer before
|
||||
* the message buffer would be full. When a message is written to the message
|
||||
* buffer an additional sizeof( size_t ) bytes are also written to store the
|
||||
* message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
|
||||
* of the largest message that can be written to the message buffer is 6 bytes.
|
||||
*
|
||||
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* Returns the length (in bytes) of the next message in a message buffer.
|
||||
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The length (in bytes) of the next message in the message buffer, or 0
|
||||
* if the message buffer is empty.
|
||||
*
|
||||
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xMessageBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferSendCompletedFromISR(). If calling
|
||||
* xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferReceiveCompletedFromISR(). If calling
|
||||
* xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||
|
||||
#if defined( __cplusplus )
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the MPU is used the standard (non MPU) API functions are mapped to
|
||||
|
@ -79,99 +37,121 @@
|
|||
#ifndef MPU_PROTOTYPES_H
|
||||
#define MPU_PROTOTYPES_H
|
||||
|
||||
/* MPU versions of tasks.h API function. */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask );
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer );
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete );
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay );
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask );
|
||||
UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t xTask );
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask );
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend );
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume );
|
||||
void MPU_vTaskStartScheduler( void );
|
||||
void MPU_vTaskSuspendAll( void );
|
||||
BaseType_t MPU_xTaskResumeAll( void );
|
||||
TickType_t MPU_xTaskGetTickCount( void );
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void );
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery );
|
||||
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery );
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask );
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue );
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex );
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void );
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime );
|
||||
void MPU_vTaskList( char * pcWriteBuffer );
|
||||
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer );
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue );
|
||||
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
|
||||
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask );
|
||||
BaseType_t MPU_xTaskIncrementTick( void );
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void );
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut );
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait );
|
||||
void MPU_vTaskMissedYield( void );
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void );
|
||||
/* MPU versions of tasks.h API functions. */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of queue.h API function. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition );
|
||||
BaseType_t MPU_xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek );
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue );
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue );
|
||||
void MPU_vQueueDelete( QueueHandle_t xQueue );
|
||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType );
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue );
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount );
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue );
|
||||
void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore );
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex );
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName );
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue );
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue );
|
||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType );
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType );
|
||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength );
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue );
|
||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber );
|
||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue );
|
||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue );
|
||||
/* MPU versions of queue.h API functions. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of timers.h API functions. */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of event_group.h API functions. */
|
||||
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
|
||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of message/stream_buffer.h API functions. */
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of timers.h API function. */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction );
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer );
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer );
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void );
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer );
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer );
|
||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||
BaseType_t MPU_xTimerCreateTimerTask( void );
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait );
|
||||
|
||||
/* MPU versions of event_group.h API function. */
|
||||
EventGroupHandle_t MPU_xEventGroupCreate( void );
|
||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer );
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait );
|
||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup );
|
||||
|
||||
#endif /* MPU_PROTOTYPES_H */
|
||||
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef MPU_WRAPPERS_H
|
||||
#define MPU_WRAPPERS_H
|
||||
|
@ -109,6 +67,7 @@ only for ports that are using the MPU. */
|
|||
#define pcTaskGetName MPU_pcTaskGetName
|
||||
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
|
||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||
|
@ -118,6 +77,7 @@ only for ports that are using the MPU. */
|
|||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||
#define vTaskList MPU_vTaskList
|
||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||
#define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter
|
||||
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||
#define xTaskNotifyWait MPU_xTaskNotifyWait
|
||||
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
|
||||
|
@ -130,7 +90,9 @@ only for ports that are using the MPU. */
|
|||
|
||||
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||
#define xQueueReceive MPU_xQueueReceive
|
||||
#define xQueuePeek MPU_xQueuePeek
|
||||
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
|
||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||
#define vQueueDelete MPU_vQueueDelete
|
||||
|
@ -164,6 +126,7 @@ only for ports that are using the MPU. */
|
|||
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
|
||||
#define pcTimerGetName MPU_pcTimerGetName
|
||||
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
|
||||
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||
|
@ -177,14 +140,35 @@ only for ports that are using the MPU. */
|
|||
#define xEventGroupSync MPU_xEventGroupSync
|
||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||
|
||||
/* Remove the privileged function macro. */
|
||||
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||
equivalents. */
|
||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
|
||||
#define xStreamBufferReset MPU_xStreamBufferReset
|
||||
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
|
||||
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
|
||||
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
|
||||
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
|
||||
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||
|
||||
|
||||
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||
macro so applications can place data in privileged access sections
|
||||
(useful when using statically allocated objects). */
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
|
||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
/* Ensure API functions go in the privileged execution section. */
|
||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
|
||||
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
|
@ -192,6 +176,7 @@ only for ports that are using the MPU. */
|
|||
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
#define portUSING_MPU_WRAPPERS 0
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Portable layer API. Each function must be defined for each port.
|
||||
|
@ -126,6 +84,14 @@ must be set in the compiler's include path. */
|
|||
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
||||
#endif
|
||||
|
||||
#ifndef portARCH_NAME
|
||||
#define portARCH_NAME NULL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -139,9 +105,17 @@ extern "C" {
|
|||
*
|
||||
*/
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#else
|
||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Used by heap_5.c. */
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PROJDEFS_H
|
||||
#define PROJDEFS_H
|
||||
|
@ -155,6 +113,11 @@ itself. */
|
|||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
/* Re-defining endian values for generic naming. */
|
||||
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
|
||||
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
|
||||
|
||||
|
||||
#endif /* PROJDEFS_H */
|
||||
|
||||
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QUEUE_H
|
||||
|
@ -79,27 +37,29 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "task.h"
|
||||
|
||||
/**
|
||||
* Type by which queues are referenced. For example, a call to xQueueCreate()
|
||||
* returns an QueueHandle_t variable that can then be used as a parameter to
|
||||
* xQueueSend(), xQueueReceive(), etc.
|
||||
*/
|
||||
typedef void * QueueHandle_t;
|
||||
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
|
||||
typedef struct QueueDefinition * QueueHandle_t;
|
||||
|
||||
/**
|
||||
* Type by which queue sets are referenced. For example, a call to
|
||||
* xQueueCreateSet() returns an xQueueSet variable that can then be used as a
|
||||
* parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
|
||||
*/
|
||||
typedef void * QueueSetHandle_t;
|
||||
typedef struct QueueDefinition * QueueSetHandle_t;
|
||||
|
||||
/**
|
||||
* Queue sets can contain both queues and semaphores, so the
|
||||
* QueueSetMemberHandle_t is defined as a type to be used where a parameter or
|
||||
* return value can be either an QueueHandle_t or an SemaphoreHandle_t.
|
||||
*/
|
||||
typedef void * QueueSetMemberHandle_t;
|
||||
typedef struct QueueDefinition * QueueSetMemberHandle_t;
|
||||
|
||||
/* For internal use only. */
|
||||
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
|
||||
|
@ -282,8 +242,6 @@ typedef void * QueueSetMemberHandle_t;
|
|||
);
|
||||
* </pre>
|
||||
*
|
||||
* This is a macro that calls xQueueGenericSend().
|
||||
*
|
||||
* Post an item to the front of a queue. The item is queued by copy, not by
|
||||
* reference. This function must not be called from an interrupt service
|
||||
* routine. See xQueueSendFromISR () for an alternative which may be used
|
||||
|
@ -696,12 +654,10 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
|
|||
* <pre>
|
||||
BaseType_t xQueuePeek(
|
||||
QueueHandle_t xQueue,
|
||||
void *pvBuffer,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait
|
||||
);</pre>
|
||||
*
|
||||
* This is a macro that calls the xQueueGenericReceive() function.
|
||||
*
|
||||
* Receive an item from a queue without removing the item from the queue.
|
||||
* The item is received by copy so a buffer of adequate size must be
|
||||
* provided. The number of bytes copied into the buffer was defined when
|
||||
|
@ -782,10 +738,10 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQ
|
|||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \defgroup xQueuePeek xQueuePeek
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
|
||||
BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
|
@ -829,8 +785,6 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
|
|||
TickType_t xTicksToWait
|
||||
);</pre>
|
||||
*
|
||||
* This is a macro that calls the xQueueGenericReceive() function.
|
||||
*
|
||||
* Receive an item from a queue. The item is received by copy so a buffer of
|
||||
* adequate size must be provided. The number of bytes copied into the buffer
|
||||
* was defined when the queue was created.
|
||||
|
@ -911,106 +865,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
|
|||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
|
||||
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
* <pre>
|
||||
BaseType_t xQueueGenericReceive(
|
||||
QueueHandle_t xQueue,
|
||||
void *pvBuffer,
|
||||
TickType_t xTicksToWait
|
||||
BaseType_t xJustPeek
|
||||
);</pre>
|
||||
*
|
||||
* It is preferred that the macro xQueueReceive() be used rather than calling
|
||||
* this function directly.
|
||||
*
|
||||
* Receive an item from a queue. The item is received by copy so a buffer of
|
||||
* adequate size must be provided. The number of bytes copied into the buffer
|
||||
* was defined when the queue was created.
|
||||
*
|
||||
* This function must not be used in an interrupt service routine. See
|
||||
* xQueueReceiveFromISR for an alternative that can.
|
||||
*
|
||||
* @param xQueue The handle to the queue from which the item is to be
|
||||
* received.
|
||||
*
|
||||
* @param pvBuffer Pointer to the buffer into which the received item will
|
||||
* be copied.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should block
|
||||
* waiting for an item to receive should the queue be empty at the time
|
||||
* of the call. The time is defined in tick periods so the constant
|
||||
* portTICK_PERIOD_MS should be used to convert to real time if this is required.
|
||||
* xQueueGenericReceive() will return immediately if the queue is empty and
|
||||
* xTicksToWait is 0.
|
||||
*
|
||||
* @param xJustPeek When set to true, the item received from the queue is not
|
||||
* actually removed from the queue - meaning a subsequent call to
|
||||
* xQueueReceive() will return the same item. When set to false, the item
|
||||
* being received from the queue is also removed from the queue.
|
||||
*
|
||||
* @return pdTRUE if an item was successfully received from the queue,
|
||||
* otherwise pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
struct AMessage
|
||||
{
|
||||
char ucMessageID;
|
||||
char ucData[ 20 ];
|
||||
} xMessage;
|
||||
|
||||
QueueHandle_t xQueue;
|
||||
|
||||
// Task to create a queue and post a value.
|
||||
void vATask( void *pvParameters )
|
||||
{
|
||||
struct AMessage *pxMessage;
|
||||
|
||||
// Create a queue capable of containing 10 pointers to AMessage structures.
|
||||
// These should be passed by pointer as they contain a lot of data.
|
||||
xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
|
||||
if( xQueue == 0 )
|
||||
{
|
||||
// Failed to create the queue.
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Send a pointer to a struct AMessage object. Don't block if the
|
||||
// queue is already full.
|
||||
pxMessage = & xMessage;
|
||||
xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
|
||||
// Task to receive from the queue.
|
||||
void vADifferentTask( void *pvParameters )
|
||||
{
|
||||
struct AMessage *pxRxedMessage;
|
||||
|
||||
if( xQueue != 0 )
|
||||
{
|
||||
// Receive a message on the created queue. Block for 10 ticks if a
|
||||
// message is not immediately available.
|
||||
if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
|
||||
{
|
||||
// pcRxedMessage now points to the struct AMessage variable posted
|
||||
// by vATask.
|
||||
}
|
||||
}
|
||||
|
||||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueReceive xQueueReceive
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* queue. h
|
||||
|
@ -1560,14 +1415,16 @@ QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION
|
|||
QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||
QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
|
||||
QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||
void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* For internal use only. Use xSemaphoreTakeMutexRecursive() or
|
||||
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
|
||||
*/
|
||||
BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Reset a queue back to its original empty state. The return value is now
|
||||
|
@ -1598,7 +1455,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
|
|||
* preferably in ROM/Flash), not on the stack.
|
||||
*/
|
||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
|
@ -328,7 +286,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
|||
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
|
||||
|
||||
/**
|
||||
* semphr. h
|
||||
|
@ -1154,6 +1112,17 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
|||
*/
|
||||
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
|
||||
|
||||
/**
|
||||
* semphr.h
|
||||
* <pre>TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );</pre>
|
||||
*
|
||||
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
|
||||
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
|
||||
* by a task), return NULL.
|
||||
*
|
||||
*/
|
||||
#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )
|
||||
|
||||
/**
|
||||
* semphr.h
|
||||
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef STACK_MACROS_H
|
||||
#define STACK_MACROS_H
|
855
FreeRTOS/Source/include/stream_buffer.h
Normal file
855
FreeRTOS/Source/include/stream_buffer.h
Normal file
|
@ -0,0 +1,855 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stream buffers are used to send a continuous stream of data from one task or
|
||||
* interrupt to another. Their implementation is light weight, making them
|
||||
* particularly suited for interrupt to task and core to core communication
|
||||
* scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section section and set the
|
||||
* receive block time to 0.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STREAM_BUFFER_H
|
||||
#define STREAM_BUFFER_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Type by which stream buffers are referenced. For example, a call to
|
||||
* xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
|
||||
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
||||
* etc.
|
||||
*/
|
||||
struct StreamBufferDef_t;
|
||||
typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||
</pre>
|
||||
*
|
||||
* Creates a new stream buffer using dynamically allocated memory. See
|
||||
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xStreamBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes the stream buffer will be
|
||||
* able to hold at any one time.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @return If NULL is returned, then the stream buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the stream buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the stream buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created stream
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
void vAFunction( void )
|
||||
{
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||
|
||||
// Create a stream buffer that can hold 100 bytes. The memory used to hold
|
||||
// both the stream buffer structure and the data in the stream buffer is
|
||||
// allocated dynamically.
|
||||
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
||||
|
||||
if( xStreamBuffer == NULL )
|
||||
{
|
||||
// There was not enough heap memory space available to create the
|
||||
// stream buffer.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The stream buffer was created successfully and can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
uint8_t *pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||
</pre>
|
||||
* Creates a new stream buffer using statically allocated memory. See
|
||||
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
|
||||
* xStreamBufferCreateStatic() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucStreamBufferStorageArea parameter.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes + 1 big. This is the array to which streams are
|
||||
* copied when they are written to the stream buffer.
|
||||
*
|
||||
* @param pxStaticStreamBuffer Must point to a variable of type
|
||||
* StaticStreamBuffer_t, which will be used to hold the stream buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @return If the stream buffer is created successfully then a handle to the
|
||||
* created stream buffer is returned. If either pucStreamBufferStorageArea or
|
||||
* pxStaticstreamBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
// Used to dimension the array used to hold the streams. The available space
|
||||
// will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
|
||||
// Defines the memory that will actually hold the streams within the stream
|
||||
// buffer.
|
||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
|
||||
// The variable used to hold the stream buffer structure.
|
||||
StaticStreamBuffer_t xStreamBufferStruct;
|
||||
|
||||
void MyFunction( void )
|
||||
{
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
const size_t xTriggerLevel = 1;
|
||||
|
||||
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||
xTriggerLevel,
|
||||
ucBufferStorage,
|
||||
&xStreamBufferStruct );
|
||||
|
||||
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
||||
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
||||
// reference the created stream buffer in other stream buffer API calls.
|
||||
|
||||
// Other code that uses the stream buffer can go here.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the buffer that holds the bytes to be copied
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for enough space to become available in the stream
|
||||
* buffer, should the stream buffer contain too little space to hold the
|
||||
* another xDataLengthBytes bytes. The block time is specified in tick periods,
|
||||
* so the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||
* before it can write all xDataLengthBytes into the buffer it will still write
|
||||
* as many bytes as possible. A task does not use any CPU time when it is in
|
||||
* the blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the stream buffer. If a task times
|
||||
* out before it can write all xDataLengthBytes into the buffer it will still
|
||||
* write as many bytes as possible.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
char *pcStringToSend = "String to send";
|
||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
|
||||
// Send an array to the stream buffer, blocking for a maximum of 100ms to
|
||||
// wait for enough space to be available in the stream buffer.
|
||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
|
||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
{
|
||||
// The call to xStreamBufferSend() times out before there was enough
|
||||
// space in the buffer for the data to be written, but it did
|
||||
// successfully write xBytesSent bytes.
|
||||
}
|
||||
|
||||
// Send the string to the stream buffer. Return immediately if there is not
|
||||
// enough space in the buffer.
|
||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The entire string could not be added to the stream buffer because
|
||||
// there was not enough free space in the buffer, but xBytesSent bytes
|
||||
// were sent. Could try again to send the remaining bytes.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferSend xStreamBufferSend
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||
* the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the data that is to be copied into the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xStreamBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xStreamBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the example code below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the stream buffer, which will
|
||||
* be less than xDataLengthBytes if the stream buffer didn't have enough free
|
||||
* space for all the bytes to be written.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A stream buffer that has already been created.
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
char *pcStringToSend = "String to send";
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Attempt to send the string to the stream buffer.
|
||||
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
||||
( void * ) pcStringToSend,
|
||||
strlen( pcStringToSend ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// There was not enough free space in the stream buffer for the entire
|
||||
// string to be written, ut xBytesSent bytes were written.
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xStreamBufferSendFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Receives bytes from a stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read from a stream buffer from a task. Use
|
||||
* xStreamBufferReceiveFromISR() to read from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which bytes are to
|
||||
* be received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes will be
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for data to become available if the stream buffer is
|
||||
* empty. xStreamBufferReceive() will return immediately if xTicksToWait is
|
||||
* zero. The block time is specified in tick periods, so the absolute time it
|
||||
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can
|
||||
* be used to convert a time specified in milliseconds into a time specified in
|
||||
* ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait
|
||||
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
|
||||
* in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||
* Blocked state.
|
||||
*
|
||||
* @return The number of bytes actually read from the stream buffer, which will
|
||||
* be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
|
||||
* out before xBufferLengthBytes were available.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( StreamBuffer_t xStreamBuffer )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
|
||||
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
||||
// Wait in the Blocked state (so not using any CPU processing time) for a
|
||||
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
||||
// available.
|
||||
xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
xBlockTime );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains another xRecievedBytes bytes of data, which can
|
||||
// be processed here....
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* An interrupt safe version of the API function that receives bytes from a
|
||||
* stream buffer.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
|
||||
* Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which a stream
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes are
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xStreamBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes read from the stream buffer, if any.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A stream buffer that has already been created.
|
||||
StreamBuffer_t xStreamBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Receive the next stream from the stream buffer.
|
||||
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// ucRxData contains xReceivedBytes read from the stream buffer.
|
||||
// Process the stream here....
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xStreamBufferReceiveFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Deletes a stream buffer that was previously created using a call to
|
||||
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
||||
* buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A stream buffer handle must not be used after the stream buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to be deleted.
|
||||
*
|
||||
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||
* does not have any free space, and therefore cannot accept any more data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is full then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||
* it does not contain any data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is empty then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||
* are no tasks blocked waiting to either send to or receive from the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being reset.
|
||||
*
|
||||
* @return If the stream buffer is reset then pdPASS is returned. If there was
|
||||
* a task blocked waiting to send to or read from the stream buffer then the
|
||||
* stream buffer is not reset and pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReset xStreamBufferReset
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see how much free space it contains, which is
|
||||
* equal to the amount of data that can be sent to the stream buffer before it
|
||||
* is full.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the stream buffer before
|
||||
* the stream buffer would be full.
|
||||
*
|
||||
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see how much data it contains, which is equal to
|
||||
* the number of bytes that can be read from the stream buffer before the stream
|
||||
* buffer would be empty.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be read from the stream buffer before
|
||||
* the stream buffer would be empty.
|
||||
*
|
||||
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||
</pre>
|
||||
*
|
||||
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||
* stream buffer before a task that is blocked on the stream buffer to
|
||||
* wait for data is moved out of the blocked state. For example, if a task is
|
||||
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||
* then the task will be unblocked when a single byte is written to the buffer
|
||||
* or the task's block time expires. As another example, if a task is blocked
|
||||
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||
* task will not be unblocked until the stream buffer contains at least 10 bytes
|
||||
* or the task's block time expires. If a reading task's block time expires
|
||||
* before the trigger level is reached then the task will still receive however
|
||||
* many bytes are actually available. Setting a trigger level of 0 will result
|
||||
* in a trigger level of 1 being used. It is not valid to specify a trigger
|
||||
* level that is greater than the buffer size.
|
||||
*
|
||||
* A trigger level is set when the stream buffer is created, and can be modified
|
||||
* using xStreamBufferSetTriggerLevel().
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being updated.
|
||||
*
|
||||
* @param xTriggerLevel The new trigger level for the stream buffer.
|
||||
*
|
||||
* @return If xTriggerLevel was less than or equal to the stream buffer's length
|
||||
* then the trigger level will be updated and pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xStreamBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferSendCompletedFromISR(). If calling
|
||||
* xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferReceiveCompletedFromISR(). If calling
|
||||
* xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* Functions below here are not part of the public API. */
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#if defined( __cplusplus )
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined( STREAM_BUFFER_H ) */
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INC_TASK_H
|
||||
|
@ -85,11 +43,19 @@ extern "C" {
|
|||
* MACROS AND DEFINITIONS
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define tskKERNEL_VERSION_NUMBER "V9.0.0"
|
||||
#define tskKERNEL_VERSION_MAJOR 9
|
||||
#define tskKERNEL_VERSION_MINOR 0
|
||||
#define tskKERNEL_VERSION_NUMBER "V10.2.0"
|
||||
#define tskKERNEL_VERSION_MAJOR 10
|
||||
#define tskKERNEL_VERSION_MINOR 2
|
||||
#define tskKERNEL_VERSION_BUILD 0
|
||||
|
||||
/* MPU region parameters passed in ulParameters
|
||||
* of MemoryRegion_t struct. */
|
||||
#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL )
|
||||
#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL )
|
||||
#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL )
|
||||
#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL )
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
|
@ -100,7 +66,8 @@ extern "C" {
|
|||
* \defgroup TaskHandle_t TaskHandle_t
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
typedef void * TaskHandle_t;
|
||||
struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||
typedef struct tskTaskControlBlock* TaskHandle_t;
|
||||
|
||||
/*
|
||||
* Defines the prototype to which the application task hook function must
|
||||
|
@ -155,11 +122,14 @@ typedef struct xTASK_PARAMETERS
|
|||
{
|
||||
TaskFunction_t pvTaskCode;
|
||||
const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
uint16_t usStackDepth;
|
||||
configSTACK_DEPTH_TYPE usStackDepth;
|
||||
void *pvParameters;
|
||||
UBaseType_t uxPriority;
|
||||
StackType_t *puxStackBuffer;
|
||||
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
|
||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
StaticTask_t * const pxTaskBuffer;
|
||||
#endif
|
||||
} TaskParameters_t;
|
||||
|
||||
/* Used with the uxTaskGetSystemState() function to return the state of each task
|
||||
|
@ -174,7 +144,7 @@ typedef struct xTASK_STATUS
|
|||
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
|
||||
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
|
||||
StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */
|
||||
uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
||||
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
||||
} TaskStatus_t;
|
||||
|
||||
/* Possible return values for eTaskConfirmSleepModeStatus(). */
|
||||
|
@ -269,7 +239,7 @@ is used in assert() statements. */
|
|||
BaseType_t xTaskCreate(
|
||||
TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
uint16_t usStackDepth,
|
||||
configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void *pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t *pvCreatedTask
|
||||
|
@ -358,11 +328,11 @@ is used in assert() statements. */
|
|||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -414,9 +384,9 @@ is used in assert() statements. */
|
|||
* memory to be allocated dynamically.
|
||||
*
|
||||
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will
|
||||
* be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer
|
||||
* are NULL then the task will not be created and
|
||||
* errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.
|
||||
* be created and a handle to the created task is returned. If either
|
||||
* pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and
|
||||
* NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
|
@ -474,12 +444,12 @@ is used in assert() statements. */
|
|||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
|
@ -487,6 +457,8 @@ is used in assert() statements. */
|
|||
*<pre>
|
||||
BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre>
|
||||
*
|
||||
* Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1.
|
||||
*
|
||||
* xTaskCreateRestricted() should only be used in systems that include an MPU
|
||||
* implementation.
|
||||
*
|
||||
|
@ -494,6 +466,9 @@ is used in assert() statements. */
|
|||
* The function parameters define the memory regions and associated access
|
||||
* permissions allocated to the task.
|
||||
*
|
||||
* See xTaskCreateRestrictedStatic() for a version that does not use any
|
||||
* dynamic memory allocation.
|
||||
*
|
||||
* @param pxTaskDefinition Pointer to a structure that contains a member
|
||||
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
|
||||
* documentation) plus an optional stack buffer and the memory region
|
||||
|
@ -553,6 +528,94 @@ TaskHandle_t xHandle;
|
|||
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*<pre>
|
||||
BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre>
|
||||
*
|
||||
* Only available when configSUPPORT_STATIC_ALLOCATION is set to 1.
|
||||
*
|
||||
* xTaskCreateRestrictedStatic() should only be used in systems that include an
|
||||
* MPU implementation.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, tasks use two blocks of
|
||||
* memory. The first block is used to hold the task's data structures. The
|
||||
* second block is used by the task as its stack. If a task is created using
|
||||
* xTaskCreateRestricted() then the stack is provided by the application writer,
|
||||
* and the memory used to hold the task's data structure is automatically
|
||||
* dynamically allocated inside the xTaskCreateRestricted() function. If a task
|
||||
* is created using xTaskCreateRestrictedStatic() then the application writer
|
||||
* must provide the memory used to hold the task's data structures too.
|
||||
* xTaskCreateRestrictedStatic() therefore allows a memory protected task to be
|
||||
* created without using any dynamic memory allocation.
|
||||
*
|
||||
* @param pxTaskDefinition Pointer to a structure that contains a member
|
||||
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
|
||||
* documentation) plus an optional stack buffer and the memory region
|
||||
* definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure
|
||||
* contains an additional member, which is used to point to a variable of type
|
||||
* StaticTask_t - which is then used to hold the task's data structure.
|
||||
*
|
||||
* @param pxCreatedTask Used to pass back a handle by which the created task
|
||||
* can be referenced.
|
||||
*
|
||||
* @return pdPASS if the task was successfully created and added to a ready
|
||||
* list, otherwise an error code defined in the file projdefs.h
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Create an TaskParameters_t structure that defines the task to be created.
|
||||
// The StaticTask_t variable is only included in the structure when
|
||||
// configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can
|
||||
// be used to force the variable into the RTOS kernel's privileged data area.
|
||||
static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
|
||||
static const TaskParameters_t xCheckTaskParameters =
|
||||
{
|
||||
vATask, // pvTaskCode - the function that implements the task.
|
||||
"ATask", // pcName - just a text name for the task to assist debugging.
|
||||
100, // usStackDepth - the stack size DEFINED IN WORDS.
|
||||
NULL, // pvParameters - passed into the task function as the function parameters.
|
||||
( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
|
||||
cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
|
||||
|
||||
// xRegions - Allocate up to three separate memory regions for access by
|
||||
// the task, with appropriate access permissions. Different processors have
|
||||
// different memory alignment requirements - refer to the FreeRTOS documentation
|
||||
// for full information.
|
||||
{
|
||||
// Base address Length Parameters
|
||||
{ cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
|
||||
{ cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
|
||||
{ cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
|
||||
}
|
||||
|
||||
&xTaskBuffer; // Holds the task's data structure.
|
||||
};
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TaskHandle_t xHandle;
|
||||
|
||||
// Create a task from the const structure defined above. The task handle
|
||||
// is requested (the second parameter is not NULL) but in this case just for
|
||||
// demonstration purposes as its not actually used.
|
||||
xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
|
||||
|
||||
// Start the scheduler.
|
||||
vTaskStartScheduler();
|
||||
|
||||
// Will only get here if there was insufficient memory to create the idle
|
||||
// and/or timer task.
|
||||
for( ;; );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*<pre>
|
||||
|
@ -780,7 +843,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );</pre>
|
||||
* <pre>UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );</pre>
|
||||
*
|
||||
* INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.
|
||||
* See the configuration section for more information.
|
||||
|
@ -823,15 +886,15 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
* \defgroup uxTaskPriorityGet uxTaskPriorityGet
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask );</pre>
|
||||
* <pre>UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );</pre>
|
||||
*
|
||||
* A version of uxTaskPriorityGet() that can be used from an ISR.
|
||||
*/
|
||||
UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1358,6 +1421,12 @@ TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*
|
|||
* a value of 1 means 4 bytes) since the task started. The smaller the returned
|
||||
* number the closer the task has come to overflowing its stack.
|
||||
*
|
||||
* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the
|
||||
* same except for their return type. Using configSTACK_DEPTH_TYPE allows the
|
||||
* user to determine the return type. It gets around the problem of the value
|
||||
* overflowing on 8-bit types without breaking backward compatibility for
|
||||
* applications that expect an 8-bit return type.
|
||||
*
|
||||
* @param xTask Handle of the task associated with the stack to be checked.
|
||||
* Set xTask to NULL to check the stack of the calling task.
|
||||
*
|
||||
|
@ -1367,6 +1436,33 @@ TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*
|
|||
*/
|
||||
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task.h
|
||||
* <PRE>configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );</PRE>
|
||||
*
|
||||
* INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for
|
||||
* this function to be available.
|
||||
*
|
||||
* Returns the high water mark of the stack associated with xTask. That is,
|
||||
* the minimum free stack space there has been (in words, so on a 32 bit machine
|
||||
* a value of 1 means 4 bytes) since the task started. The smaller the returned
|
||||
* number the closer the task has come to overflowing its stack.
|
||||
*
|
||||
* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the
|
||||
* same except for their return type. Using configSTACK_DEPTH_TYPE allows the
|
||||
* user to determine the return type. It gets around the problem of the value
|
||||
* overflowing on 8-bit types without breaking backward compatibility for
|
||||
* applications that expect an 8-bit return type.
|
||||
*
|
||||
* @param xTask Handle of the task associated with the stack to be checked.
|
||||
* Set xTask to NULL to check the stack of the calling task.
|
||||
*
|
||||
* @return The smallest amount of free stack space there has been (in words, so
|
||||
* actual spaces on the stack rather than bytes) since the task referenced by
|
||||
* xTask was created.
|
||||
*/
|
||||
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* When using trace macros it is sometimes necessary to include task.h before
|
||||
FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,
|
||||
so the following two prototypes will cause a compilation error. This can be
|
||||
|
@ -1389,9 +1485,20 @@ constant. */
|
|||
* task.h
|
||||
* <pre>void xTaskGetApplicationTaskTag( TaskHandle_t xTask );</pre>
|
||||
*
|
||||
* Returns the pxHookFunction value assigned to the task xTask.
|
||||
* Returns the pxHookFunction value assigned to the task xTask. Do not
|
||||
* call from an interrupt service routine - call
|
||||
* xTaskGetApplicationTaskTagFromISR() instead.
|
||||
*/
|
||||
TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task.h
|
||||
* <pre>void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );</pre>
|
||||
*
|
||||
* Returns the pxHookFunction value assigned to the task xTask. Can
|
||||
* be called from an interrupt service routine.
|
||||
*/
|
||||
TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configUSE_APPLICATION_TASK_TAG ==1 */
|
||||
#endif /* ifdef configUSE_APPLICATION_TASK_TAG */
|
||||
|
||||
|
@ -1629,6 +1736,36 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
|
|||
*/
|
||||
void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>TickType_t xTaskGetIdleRunTimeCounter( void );</PRE>
|
||||
*
|
||||
* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
|
||||
* must both be defined as 1 for this function to be available. The application
|
||||
* must also then provide definitions for
|
||||
* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()
|
||||
* to configure a peripheral timer/counter and return the timers current count
|
||||
* value respectively. The counter should be at least 10 times the frequency of
|
||||
* the tick count.
|
||||
*
|
||||
* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
|
||||
* accumulated execution time being stored for each task. The resolution
|
||||
* of the accumulated time value depends on the frequency of the timer
|
||||
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
|
||||
* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total
|
||||
* execution time of each task into a buffer, xTaskGetIdleRunTimeCounter()
|
||||
* returns the total execution time of just the idle task.
|
||||
*
|
||||
* @return The total run time of the idle task. This is the amount of time the
|
||||
* idle task has actually been executing. The unit of time is dependent on the
|
||||
* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
|
||||
* portGET_RUN_TIME_COUNTER_VALUE() macros.
|
||||
*
|
||||
* \defgroup xTaskGetIdleRunTimeCounter xTaskGetIdleRunTimeCounter
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
TickType_t xTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>
|
||||
|
@ -2141,14 +2278,14 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
|
|||
* Removes a task from both the specified event list and the list of blocked
|
||||
* tasks, and places it on a ready queue.
|
||||
*
|
||||
* xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called
|
||||
* xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called
|
||||
* if either an event occurs to unblock a task, or the block timeout period
|
||||
* expires.
|
||||
*
|
||||
* xTaskRemoveFromEventList() is used when the event list is in task priority
|
||||
* order. It removes the list item from the head of the event list as that will
|
||||
* have the highest priority owning task of all the tasks on the event list.
|
||||
* xTaskRemoveFromUnorderedEventList() is used when the event list is not
|
||||
* vTaskRemoveFromUnorderedEventList() is used when the event list is not
|
||||
* ordered and the event list items hold something other than the owning tasks
|
||||
* priority. In this case the event list item value is updated to the value
|
||||
* passed in the xItemValue parameter.
|
||||
|
@ -2157,7 +2294,7 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
|
|||
* making the call, otherwise pdFALSE.
|
||||
*/
|
||||
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION;
|
||||
void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
|
||||
|
@ -2207,7 +2344,7 @@ BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;
|
|||
* Raises the priority of the mutex holder to that of the calling task should
|
||||
* the mutex holder have a priority less than the calling task.
|
||||
*/
|
||||
void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Set the priority of a task back to its proper priority in the case that it
|
||||
|
@ -2215,6 +2352,16 @@ void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTIO
|
|||
*/
|
||||
BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* If a higher priority task attempting to obtain a mutex caused a lower
|
||||
* priority task to inherit the higher priority task's priority - but the higher
|
||||
* priority task then timed out without obtaining the mutex, then the lower
|
||||
* priority task will disinherit the priority again - but only down as far as
|
||||
* the highest priority task that is still waiting for the mutex (if there were
|
||||
* more than one task waiting for the mutex).
|
||||
*/
|
||||
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
||||
*/
|
||||
|
@ -2237,7 +2384,7 @@ void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVIL
|
|||
void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Only avilable when configUSE_TICKLESS_IDLE is set to 1.
|
||||
* Only available when configUSE_TICKLESS_IDLE is set to 1.
|
||||
* Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port
|
||||
* specific sleep function to determine if it is ok to proceed with the sleep,
|
||||
* and if it is ok to proceed, if it is ok to sleep indefinitely.
|
||||
|
@ -2256,7 +2403,14 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
|
|||
* For internal use only. Increment the mutex held count when a mutex is
|
||||
* taken and return the handle of the task that has taken the mutex.
|
||||
*/
|
||||
void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* For internal use only. Same as vTaskSetTimeOutState(), but without a critial
|
||||
* section.
|
||||
*/
|
||||
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIMERS_H
|
||||
|
@ -75,10 +33,10 @@
|
|||
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||
#endif
|
||||
|
||||
/*lint -e537 This headers are only multiply included if the application code
|
||||
/*lint -save -e537 This headers are only multiply included if the application code
|
||||
happens to also be including task.h. */
|
||||
#include "task.h"
|
||||
/*lint +e537 */
|
||||
/*lint -restore */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -115,7 +73,8 @@ or interrupt version of the queue send function should be used. */
|
|||
* reference the subject timer in calls to other software timer API functions
|
||||
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||
*/
|
||||
typedef void * TimerHandle_t;
|
||||
struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||
typedef struct tmrTimerControl * TimerHandle_t;
|
||||
|
||||
/*
|
||||
* Defines the prototype to which timer callback functions must conform.
|
||||
|
@ -266,11 +225,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -396,12 +355,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
|
@ -1272,6 +1231,23 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvPar
|
|||
*/
|
||||
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/**
|
||||
* void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload );
|
||||
*
|
||||
* Updates a timer to be either an autoreload timer, in which case the timer
|
||||
* automatically resets itself each time it expires, or a one shot timer, in
|
||||
* which case the timer will only expire once unless it is manually restarted.
|
||||
*
|
||||
* @param xTimer The handle of the timer being updated.
|
||||
*
|
||||
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
||||
* expire repeatedly with a frequency set by the timer's period (see the
|
||||
* xTimerPeriodInTicks parameter of the xTimerCreate() API function). If
|
||||
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||
* enter the dormant state after it expires.
|
||||
*/
|
||||
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
|
||||
*
|
||||
|
@ -1305,6 +1281,11 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
|||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -81,7 +39,7 @@ void vListInitialise( List_t * const pxList )
|
|||
/* The list structure contains a list item which is used to mark the
|
||||
end of the list. To initialise the list the list end is inserted
|
||||
as the only list entry. */
|
||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
|
||||
/* The list end value is the highest possible value in the list to
|
||||
ensure it remains at the end of the list. */
|
||||
|
@ -89,8 +47,8 @@ void vListInitialise( List_t * const pxList )
|
|||
|
||||
/* The list end next and previous pointers point to itself so we know
|
||||
when the list is empty. */
|
||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
|
||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||
|
||||
|
@ -104,7 +62,7 @@ void vListInitialise( List_t * const pxList )
|
|||
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||
{
|
||||
/* Make sure the list item is not recorded as being on a list. */
|
||||
pxItem->pvContainer = NULL;
|
||||
pxItem->pxContainer = NULL;
|
||||
|
||||
/* Write known values into the list item if
|
||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
|
@ -136,7 +94,7 @@ ListItem_t * const pxIndex = pxList->pxIndex;
|
|||
pxIndex->pxPrevious = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
|
@ -156,7 +114,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||
|
||||
If the list already contains a list item with the same item value then the
|
||||
new list item should be placed after it. This ensures that TCB's which are
|
||||
new list item should be placed after it. This ensures that TCBs which are
|
||||
stored in ready lists (all of which have the same xItemValue value) get a
|
||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||
the iteration loop below will not end. Therefore the value is checked
|
||||
|
@ -169,18 +127,18 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
{
|
||||
/* *** NOTE ***********************************************************
|
||||
If you find your application is crashing here then likely causes are
|
||||
listed below. In addition see http://www.freertos.org/FAQHelp.html for
|
||||
listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
||||
more tips, and ensure configASSERT() is defined!
|
||||
http://www.freertos.org/a00110.html#configASSERT
|
||||
https://www.freertos.org/a00110.html#configASSERT
|
||||
|
||||
1) Stack overflow -
|
||||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||
parts where numerically high priority values denote low actual
|
||||
interrupt priorities, which can seem counter intuitive. See
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||
http://www.freertos.org/a00110.html
|
||||
https://www.freertos.org/a00110.html
|
||||
3) Calling an API function from within a critical section or when
|
||||
the scheduler is suspended, or calling an API function that does
|
||||
not end in "FromISR" from an interrupt.
|
||||
|
@ -189,7 +147,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
before vTaskStartScheduler() has been called?).
|
||||
**********************************************************************/
|
||||
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||
{
|
||||
/* There is nothing to do here, just iterating to the wanted
|
||||
insertion position. */
|
||||
|
@ -203,7 +161,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
|
||||
/* Remember which list the item is in. This allows fast removal of the
|
||||
item later. */
|
||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
|
@ -213,7 +171,7 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
|||
{
|
||||
/* The list item knows which list it is in. Obtain the list from the list
|
||||
item. */
|
||||
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||
|
||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||
|
@ -231,7 +189,7 @@ List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
|||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
pxItemToRemove->pvContainer = NULL;
|
||||
pxItemToRemove->pxContainer = NULL;
|
||||
( pxList->uxNumberOfItems )--;
|
||||
|
||||
return pxList->uxNumberOfItems;
|
||||
|
|
|
@ -1,66 +1,30 @@
|
|||
/*
|
||||
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that has become a de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly and support the FreeRTOS *
|
||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* Thank you! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
|
||||
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||
>>! the source code for proprietary components outside of the FreeRTOS
|
||||
>>! kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for ESP8266
|
||||
|
@ -73,10 +37,12 @@
|
|||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtensa_ops.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
unsigned cpu_sr;
|
||||
|
@ -91,6 +57,13 @@ char level1_int_disabled;
|
|||
*/
|
||||
void *xPortSupervisorStackPointer;
|
||||
|
||||
void vAssertCalled(const char * pcFile, unsigned long ulLine)
|
||||
{
|
||||
printf("rtos assert %s %lu\n", pcFile, ulLine);
|
||||
abort();
|
||||
//for (;;);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stack initialization
|
||||
*/
|
||||
|
@ -100,7 +73,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
|
|||
portSTACK_TYPE *sp, *tp;
|
||||
|
||||
/* Create interrupt stack frame aligned to 16 byte boundary */
|
||||
sp = (portSTACK_TYPE*) (((uint32_t)(pxTopOfStack+1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
|
||||
sp = (portSTACK_TYPE*) (((uint32_t)(pxTopOfStack + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
|
||||
|
||||
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
|
||||
for (tp = sp; tp <= pxTopOfStack; ++tp)
|
||||
|
@ -121,30 +94,29 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
|
|||
static int pending_soft_sv;
|
||||
static int pending_maclayer_sv;
|
||||
|
||||
/* PendSV is called in place of vPortYield() to request a supervisor
|
||||
call.
|
||||
|
||||
The portYIELD macro calls pendSV if it's a software request.
|
||||
|
||||
The libpp and libudhcp libraries also call this function, assuming
|
||||
always with arg==2 (but maybe sometimes with arg==1?)
|
||||
|
||||
In the original esp_iot_rtos_sdk implementation, arg was a char. Using an
|
||||
enum is ABI-compatible, though.
|
||||
*/
|
||||
/*
|
||||
* The portYIELD macro calls PendSV with SVC_Software to set a pending interrupt
|
||||
* service callback that allows a task switch, and this occur when interrupts
|
||||
* are enabled which might be after exiting the critical region below.
|
||||
*
|
||||
* The wdev NMI calls this function from pp_post() with SVC_MACLayer to set a
|
||||
* pending interrupt service callback which flushs the queue of messages that
|
||||
* the NMI stashes away. This interrupt will be triggered after the return from
|
||||
* the NMI and when interrupts are enabled. The NMI can not touch the FreeRTOS
|
||||
* queues itself. The NMI must not touch the interrupt masks so that path must
|
||||
* not call vPortEnterCritical and vPortExitCritical.
|
||||
*/
|
||||
void IRAM PendSV(enum SVC_ReqType req)
|
||||
{
|
||||
if (req == SVC_Software) {
|
||||
vPortEnterCritical();
|
||||
|
||||
if(req == SVC_Software)
|
||||
{
|
||||
pending_soft_sv = 1;
|
||||
}
|
||||
else if(req == SVC_MACLayer)
|
||||
pending_maclayer_sv= 1;
|
||||
|
||||
WSR(BIT(INUM_SOFT), interrupt);
|
||||
vPortExitCritical();
|
||||
} else if (req == SVC_MACLayer) {
|
||||
pending_maclayer_sv= 1;
|
||||
WSR(BIT(INUM_SOFT), interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
/* This MAC layer ISR handler is defined in libpp.a, and is called
|
||||
|
@ -153,16 +125,14 @@ void IRAM PendSV(enum SVC_ReqType req)
|
|||
*/
|
||||
extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void);
|
||||
|
||||
void IRAM SV_ISR(void)
|
||||
void IRAM SV_ISR(void *arg)
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ;
|
||||
if(pending_maclayer_sv)
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE ;
|
||||
if (pending_maclayer_sv) {
|
||||
xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
|
||||
pending_maclayer_sv = 0;
|
||||
}
|
||||
if( xHigherPriorityTaskWoken || pending_soft_sv)
|
||||
{
|
||||
if (xHigherPriorityTaskWoken || pending_soft_sv) {
|
||||
sdk__xt_timer_int1();
|
||||
pending_soft_sv = 0;
|
||||
}
|
||||
|
@ -170,14 +140,9 @@ void IRAM SV_ISR(void)
|
|||
|
||||
void xPortSysTickHandle (void)
|
||||
{
|
||||
//CloseNMI();
|
||||
{
|
||||
if(xTaskIncrementTick() !=pdFALSE )
|
||||
{
|
||||
if (xTaskIncrementTick() != pdFALSE) {
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
}
|
||||
//OpenNMI();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -185,11 +150,11 @@ void xPortSysTickHandle (void)
|
|||
*/
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
_xt_isr_attach(INUM_SOFT, SV_ISR);
|
||||
_xt_isr_attach(INUM_SOFT, SV_ISR, NULL);
|
||||
_xt_isr_unmask(BIT(INUM_SOFT));
|
||||
|
||||
/* Initialize system tick timer interrupt and schedule the first tick. */
|
||||
_xt_isr_attach(INUM_TICK, sdk__xt_timer_int);
|
||||
_xt_isr_attach(INUM_TICK, sdk__xt_timer_int, NULL);
|
||||
_xt_isr_unmask(BIT(INUM_TICK));
|
||||
sdk__xt_tick_timer_init();
|
||||
|
||||
|
@ -221,8 +186,10 @@ size_t xPortGetFreeHeapSize( void )
|
|||
uint32_t brk_val = (uint32_t) sbrk(0);
|
||||
|
||||
intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
|
||||
if(sp == 0) /* scheduler not started */
|
||||
if (sp == 0) {
|
||||
/* scheduler not started */
|
||||
SP(sp);
|
||||
}
|
||||
return sp - brk_val + mi.fordblks;
|
||||
}
|
||||
|
||||
|
@ -233,8 +200,6 @@ void vPortEndScheduler( void )
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static unsigned portBASE_TYPE uxCriticalNesting = 0;
|
||||
|
||||
/* These nested vPortEnter/ExitCritical macros are called by SDK
|
||||
|
@ -243,26 +208,42 @@ static unsigned portBASE_TYPE uxCriticalNesting = 0;
|
|||
* It may be possible to replace the global nesting count variable
|
||||
* with a save/restore of interrupt level, although it's difficult as
|
||||
* the functions have no return value.
|
||||
*
|
||||
* These should not be called from the NMI in regular operation and
|
||||
* the NMI must not touch the interrupt mask, but that might occur in
|
||||
* exceptional paths such as aborts and debug code.
|
||||
*/
|
||||
void IRAM vPortEnterCritical( void )
|
||||
{
|
||||
void IRAM vPortEnterCritical(void) {
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void IRAM vPortExitCritical( void )
|
||||
{
|
||||
void IRAM vPortExitCritical(void) {
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == 0 )
|
||||
if (uxCriticalNesting == 0)
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
/* Backward compatibility with libmain.a and libpp.a and can remove when these are open. */
|
||||
signed portBASE_TYPE xTaskGenericCreate( TaskFunction_t pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, TaskHandle_t *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const MemoryRegion_t * const xRegions )
|
||||
{
|
||||
(void)puxStackBuffer; (void)xRegions;
|
||||
return xTaskCreate( pxTaskCode, (const char * const)pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask);
|
||||
/* Backward compatibility, for the sdk library. */
|
||||
|
||||
signed portBASE_TYPE xTaskGenericCreate(TaskFunction_t pxTaskCode,
|
||||
const signed char * const pcName,
|
||||
unsigned short usStackDepth,
|
||||
void *pvParameters,
|
||||
unsigned portBASE_TYPE uxPriority,
|
||||
TaskHandle_t *pxCreatedTask,
|
||||
portSTACK_TYPE *puxStackBuffer,
|
||||
const MemoryRegion_t * const xRegions) {
|
||||
(void)puxStackBuffer;
|
||||
(void)xRegions;
|
||||
return xTaskCreate(pxTaskCode, (const char * const)pcName, usStackDepth,
|
||||
pvParameters, uxPriority, pxCreatedTask);
|
||||
}
|
||||
|
||||
|
||||
BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer,
|
||||
TickType_t xTicksToWait, const BaseType_t xJustPeeking) {
|
||||
configASSERT(xJustPeeking == 0);
|
||||
return xQueueReceive(xQueue, pvBuffer, xTicksToWait);
|
||||
}
|
||||
|
|
|
@ -1,67 +1,30 @@
|
|||
/*
|
||||
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that has become a de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly and support the FreeRTOS *
|
||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* Thank you! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
|
||||
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||
>>! the source code for proprietary components outside of the FreeRTOS
|
||||
>>! kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
@ -92,18 +55,18 @@ extern "C" {
|
|||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE unsigned portLONG
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portPOINTER_SIZE_TYPE unsigned portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef unsigned portBASE_TYPE UBaseType_t;
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffff
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portARCH_NAME "ESP8266"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
@ -144,7 +107,7 @@ void PendSV(enum SVC_ReqType);
|
|||
ESPTODO: It may be possible to just read the 'ps' register instead
|
||||
of accessing thisvariable.
|
||||
*/
|
||||
extern char sdk_NMIIrqIsOn;
|
||||
extern uint8_t sdk_NMIIrqIsOn;
|
||||
extern char level1_int_disabled;
|
||||
extern unsigned cpu_sr;
|
||||
|
||||
|
@ -156,6 +119,9 @@ extern unsigned cpu_sr;
|
|||
prefer to _xt_disable_interrupts & _xt_enable_interrupts and store
|
||||
the ps value in a local variable - that approach is recursive-safe
|
||||
and generally better.
|
||||
|
||||
The NMI must not touch the interrupt mask and it should not in
|
||||
regular operation, but there is a guard here just in case.
|
||||
*/
|
||||
inline static __attribute__((always_inline)) void portDISABLE_INTERRUPTS(void)
|
||||
{
|
||||
|
@ -185,6 +151,10 @@ not necessary for to use this port. They are defined so the common demo files
|
|||
(which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
/* FreeRTOS API functions should not be called from the NMI handler. */
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT(sdk_NMIIrqIsOn == 0)
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
20
FreeRTOS/Source/portable/readme.txt
Normal file
20
FreeRTOS/Source/portable/readme.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
Each real time kernel port consists of three files that contain the core kernel
|
||||
components and are common to every port, and one or more files that are
|
||||
specific to a particular microcontroller and/or compiler.
|
||||
|
||||
|
||||
+ The FreeRTOS/Source/Portable/MemMang directory contains the five sample
|
||||
memory allocators as described on the http://www.FreeRTOS.org WEB site.
|
||||
|
||||
+ The other directories each contain files specific to a particular
|
||||
microcontroller or compiler, where the directory name denotes the compiler
|
||||
specific files the directory contains.
|
||||
|
||||
|
||||
|
||||
For example, if you are interested in the [compiler] port for the [architecture]
|
||||
microcontroller, then the port specific files are contained in
|
||||
FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the
|
||||
only port you are interested in then all the other directories can be
|
||||
ignored.
|
||||
|
File diff suppressed because it is too large
Load diff
1263
FreeRTOS/Source/stream_buffer.c
Normal file
1263
FreeRTOS/Source/stream_buffer.c
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,71 +1,29 @@
|
|||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
@ -84,11 +42,11 @@ task.h is included from an application file. */
|
|||
#error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
|
||||
#endif
|
||||
|
||||
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
||||
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
||||
header files above, but not in this file, in order to generate the correct
|
||||
privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
|
||||
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
for the header files above, but not in this file, in order to generate the
|
||||
correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */
|
||||
|
||||
|
||||
/* This entire source file will be skipped if the application is not configured
|
||||
|
@ -100,22 +58,29 @@ configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
|
|||
/* Misc definitions. */
|
||||
#define tmrNO_DELAY ( TickType_t ) 0U
|
||||
|
||||
/* The name assigned to the timer service task. This can be overridden by
|
||||
defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
|
||||
#ifndef configTIMER_SERVICE_TASK_NAME
|
||||
#define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
|
||||
#endif
|
||||
|
||||
/* Bit definitions used in the ucStatus member of a timer structure. */
|
||||
#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 )
|
||||
#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 )
|
||||
#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 )
|
||||
|
||||
/* The definition of the timers themselves. */
|
||||
typedef struct tmrTimerControl
|
||||
typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||
{
|
||||
const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
|
||||
TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
|
||||
UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */
|
||||
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
|
||||
TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
|
||||
#endif
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */
|
||||
#endif
|
||||
uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */
|
||||
} xTIMER;
|
||||
|
||||
/* The old xTIMER name is maintained above then typedefed to the new Timer_t
|
||||
|
@ -158,12 +123,15 @@ typedef struct tmrTimerQueueMessage
|
|||
} u;
|
||||
} DaemonTaskMessage_t;
|
||||
|
||||
/*lint -e956 A manual analysis and inspection has been used to determine which
|
||||
static variables must be declared volatile. */
|
||||
/*lint -save -e956 A manual analysis and inspection has been used to determine
|
||||
which static variables must be declared volatile. */
|
||||
|
||||
/* The list in which active timers are stored. Timers are referenced in expire
|
||||
time order, with the nearest expiry time at the front of the list. Only the
|
||||
timer service task is allowed to access these lists. */
|
||||
timer service task is allowed to access these lists.
|
||||
xActiveTimerList1 and xActiveTimerList2 could be at function scope but that
|
||||
breaks some kernel aware debuggers, and debuggers that reply on removing the
|
||||
static qualifier. */
|
||||
PRIVILEGED_DATA static List_t xActiveTimerList1;
|
||||
PRIVILEGED_DATA static List_t xActiveTimerList2;
|
||||
PRIVILEGED_DATA static List_t *pxCurrentTimerList;
|
||||
|
@ -173,7 +141,7 @@ PRIVILEGED_DATA static List_t *pxOverflowTimerList;
|
|||
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
|
||||
PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
|
||||
|
||||
/*lint +e956 */
|
||||
/*lint -restore */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -198,7 +166,7 @@ static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
|
|||
* task. Other tasks communicate with the timer service task using the
|
||||
* xTimerQueue queue.
|
||||
*/
|
||||
static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Called by the timer service task to interpret and process a command it
|
||||
|
@ -248,12 +216,12 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
|
|||
* Called after a Timer_t structure has been allocated either statically or
|
||||
* dynamically to fill in the structure's members.
|
||||
*/
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName,
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTimerCreateTimerTask( void )
|
||||
|
@ -276,7 +244,7 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
|
||||
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
ulTimerTaskStackSize,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
|
@ -291,7 +259,7 @@ BaseType_t xReturn = pdFAIL;
|
|||
#else
|
||||
{
|
||||
xReturn = xTaskCreate( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
configTIMER_TASK_STACK_DEPTH,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
|
@ -311,44 +279,39 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerCallbackFunction_t pxCallbackFunction )
|
||||
{
|
||||
Timer_t *pxNewTimer;
|
||||
|
||||
pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
|
||||
pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */
|
||||
|
||||
if( pxNewTimer != NULL )
|
||||
{
|
||||
/* Status is thus far zero as the timer is not created statically
|
||||
and has not been started. The autoreload bit may get set in
|
||||
prvInitialiseNewTimer. */
|
||||
pxNewTimer->ucStatus = 0x00;
|
||||
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Timers can be created statically or dynamically, so note this
|
||||
timer was created dynamically in case the timer is later
|
||||
deleted. */
|
||||
pxNewTimer->ucStaticallyAllocated = pdFALSE;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
}
|
||||
|
||||
return pxNewTimer;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
StaticTimer_t *pxTimerBuffer )
|
||||
{
|
||||
Timer_t *pxNewTimer;
|
||||
|
||||
|
@ -356,27 +319,25 @@ BaseType_t xReturn = pdFAIL;
|
|||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
variable of type StaticTimer_t equals the size of the real timer
|
||||
structures. */
|
||||
structure. */
|
||||
volatile size_t xSize = sizeof( StaticTimer_t );
|
||||
configASSERT( xSize == sizeof( Timer_t ) );
|
||||
( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* A pointer to a StaticTimer_t structure MUST be provided, use it. */
|
||||
configASSERT( pxTimerBuffer );
|
||||
pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */
|
||||
|
||||
if( pxNewTimer != NULL )
|
||||
{
|
||||
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Timers can be created statically or dynamically so note this
|
||||
timer was created statically in case it is later deleted. */
|
||||
pxNewTimer->ucStaticallyAllocated = pdTRUE;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
timer was created statically in case it is later deleted. The
|
||||
autoreload bit may get set in prvInitialiseNewTimer(). */
|
||||
pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;
|
||||
|
||||
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
|
||||
}
|
||||
|
||||
return pxNewTimer;
|
||||
|
@ -385,12 +346,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName,
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
Timer_t *pxNewTimer )
|
||||
{
|
||||
/* 0 is not a valid value for xTimerPeriodInTicks. */
|
||||
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||
|
@ -405,10 +366,13 @@ static void prvInitialiseNewTimer( const char * const pcTimerName,
|
|||
parameters. */
|
||||
pxNewTimer->pcTimerName = pcTimerName;
|
||||
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
|
||||
pxNewTimer->uxAutoReload = uxAutoReload;
|
||||
pxNewTimer->pvTimerID = pvTimerID;
|
||||
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
||||
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
||||
if( uxAutoReload != pdFALSE )
|
||||
{
|
||||
pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
|
||||
}
|
||||
traceTIMER_CREATE( pxNewTimer );
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +392,7 @@ DaemonTaskMessage_t xMessage;
|
|||
/* Send a command to the timer service task to start the xTimer timer. */
|
||||
xMessage.xMessageID = xCommandID;
|
||||
xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
|
||||
xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
|
||||
xMessage.u.xTimerParameters.pxTimer = xTimer;
|
||||
|
||||
if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
|
||||
{
|
||||
|
@ -468,16 +432,36 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
|
|||
|
||||
TickType_t xTimerGetPeriod( TimerHandle_t xTimer )
|
||||
{
|
||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
|
||||
Timer_t *pxTimer = xTimer;
|
||||
|
||||
configASSERT( xTimer );
|
||||
return pxTimer->xTimerPeriodInTicks;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload )
|
||||
{
|
||||
Timer_t * pxTimer = xTimer;
|
||||
|
||||
configASSERT( xTimer );
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
if( uxAutoReload != pdFALSE )
|
||||
{
|
||||
pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )
|
||||
{
|
||||
Timer_t * pxTimer = ( Timer_t * ) xTimer;
|
||||
Timer_t * pxTimer = xTimer;
|
||||
TickType_t xReturn;
|
||||
|
||||
configASSERT( xTimer );
|
||||
|
@ -488,7 +472,7 @@ TickType_t xReturn;
|
|||
|
||||
const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
|
||||
Timer_t *pxTimer = xTimer;
|
||||
|
||||
configASSERT( xTimer );
|
||||
return pxTimer->pcTimerName;
|
||||
|
@ -498,7 +482,7 @@ Timer_t *pxTimer = ( Timer_t * ) xTimer;
|
|||
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
|
||||
{
|
||||
BaseType_t xResult;
|
||||
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
|
||||
|
||||
/* Remove the timer from the list of active timers. A check has already
|
||||
been performed to ensure the list is not empty. */
|
||||
|
@ -507,7 +491,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
|
|||
|
||||
/* If the timer is an auto reload timer then calculate the next
|
||||
expiry time and re-insert the timer in the list of active timers. */
|
||||
if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
|
||||
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
|
||||
{
|
||||
/* The timer is inserted into a list using a time relative to anything
|
||||
other than the current time. It will therefore be inserted into the
|
||||
|
@ -527,6 +511,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
|
|||
}
|
||||
else
|
||||
{
|
||||
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
|
@ -535,7 +520,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTimerTask( void *pvParameters )
|
||||
static portTASK_FUNCTION( prvTimerTask, pvParameters )
|
||||
{
|
||||
TickType_t xNextExpireTime;
|
||||
BaseType_t xListWasEmpty;
|
||||
|
@ -760,7 +745,7 @@ TickType_t xTimeNow;
|
|||
software timer. */
|
||||
pxTimer = xMessage.u.xTimerParameters.pxTimer;
|
||||
|
||||
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
|
||||
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
|
||||
{
|
||||
/* The timer is in a list, remove it. */
|
||||
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
|
||||
|
@ -788,6 +773,7 @@ TickType_t xTimeNow;
|
|||
case tmrCOMMAND_RESET_FROM_ISR :
|
||||
case tmrCOMMAND_START_DONT_TRACE :
|
||||
/* Start or restart a timer. */
|
||||
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
|
||||
if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )
|
||||
{
|
||||
/* The timer expired before it was added to the active
|
||||
|
@ -795,7 +781,7 @@ TickType_t xTimeNow;
|
|||
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
|
||||
traceTIMER_EXPIRED( pxTimer );
|
||||
|
||||
if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
|
||||
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
|
||||
{
|
||||
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
|
||||
configASSERT( xResult );
|
||||
|
@ -814,12 +800,13 @@ TickType_t xTimeNow;
|
|||
|
||||
case tmrCOMMAND_STOP :
|
||||
case tmrCOMMAND_STOP_FROM_ISR :
|
||||
/* The timer has already been removed from the active list.
|
||||
There is nothing to do here. */
|
||||
/* The timer has already been removed from the active list. */
|
||||
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
|
||||
break;
|
||||
|
||||
case tmrCOMMAND_CHANGE_PERIOD :
|
||||
case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
|
||||
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
|
||||
pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
|
||||
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
|
||||
|
||||
|
@ -833,29 +820,28 @@ TickType_t xTimeNow;
|
|||
break;
|
||||
|
||||
case tmrCOMMAND_DELETE :
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* The timer has already been removed from the active list,
|
||||
just free up the memory if the memory was dynamically
|
||||
allocated. */
|
||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
{
|
||||
/* The timer can only have been allocated dynamically -
|
||||
free it again. */
|
||||
vPortFree( pxTimer );
|
||||
}
|
||||
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
{
|
||||
/* The timer could have been allocated statically or
|
||||
dynamically, so check before attempting to free the
|
||||
memory. */
|
||||
if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )
|
||||
{
|
||||
vPortFree( pxTimer );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* If dynamic allocation is not enabled, the memory
|
||||
could not have been dynamically allocated. So there is
|
||||
no need to free the memory - just mark the timer as
|
||||
"not active". */
|
||||
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
break;
|
||||
|
||||
|
@ -884,7 +870,7 @@ BaseType_t xResult;
|
|||
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||
|
||||
/* Remove the timer from the list. */
|
||||
pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||
pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
|
||||
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
|
||||
traceTIMER_EXPIRED( pxTimer );
|
||||
|
||||
|
@ -893,7 +879,7 @@ BaseType_t xResult;
|
|||
have not yet been switched. */
|
||||
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
|
||||
|
||||
if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
|
||||
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
|
||||
{
|
||||
/* Calculate the reload value, and if the reload value results in
|
||||
the timer going into the same timer list then it has already expired
|
||||
|
@ -945,10 +931,10 @@ static void prvCheckForValidListAndQueue( void )
|
|||
{
|
||||
/* The timer queue is allocated statically in case
|
||||
configSUPPORT_DYNAMIC_ALLOCATION is 0. */
|
||||
static StaticQueue_t xStaticTimerQueue;
|
||||
static uint8_t ucStaticTimerQueueStorage[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ];
|
||||
static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
|
||||
static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
|
||||
|
||||
xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
|
||||
xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
@ -980,28 +966,32 @@ static void prvCheckForValidListAndQueue( void )
|
|||
|
||||
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
|
||||
{
|
||||
BaseType_t xTimerIsInActiveList;
|
||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
|
||||
BaseType_t xReturn;
|
||||
Timer_t *pxTimer = xTimer;
|
||||
|
||||
configASSERT( xTimer );
|
||||
|
||||
/* Is the timer in the list of active timers? */
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Checking to see if it is in the NULL list in effect checks to see if
|
||||
it is referenced from either the current or the overflow timer lists in
|
||||
one go, but the logic has to be reversed, hence the '!'. */
|
||||
xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
|
||||
if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return xTimerIsInActiveList;
|
||||
return xReturn;
|
||||
} /*lint !e818 Can't be pointer to const due to the typedef. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void *pvTimerGetTimerID( const TimerHandle_t xTimer )
|
||||
{
|
||||
Timer_t * const pxTimer = ( Timer_t * ) xTimer;
|
||||
Timer_t * const pxTimer = xTimer;
|
||||
void *pvReturn;
|
||||
|
||||
configASSERT( xTimer );
|
||||
|
@ -1018,7 +1008,7 @@ void *pvReturn;
|
|||
|
||||
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )
|
||||
{
|
||||
Timer_t * const pxTimer = ( Timer_t * ) xTimer;
|
||||
Timer_t * const pxTimer = xTimer;
|
||||
|
||||
configASSERT( xTimer );
|
||||
|
||||
|
@ -1083,6 +1073,26 @@ Timer_t * const pxTimer = ( Timer_t * ) xTimer;
|
|||
#endif /* INCLUDE_xTimerPendFunctionCall */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer )
|
||||
{
|
||||
return ( ( Timer_t * ) xTimer )->uxTimerNumber;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber )
|
||||
{
|
||||
( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This entire source file will be skipped if the application is not configured
|
||||
to include software timer functionality. If you want to include software timer
|
||||
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
Directories:
|
||||
|
||||
+ The FreeRTOS/Source directory contains the FreeRTOS source code, and contains
|
||||
its own readme file.
|
||||
|
||||
+ The FreeRTOS/Demo directory contains a demo application for every official
|
||||
FreeRTOS port, and contains its own readme file.
|
||||
|
||||
+ See http://www.freertos.org/a00017.html for full details of the directory
|
||||
structure and information on locating the files you require.
|
||||
|
||||
The easiest way to use FreeRTOS is to start with one of the pre-configured demo
|
||||
application projects (found in the FreeRTOS/Demo directory). That way you will
|
||||
have the correct FreeRTOS source files included, and the correct include paths
|
||||
configured. Once a demo application is building and executing you can remove
|
||||
the demo application file, and start to add in your own application source
|
||||
files.
|
||||
|
||||
See also -
|
||||
http://www.freertos.org/FreeRTOS-quick-start-guide.html
|
||||
http://www.freertos.org/FAQHelp.html
|
|
@ -77,9 +77,9 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl
|
|||
|
||||
## Open Source Components
|
||||
|
||||
* [FreeRTOS](http://www.freertos.org/) V9.0.0
|
||||
* [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v1.4.1, modified via the [esp-lwip project](https://github.com/kadamski/esp-lwip) by @kadamski.
|
||||
* [newlib](https://github.com/projectgus/newlib-xtensa) v2.2.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS.
|
||||
* [FreeRTOS](http://www.freertos.org/) V10.2.0
|
||||
* [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v2.0.3, with [some modifications](https://github.com/ourairquality/lwip/).
|
||||
* [newlib](https://github.com/ourairquality/newlib) v3.0.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS.
|
||||
|
||||
For details of how third party libraries are integrated, [see the wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries).
|
||||
|
||||
|
@ -100,7 +100,7 @@ Some binary libraries appear to contain unattributed open source code:
|
|||
|
||||
* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki). lwIP is Copyright (C) Swedish Institute of Computer Science.
|
||||
|
||||
* FreeRTOS is provided under the GPL with the FreeRTOS linking exception, allowing non-GPL firmwares to be produced using FreeRTOS as the RTOS core. License details in files under FreeRTOS dir. FreeRTOS is Copyright (C) Real Time Engineers Ltd.
|
||||
* FreeRTOS (since v10) is provided under the MIT license. License details in files under FreeRTOS dir. FreeRTOS is Copyright (C) Amazon.
|
||||
|
||||
* Source & binary components from the [Espressif IOT RTOS SDK](https://github.com/espressif/esp_iot_rtos_sdk) were released under the MIT license. Source code components are relicensed here under the BSD license. The original parts are Copyright (C) Espressif Systems.
|
||||
|
||||
|
|
10
bootloader/c_types.h
Normal file
10
bootloader/c_types.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* rboot type definitions */
|
||||
|
||||
|
||||
typedef int int32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
|
@ -1 +1 @@
|
|||
Subproject commit 30afbaa777e00abf9d7d469fb3345f118c4975c1
|
||||
Subproject commit 3b067a8686a07474c5f722953d3b2f0e71db681f
|
42
common.mk
42
common.mk
|
@ -146,7 +146,7 @@ ifndef $(1)_WHOLE_ARCHIVE
|
|||
$(1)_AR_IN_FILES += $$($(1)_SRC_FILES)
|
||||
endif
|
||||
|
||||
$$($(1)_AR): $$($(1)_OBJ_FILES) $$($(1)_SRC_IN_AR_FILES)
|
||||
$$($(1)_AR): $$($(1)_AR_IN_FILES)
|
||||
$(vecho) "AR $$@"
|
||||
$(Q) mkdir -p $$(dir $$@)
|
||||
$(Q) $(AR) cru $$@ $$^
|
||||
|
@ -160,6 +160,26 @@ endif
|
|||
-include $$($(1)_OBJ_FILES:.o=.d)
|
||||
endef
|
||||
|
||||
# Remove comment lines from libgcc.remove file
|
||||
$(BUILD_DIR)libgcc.remove: $(ROOT)lib/libgcc.remove | $(BUILD_DIR)
|
||||
$(Q) grep -v "^#" $< | cat > $@
|
||||
|
||||
# Remove unwanted object files listed in libgcc.remove
|
||||
$(BUILD_DIR)libgcc.a: $(ROOT)lib/libgcc.a $(BUILD_DIR)libgcc.remove | $(BUILD_DIR)
|
||||
@echo "Removing unwanted objects from $<"
|
||||
$(Q) cat $< > $@
|
||||
$(Q) $(AR) d $@ @$(word 2,$^)
|
||||
|
||||
# Remove comment lines from libc.remove file
|
||||
$(BUILD_DIR)libc.remove: $(ROOT)libc/libc.remove | $(BUILD_DIR)
|
||||
$(Q) grep -v "^#" $< | cat > $@
|
||||
|
||||
# Remove unwanted object files listed in libgcc.remove
|
||||
$(BUILD_DIR)libc.a: $(ROOT)libc/xtensa-lx106-elf/lib/libc.a $(BUILD_DIR)libc.remove | $(BUILD_DIR)
|
||||
@echo "Removing unwanted objects from $<"
|
||||
$(Q) cat $< > $@
|
||||
$(Q) $(AR) d $@ @$(word 2,$^)
|
||||
|
||||
## Linking rules for SDK libraries
|
||||
## SDK libraries are preprocessed to:
|
||||
# - remove object files named in <libname>.remove
|
||||
|
@ -208,9 +228,9 @@ $(foreach component,$(COMPONENTS), \
|
|||
)
|
||||
|
||||
# final linking step to produce .elf
|
||||
$(PROGRAM_OUT): $(WHOLE_ARCHIVES) $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS)
|
||||
$(PROGRAM_OUT): $(WHOLE_ARCHIVES) $(COMPONENT_ARS) $(BUILD_DIR)libgcc.a $(BUILD_DIR)libc.a $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS)
|
||||
$(vecho) "LD $@"
|
||||
$(Q) $(LD) $(LDFLAGS) -Wl,--whole-archive $(WHOLE_ARCHIVES) -Wl,--no-whole-archive -Wl,--start-group $(COMPONENT_ARS) $(LIB_ARGS) $(SDK_LIB_ARGS) -Wl,--end-group -o $@
|
||||
$(Q) $(LD) $(LDFLAGS) -Wl,--whole-archive $(WHOLE_ARCHIVES) -Wl,--no-whole-archive -Wl,--start-group $(COMPONENT_ARS) $(BUILD_DIR)libgcc.a $(BUILD_DIR)libc.a $(LIB_ARGS) $(SDK_LIB_ARGS) -Wl,--end-group -o $@
|
||||
|
||||
$(BUILD_DIR) $(FIRMWARE_DIR) $(BUILD_DIR)sdklib:
|
||||
$(Q) mkdir -p $@
|
||||
|
@ -223,17 +243,16 @@ $(FW_FILE): $(PROGRAM_OUT) $(FIRMWARE_DIR)
|
|||
$(vecho) "FW $@"
|
||||
$(Q) $(ESPTOOL) elf2image --version=2 $(ESPTOOL_ARGS) $< -o $(FW_FILE)
|
||||
|
||||
ESPTOOL_FLASH_CMD ?= -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPTOOL_ARGS) \
|
||||
0x0 $(RBOOT_BIN) 0x1000 $(RBOOT_CONF) 0x2000 $(FW_FILE) $(SPIFFS_ESPTOOL_ARGS)
|
||||
|
||||
flash: all
|
||||
$(Q) $(ESPTOOL) $(ESPTOOL_FLASH_CMD)
|
||||
|
||||
print_flash_cmd:
|
||||
$(Q) echo "$(ESPTOOL_FLASH_CMD)"
|
||||
$(if will_flash, $(call will_flash, "flash"))
|
||||
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPTOOL_ARGS) \
|
||||
$(RBOOT_ARGS) 0x2000 $(FW_FILE) $(SPIFFS_ESPTOOL_ARGS)
|
||||
$(if did_flash, $(call did_flash, "flash"))
|
||||
|
||||
erase_flash:
|
||||
$(if will_flash, $(call will_flash, "erase"))
|
||||
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) erase_flash
|
||||
$(if did_flash, $(call did_flash, "erase"))
|
||||
|
||||
size: $(PROGRAM_OUT)
|
||||
$(Q) $(CROSS)size --format=sysv $(PROGRAM_OUT)
|
||||
|
@ -275,9 +294,6 @@ help:
|
|||
@echo "test"
|
||||
@echo "'flash', then start a GNU Screen session on the same serial port to see serial output."
|
||||
@echo ""
|
||||
@echo "print_flash_cmd"
|
||||
@echo "Just print command line arguments for flashing with esptool.py"
|
||||
@echo ""
|
||||
@echo "size"
|
||||
@echo "Build, then print a summary of built firmware size."
|
||||
@echo ""
|
||||
|
|
105
core/app_main.c
105
core/app_main.c
|
@ -21,13 +21,17 @@
|
|||
#include "esp/spi_regs.h"
|
||||
#include "esp/dport_regs.h"
|
||||
#include "esp/wdev_regs.h"
|
||||
#include "esp/wdt_regs.h"
|
||||
#include "esp/rtcmem_regs.h"
|
||||
#include "esp/hwrand.h"
|
||||
#include "os_version.h"
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "espressif/phy_info.h"
|
||||
#include "sdk_internal.h"
|
||||
#include "esplibs/libmain.h"
|
||||
#include "esplibs/libnet80211.h"
|
||||
#include "esplibs/libphy.h"
|
||||
#include "esplibs/libpp.h"
|
||||
#include "sysparam.h"
|
||||
|
||||
/* This is not declared in any header file (but arguably should be) */
|
||||
|
@ -130,6 +134,10 @@ static void IRAM default_putc(char c) {
|
|||
uart_putc(0, c);
|
||||
}
|
||||
|
||||
void init_newlib_locks(void);
|
||||
extern uint8_t sdk_wDevCtrl[];
|
||||
void nano_malloc_insert_chunk(void *start, size_t size);
|
||||
|
||||
// .text+0x258
|
||||
void IRAM sdk_user_start(void) {
|
||||
uint32_t buf32[sizeof(struct sdk_g_ic_saved_st) / 4];
|
||||
|
@ -166,25 +174,32 @@ void IRAM sdk_user_start(void) {
|
|||
}
|
||||
switch (buf8[3] >> 4) {
|
||||
case 0x0: // 4 Mbit (512 KByte)
|
||||
flash_sectors = 128;
|
||||
flash_size = 524288;
|
||||
break;
|
||||
case 0x1: // 2 Mbit (256 Kbyte)
|
||||
flash_sectors = 64;
|
||||
flash_size = 262144;
|
||||
break;
|
||||
case 0x2: // 8 Mbit (1 Mbyte)
|
||||
flash_sectors = 256;
|
||||
flash_size = 1048576;
|
||||
break;
|
||||
case 0x3: // 16 Mbit (2 Mbyte)
|
||||
flash_sectors = 512;
|
||||
case 0x5: // 16 Mbit (2 Mbyte)
|
||||
flash_size = 2097152;
|
||||
break;
|
||||
case 0x4: // 32 Mbit (4 Mbyte)
|
||||
flash_sectors = 1024;
|
||||
case 0x6: // 32 Mbit (4 Mbyte)
|
||||
flash_size = 4194304;
|
||||
break;
|
||||
case 0x8: // 64 Mbit (8 Mbyte)
|
||||
flash_size = 8388608;
|
||||
break;
|
||||
case 0x9: // 128 Mbit (16 Mbyte)
|
||||
flash_size = 16777216;
|
||||
break;
|
||||
default: // Invalid -- Assume 4 Mbit (512 KByte)
|
||||
flash_sectors = 128;
|
||||
flash_size = 524288;
|
||||
}
|
||||
//FIXME: we should probably calculate flash_sectors by starting with flash_size and dividing by sdk_flashchip.sector_size instead of vice-versa.
|
||||
flash_size = flash_sectors * 4096;
|
||||
flash_sectors = flash_size / sdk_flashchip.sector_size;
|
||||
sdk_flashchip.chip_size = flash_size;
|
||||
set_spi0_divisor(flash_speed_divisor);
|
||||
sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE);
|
||||
|
@ -197,6 +212,15 @@ void IRAM sdk_user_start(void) {
|
|||
Cache_Read_Enable(0, 0, 1);
|
||||
zero_bss();
|
||||
sdk_os_install_putc1(default_putc);
|
||||
|
||||
/* HACK Reclaim a region of unused bss from wdev.o. This would not be
|
||||
* necessary if the source code to wdev were available, and then it would
|
||||
* not be a fragmented area, but the extra memory is desparately needed and
|
||||
* it is in very useful dram. */
|
||||
nano_malloc_insert_chunk((void *)(sdk_wDevCtrl + 0x2190), 8000);
|
||||
|
||||
init_newlib_locks();
|
||||
|
||||
if (cksum_magic == 0xffffffff) {
|
||||
// No checksum required
|
||||
} else if ((cksum_magic == 0x55aa55aa) &&
|
||||
|
@ -210,8 +234,8 @@ void IRAM sdk_user_start(void) {
|
|||
memcpy(&sdk_g_ic.s, buf32, sizeof(struct sdk_g_ic_saved_st));
|
||||
|
||||
// By default, put the sysparam region just below the config sectors at the
|
||||
// top of the flash space
|
||||
sysparam_addr = flash_size - (4 + DEFAULT_SYSPARAM_SECTORS) * sdk_flashchip.sector_size;
|
||||
// top of the flash space, and allowing one extra sector spare.
|
||||
sysparam_addr = flash_size - (5 + DEFAULT_SYSPARAM_SECTORS) * sdk_flashchip.sector_size;
|
||||
status = sysparam_init(sysparam_addr, flash_size);
|
||||
if (status == SYSPARAM_NOTFOUND) {
|
||||
status = sysparam_create_area(sysparam_addr, DEFAULT_SYSPARAM_SECTORS, false);
|
||||
|
@ -232,12 +256,12 @@ void IRAM vApplicationStackOverflowHook(TaskHandle_t task, char *task_name) {
|
|||
}
|
||||
|
||||
// .text+0x3d8
|
||||
void IRAM vApplicationIdleHook(void) {
|
||||
void __attribute__((weak)) IRAM vApplicationIdleHook(void) {
|
||||
printf("idle %u\n", WDEV.SYS_TIME);
|
||||
}
|
||||
|
||||
// .text+0x404
|
||||
void IRAM vApplicationTickHook(void) {
|
||||
void __attribute__((weak)) IRAM vApplicationTickHook(void) {
|
||||
printf("tick %u\n", WDEV.SYS_TIME);
|
||||
}
|
||||
|
||||
|
@ -252,12 +276,25 @@ static void zero_bss(void) {
|
|||
|
||||
// .Lfunc006 -- .irom0.text+0x70
|
||||
static void init_networking(sdk_phy_info_t *phy_info, uint8_t *mac_addr) {
|
||||
// The call to sdk_register_chipv6_phy appears to change the bus clock,
|
||||
// perhaps from 40MHz to 26MHz, at least it has such an effect on the uart
|
||||
// baud rate. The caller flushes the TX fifos.
|
||||
if (sdk_register_chipv6_phy(phy_info)) {
|
||||
printf("FATAL: sdk_register_chipv6_phy failed");
|
||||
abort();
|
||||
}
|
||||
uart_set_baud(0, 74906);
|
||||
uart_set_baud(1, 74906);
|
||||
|
||||
// The boot rom initializes uart0 for a 115200 baud rate but the bus clock
|
||||
// does not appear to be as expected so the initial baud rate is actually
|
||||
// 74906. On a cold boot, to keep the 74906 baud rate the uart0 divisor
|
||||
// would need to changed here to 74906. On a warm boot the bus clock is
|
||||
// expected to have already been set so the boot baud rate is 115200.
|
||||
// Reset the rate here and settle on a 115200 baud rate.
|
||||
if (sdk_rst_if.reason > 0) {
|
||||
uart_set_baud(0, 115200);
|
||||
uart_set_baud(1, 115200);
|
||||
}
|
||||
|
||||
sdk_phy_disable_agc();
|
||||
sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode);
|
||||
sdk_lmacInit();
|
||||
|
@ -294,13 +331,13 @@ static void init_g_ic(void) {
|
|||
if (sdk_g_ic.s._unknown310 > 4) {
|
||||
sdk_g_ic.s._unknown310 = 4;
|
||||
}
|
||||
if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) {
|
||||
bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4));
|
||||
bzero(&sdk_g_ic.s._unknown20f, sizeof(sdk_g_ic.s._unknown20f));
|
||||
if (sdk_g_ic.s.sta_ssid.ssid_length == 0xffffffff) {
|
||||
bzero(&sdk_g_ic.s.sta_ssid, sizeof(sdk_g_ic.s.sta_ssid));
|
||||
bzero(&sdk_g_ic.s.sta_password, sizeof(sdk_g_ic.s.sta_password));
|
||||
}
|
||||
sdk_g_ic.s.wifi_led_enable = 0;
|
||||
if (sdk_g_ic.s._unknown281 > 1) {
|
||||
sdk_g_ic.s._unknown281 = 0;
|
||||
if (sdk_g_ic.s.sta_bssid_set > 1) {
|
||||
sdk_g_ic.s.sta_bssid_set = 0;
|
||||
}
|
||||
if (sdk_g_ic.s.ap_number > 5) {
|
||||
sdk_g_ic.s.ap_number = 1;
|
||||
|
@ -322,10 +359,16 @@ void sdk_wdt_init(void) {
|
|||
sdk_pp_soft_wdt_init();
|
||||
}
|
||||
|
||||
extern void *xPortSupervisorStackPointer;
|
||||
|
||||
// .irom0.text+0x474
|
||||
void sdk_user_init_task(void *params) {
|
||||
int phy_ver, pp_ver;
|
||||
|
||||
/* The start up stack is not used after scheduling has started, so all of
|
||||
* the top area of RAM which was stack can be used for the dynamic heap. */
|
||||
xPortSupervisorStackPointer = (void *)0x40000000;
|
||||
|
||||
sdk_ets_timer_init();
|
||||
printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__);
|
||||
phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16;
|
||||
|
@ -335,18 +378,24 @@ void sdk_user_init_task(void *params) {
|
|||
user_init();
|
||||
sdk_user_init_flag = 1;
|
||||
sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode);
|
||||
if (sdk_g_ic.s.wifi_mode == 1) {
|
||||
if (sdk_g_ic.s.wifi_mode == STATION_MODE) {
|
||||
sdk_wifi_station_start();
|
||||
LOCK_TCPIP_CORE();
|
||||
netif_set_default(sdk_g_ic.v.station_netif_info->netif);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
}
|
||||
if (sdk_g_ic.s.wifi_mode == 2) {
|
||||
if (sdk_g_ic.s.wifi_mode == SOFTAP_MODE) {
|
||||
sdk_wifi_softap_start();
|
||||
LOCK_TCPIP_CORE();
|
||||
netif_set_default(sdk_g_ic.v.softap_netif_info->netif);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
}
|
||||
if (sdk_g_ic.s.wifi_mode == 3) {
|
||||
if (sdk_g_ic.s.wifi_mode == STATIONAP_MODE) {
|
||||
sdk_wifi_station_start();
|
||||
sdk_wifi_softap_start();
|
||||
netif_set_default(sdk_g_ic.v.softap_netif_info->netif);
|
||||
LOCK_TCPIP_CORE();
|
||||
netif_set_default(sdk_g_ic.v.station_netif_info->netif);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
}
|
||||
if (sdk_wifi_station_get_auto_connect()) {
|
||||
sdk_wifi_station_connect();
|
||||
|
@ -374,9 +423,9 @@ static __attribute__((noinline)) void user_start_phase2(void) {
|
|||
sdk_sleep_reset_analog_rtcreg_8266();
|
||||
get_otp_mac_address(sdk_info.sta_mac_addr);
|
||||
sdk_wifi_softap_cacl_mac(sdk_info.softap_mac_addr, sdk_info.sta_mac_addr);
|
||||
sdk_info._unknown0 = 0x0104a8c0;
|
||||
sdk_info._unknown4 = 0x00ffffff;
|
||||
sdk_info._unknown8 = 0x0104a8c0;
|
||||
sdk_info.softap_ipaddr.addr = 0x0104a8c0; // 192.168.4.1
|
||||
sdk_info.softap_netmask.addr = 0x00ffffff; // 255.255.255.0
|
||||
sdk_info.softap_gw.addr = 0x0104a8c0; // 192.168.4.1
|
||||
init_g_ic();
|
||||
|
||||
read_saved_phy_info(&phy_info);
|
||||
|
@ -389,8 +438,6 @@ static __attribute__((noinline)) void user_start_phase2(void) {
|
|||
memcpy(&phy_info, &default_phy_info, sizeof(sdk_phy_info_t));
|
||||
}
|
||||
|
||||
// Disable default buffering on stdout
|
||||
setbuf(stdout, NULL);
|
||||
// Wait for UARTs to finish sending anything in their queues.
|
||||
uart_flush_txfifo(0);
|
||||
uart_flush_txfifo(1);
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *operator new(size_t size)
|
||||
void * __attribute__((weak)) operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
void * __attribute__((weak)) operator new[](size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void * ptr)
|
||||
void __attribute__((weak)) operator delete(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void * ptr)
|
||||
void __attribute__((weak)) operator delete[](void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include "xtensa_ops.h"
|
||||
#include "esp/rom.h"
|
||||
#include "esp/uart.h"
|
||||
#include "esp/dport_regs.h"
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esplibs/libmain.h"
|
||||
#include "user_exception.h"
|
||||
|
||||
/* Forward declarations */
|
||||
static void IRAM fatal_handler_prelude(void);
|
||||
|
@ -32,6 +34,8 @@ static void __attribute__((noinline)) __attribute__((noreturn)) abort_handler_in
|
|||
|
||||
static IRAM_DATA fatal_exception_handler_fn fatal_exception_handler_inner = standard_fatal_exception_handler_inner;
|
||||
|
||||
static void (*user_exception_handler)(void) = NULL;
|
||||
|
||||
/* fatal_exception_handler called from any unhandled user exception
|
||||
*
|
||||
* (similar to a hard fault on other processor architectures)
|
||||
|
@ -156,6 +160,10 @@ static void IRAM fatal_handler_prelude(void) {
|
|||
}
|
||||
Cache_Read_Disable();
|
||||
Cache_Read_Enable(0, 0, 1);
|
||||
|
||||
if (user_exception_handler != NULL) {
|
||||
user_exception_handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* Main part of fatal exception handler, is run from flash to save
|
||||
|
@ -229,3 +237,9 @@ static void abort_handler_inner(uint32_t *caller, uint32_t *sp) {
|
|||
dump_heapinfo();
|
||||
post_crash_reset();
|
||||
}
|
||||
|
||||
void set_user_exception_handler(void (*fn)(void))
|
||||
{
|
||||
user_exception_handler = fn;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,3 +56,34 @@ void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep)
|
|||
iomux_set_pullup_flags(gpio_to_iomux(gpio_num), flags);
|
||||
}
|
||||
|
||||
static gpio_interrupt_handler_t gpio_interrupt_handlers[16] = { 0 };
|
||||
|
||||
void __attribute__((weak)) IRAM gpio_interrupt_handler(void *arg)
|
||||
{
|
||||
uint32_t status_reg = GPIO.STATUS;
|
||||
GPIO.STATUS_CLEAR = status_reg;
|
||||
|
||||
uint8_t gpio_idx;
|
||||
while ((gpio_idx = __builtin_ffs(status_reg)))
|
||||
{
|
||||
gpio_idx--;
|
||||
status_reg &= ~BIT(gpio_idx);
|
||||
if (FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_idx])) {
|
||||
gpio_interrupt_handler_t handler = gpio_interrupt_handlers[gpio_idx];
|
||||
if (handler) {
|
||||
handler(gpio_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type, gpio_interrupt_handler_t handler)
|
||||
{
|
||||
gpio_interrupt_handlers[gpio_num] = handler;
|
||||
|
||||
GPIO.CONF[gpio_num] = SET_FIELD(GPIO.CONF[gpio_num], GPIO_CONF_INTTYPE, int_type);
|
||||
if (int_type != GPIO_INTTYPE_NONE) {
|
||||
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler, NULL);
|
||||
_xt_isr_unmask(1<<INUM_GPIO);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/* ESP GPIO interrupts.
|
||||
|
||||
Use with gpio_set_interrupt(), defined in esp/gpio.h
|
||||
|
||||
These interrupt vectors are default implementations with weak
|
||||
linkage. If you write your own GPIO interrupt vectors in your program
|
||||
then they will replace these at link time.
|
||||
|
||||
Look in examples/button/ for a simple GPIO interrupt example.
|
||||
|
||||
You can implement GPIO interrupt handlers in either of two ways:
|
||||
|
||||
- Implement gpXX_interrupt_handler() for each GPIO pin number that
|
||||
you want to use interrupt with. This is simple but it may not
|
||||
be enough in all cases.
|
||||
|
||||
void gpio01_interrupt_handler(void) {
|
||||
// Do something when GPIO 01 changes
|
||||
}
|
||||
|
||||
void gpio12_interrupt_handler(void) {
|
||||
// Do something when GPIO 12 changes
|
||||
}
|
||||
|
||||
OR
|
||||
|
||||
- Implement a single function named gpio_interrupt_handler(). This
|
||||
will need to manually check GPIO.STATUS and clear any status
|
||||
bits after handling interrupts. This gives you full control, but
|
||||
you can't combine it with the first approach.
|
||||
|
||||
|
||||
Part of esp-open-rtos
|
||||
Copyright (C) 2015 Superhouse Automation Pty Ltd
|
||||
BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#include "esp8266.h"
|
||||
|
||||
void gpio_interrupt_handler(void);
|
||||
void gpio_noop_interrupt_handler(void) { }
|
||||
void gpio00_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio01_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio02_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio03_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio04_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio05_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio06_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio07_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio08_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio09_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio10_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio11_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio12_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio13_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio14_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
void gpio15_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||
|
||||
typedef void (* gpio_interrupt_handler_t)(void);
|
||||
|
||||
const gpio_interrupt_handler_t gpio_interrupt_handlers[16] = {
|
||||
gpio00_interrupt_handler, gpio01_interrupt_handler, gpio02_interrupt_handler,
|
||||
gpio03_interrupt_handler, gpio04_interrupt_handler, gpio05_interrupt_handler,
|
||||
gpio06_interrupt_handler, gpio07_interrupt_handler, gpio08_interrupt_handler,
|
||||
gpio09_interrupt_handler, gpio10_interrupt_handler, gpio11_interrupt_handler,
|
||||
gpio12_interrupt_handler, gpio13_interrupt_handler, gpio14_interrupt_handler,
|
||||
gpio15_interrupt_handler };
|
||||
|
||||
void __attribute__((weak)) IRAM gpio_interrupt_handler(void)
|
||||
{
|
||||
uint32_t status_reg = GPIO.STATUS;
|
||||
GPIO.STATUS_CLEAR = status_reg;
|
||||
uint8_t gpio_idx;
|
||||
while((gpio_idx = __builtin_ffs(status_reg)))
|
||||
{
|
||||
gpio_idx--;
|
||||
status_reg &= ~BIT(gpio_idx);
|
||||
if(FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_idx]))
|
||||
gpio_interrupt_handlers[gpio_idx]();
|
||||
}
|
||||
}
|
|
@ -10,8 +10,13 @@
|
|||
#include <esp/wdev_regs.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Return a random 32-bit number */
|
||||
uint32_t hwrand(void)
|
||||
/* Return a random 32-bit number.
|
||||
*
|
||||
* This is also used as a substitute for rand() called from
|
||||
* lmac.a:sdk_lmacTxFrame to avoid touching the newlib reent structures within
|
||||
* the NMI and the NMI code needs to be in IRAM.
|
||||
*/
|
||||
uint32_t IRAM hwrand(void)
|
||||
{
|
||||
return WDEV.HWRNG;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,19 @@
|
|||
*/
|
||||
#include <esp/interrupts.h>
|
||||
|
||||
_xt_isr isr[16];
|
||||
typedef struct _xt_isr_entry_ {
|
||||
_xt_isr handler;
|
||||
void *arg;
|
||||
} _xt_isr_entry;
|
||||
|
||||
_xt_isr_entry isr[16];
|
||||
|
||||
bool esp_in_isr;
|
||||
|
||||
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
|
||||
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func, void *arg)
|
||||
{
|
||||
isr[i] = func;
|
||||
isr[i].handler = func;
|
||||
isr[i].arg = arg;
|
||||
}
|
||||
|
||||
/* Generic ISR handler.
|
||||
|
@ -25,17 +31,20 @@ uint16_t IRAM _xt_isr_handler(uint16_t intset)
|
|||
esp_in_isr = true;
|
||||
|
||||
/* WDT has highest priority (occasional WDT resets otherwise) */
|
||||
if(intset & BIT(INUM_WDT)) {
|
||||
if (intset & BIT(INUM_WDT)) {
|
||||
_xt_clear_ints(BIT(INUM_WDT));
|
||||
isr[INUM_WDT]();
|
||||
isr[INUM_WDT].handler(NULL);
|
||||
intset -= BIT(INUM_WDT);
|
||||
}
|
||||
|
||||
while(intset) {
|
||||
while (intset) {
|
||||
uint8_t index = __builtin_ffs(intset) - 1;
|
||||
uint16_t mask = BIT(index);
|
||||
_xt_clear_ints(mask);
|
||||
isr[index]();
|
||||
_xt_isr handler = isr[index].handler;
|
||||
if (handler) {
|
||||
handler(isr[index].arg);
|
||||
}
|
||||
intset -= mask;
|
||||
}
|
||||
|
||||
|
|
125
core/esp_spi.c
125
core/esp_spi.c
|
@ -27,6 +27,7 @@
|
|||
#define _SPI1_FUNC IOMUX_FUNC(2)
|
||||
|
||||
#define _SPI_BUF_SIZE 64
|
||||
#define __min(a,b) ((a > b) ? (b):(a))
|
||||
|
||||
static bool _minimal_pins[2] = {false, false};
|
||||
|
||||
|
@ -158,6 +159,22 @@ inline static void _start(uint8_t bus)
|
|||
SPI(bus).CMD |= SPI_CMD_USR;
|
||||
}
|
||||
|
||||
inline static void _store_data(uint8_t bus, const void *data, size_t len)
|
||||
{
|
||||
uint8_t words = len / 4;
|
||||
uint8_t tail = len % 4;
|
||||
|
||||
memcpy((void *)SPI(bus).W, data, len - tail);
|
||||
|
||||
if (!tail) return;
|
||||
|
||||
uint32_t last = 0;
|
||||
uint8_t *offs = (uint8_t *)data + len - tail;
|
||||
for (uint8_t i = 0; i < tail; i++)
|
||||
last = last | (offs[i] << (i * 8));
|
||||
SPI(bus).W[words] = last;
|
||||
}
|
||||
|
||||
inline static uint32_t _swap_bytes(uint32_t value)
|
||||
{
|
||||
return (value << 24) | ((value << 8) & 0x00ff0000) | ((value >> 8) & 0x0000ff00) | (value >> 24);
|
||||
|
@ -188,7 +205,7 @@ static void _spi_buf_transfer(uint8_t bus, const void *out_data, void *in_data,
|
|||
_wait(bus);
|
||||
size_t bytes = len * (uint8_t)word_size;
|
||||
_set_size(bus, bytes);
|
||||
memcpy((void *)SPI(bus).W, out_data, bytes);
|
||||
_store_data(bus, out_data, bytes);
|
||||
_spi_buf_prepare(bus, len, e, word_size);
|
||||
_start(bus);
|
||||
_wait(bus);
|
||||
|
@ -220,6 +237,39 @@ uint32_t spi_transfer_32(uint8_t bus, uint32_t data)
|
|||
return res;
|
||||
}
|
||||
|
||||
static void _rearm_extras_bit(uint8_t bus, bool arm)
|
||||
{
|
||||
if (!_minimal_pins[bus]) return;
|
||||
static uint8_t status[2];
|
||||
|
||||
if (arm)
|
||||
{
|
||||
if (status[bus] & 0x01) SPI(bus).USER0 |= (SPI_USER0_ADDR);
|
||||
if (status[bus] & 0x02) SPI(bus).USER0 |= (SPI_USER0_COMMAND);
|
||||
if (status[bus] & 0x04)
|
||||
SPI(bus).USER0 |= (SPI_USER0_DUMMY | SPI_USER0_MISO);
|
||||
status[bus] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SPI(bus).USER0 & SPI_USER0_ADDR)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_ADDR);
|
||||
status[bus] |= 0x01;
|
||||
}
|
||||
if (SPI(bus).USER0 & SPI_USER0_COMMAND)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_COMMAND);
|
||||
status[bus] |= 0x02;
|
||||
}
|
||||
if (SPI(bus).USER0 & SPI_USER0_DUMMY)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_DUMMY | SPI_USER0_MISO);
|
||||
status[bus] |= 0x04;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len, spi_word_size_t word_size)
|
||||
{
|
||||
if (!out_data || !len) return 0;
|
||||
|
@ -233,6 +283,7 @@ size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len
|
|||
size_t offset = i * _SPI_BUF_SIZE;
|
||||
_spi_buf_transfer(bus, (const uint8_t *)out_data + offset,
|
||||
in_data ? (uint8_t *)in_data + offset : NULL, buf_size, e, word_size);
|
||||
_rearm_extras_bit(bus, false);
|
||||
}
|
||||
|
||||
uint8_t tail = len % buf_size;
|
||||
|
@ -242,5 +293,77 @@ size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len
|
|||
in_data ? (uint8_t *)in_data + blocks * _SPI_BUF_SIZE : NULL, tail, e, word_size);
|
||||
}
|
||||
|
||||
if (blocks) _rearm_extras_bit(bus, true);
|
||||
return len;
|
||||
}
|
||||
|
||||
static void _spi_buf_read(uint8_t bus, uint8_t b, void *in_data,
|
||||
size_t len, spi_endianness_t e, spi_word_size_t word_size)
|
||||
{
|
||||
_wait(bus);
|
||||
size_t bytes = len * (uint8_t)word_size;
|
||||
_set_size(bus, bytes);
|
||||
uint32_t w = ((uint32_t)b << 24) | ((uint32_t)b << 16) | ((uint32_t)b << 8) | b;
|
||||
for (uint8_t i = 0; i < _SPI_BUF_SIZE / 4; i ++)
|
||||
SPI(bus).W[i] = w;
|
||||
_start(bus);
|
||||
_wait(bus);
|
||||
_spi_buf_prepare(bus, len, e, word_size);
|
||||
memcpy(in_data, (void *)SPI(bus).W, bytes);
|
||||
}
|
||||
|
||||
void spi_read(uint8_t bus, uint8_t out_byte, void *in_data, size_t len, spi_word_size_t word_size)
|
||||
{
|
||||
spi_endianness_t e = spi_get_endianness(bus);
|
||||
uint8_t buf_size = _SPI_BUF_SIZE / (uint8_t)word_size;
|
||||
|
||||
size_t blocks = len / buf_size;
|
||||
for (size_t i = 0; i < blocks; i++)
|
||||
{
|
||||
size_t offset = i * _SPI_BUF_SIZE;
|
||||
_spi_buf_read(bus, out_byte, (uint8_t *)in_data + offset, buf_size, e, word_size);
|
||||
_rearm_extras_bit(bus, false);
|
||||
}
|
||||
|
||||
uint8_t tail = len % buf_size;
|
||||
if (tail)
|
||||
_spi_buf_read(bus, out_byte, (uint8_t *)in_data + blocks * _SPI_BUF_SIZE, tail, e, word_size);
|
||||
|
||||
if (blocks) _rearm_extras_bit(bus, true);
|
||||
}
|
||||
|
||||
static void _repeat_send(uint8_t bus, uint32_t *dword, int32_t *repeats,
|
||||
spi_word_size_t size)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
while (*repeats > 0)
|
||||
{
|
||||
uint16_t bytes_to_transfer = __min(*repeats * size, _SPI_BUF_SIZE);
|
||||
_wait(bus);
|
||||
if (i) _rearm_extras_bit(bus, false);
|
||||
_set_size(bus, bytes_to_transfer);
|
||||
for (i = 0; i < (bytes_to_transfer + 3) / 4; i++)
|
||||
SPI(bus).W[i] = *dword; //need test with memcpy !
|
||||
_start(bus);
|
||||
*repeats -= (bytes_to_transfer / size);
|
||||
}
|
||||
_wait(bus);
|
||||
_rearm_extras_bit(bus, true);
|
||||
}
|
||||
|
||||
void spi_repeat_send_8(uint8_t bus, uint8_t data, int32_t repeats)
|
||||
{
|
||||
uint32_t dword = data << 24 | data << 16 | data << 8 | data;
|
||||
_repeat_send(bus, &dword, &repeats, SPI_8BIT);
|
||||
}
|
||||
|
||||
void spi_repeat_send_16(uint8_t bus, uint16_t data, int32_t repeats)
|
||||
{
|
||||
uint32_t dword = data << 16 | data;
|
||||
_repeat_send(bus, &dword, &repeats, SPI_16BIT);
|
||||
}
|
||||
|
||||
void spi_repeat_send_32(uint8_t bus, uint32_t data, int32_t repeats)
|
||||
{
|
||||
_repeat_send(bus, &data, &repeats, SPI_32BIT);
|
||||
}
|
||||
|
|
|
@ -83,6 +83,11 @@ int timer_set_frequency(const timer_frc_t frc, uint32_t freq)
|
|||
uint32_t counts = 0;
|
||||
timer_clkdiv_t div = timer_freq_to_div(freq);
|
||||
|
||||
if(freq == 0) //can't divide by 0
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
counts = timer_freq_to_count(frc, freq, div);
|
||||
if(counts == 0)
|
||||
{
|
||||
|
|
|
@ -127,21 +127,44 @@ static inline bool gpio_read(const uint8_t gpio_num)
|
|||
return GPIO.IN & BIT(gpio_num);
|
||||
}
|
||||
|
||||
extern void gpio_interrupt_handler(void);
|
||||
typedef void (* gpio_interrupt_handler_t)(uint8_t gpio_num);
|
||||
|
||||
/*
|
||||
* You can implement GPIO interrupt handlers in either of two ways:
|
||||
* - Implement handler and use it with the gpio_set_interrupt()
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* void my_intr_handler(uint8_t gpio_num) {
|
||||
* // Do something when GPIO changes
|
||||
* }
|
||||
* ...
|
||||
* gpio_set_interrupt(MY_GPIO_NUM, GPIO_INTTYPE_EDGE_ANY, my_intr_handler);
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* - Implement a single function named gpio_interrupt_handler(). This
|
||||
* will need to manually check GPIO.STATUS and clear any status
|
||||
* bits after handling interrupts. This gives you full control, but
|
||||
* you can't combine it with the first approach.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* void IRAM gpio_interrupt_handler(void *arg) {
|
||||
* // check GPIO.STATUS
|
||||
* // write GPIO.STATUS_CLEAR
|
||||
* // Do something when GPIO changes
|
||||
* }
|
||||
* ...
|
||||
* gpio_set_interrupt(MY_GPIO_NUM, GPIO_INTTYPE_EDGE_ANY, NULL);
|
||||
*/
|
||||
|
||||
/* Set the interrupt type for a given pin
|
||||
*
|
||||
* If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be
|
||||
* attached and unmasked.
|
||||
*/
|
||||
static inline void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
|
||||
{
|
||||
GPIO.CONF[gpio_num] = SET_FIELD(GPIO.CONF[gpio_num], GPIO_CONF_INTTYPE, int_type);
|
||||
if(int_type != GPIO_INTTYPE_NONE) {
|
||||
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler);
|
||||
_xt_isr_unmask(1<<INUM_GPIO);
|
||||
}
|
||||
}
|
||||
void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type, gpio_interrupt_handler_t handler);
|
||||
|
||||
/* Return the interrupt type set for a pin */
|
||||
static inline gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
|
||||
|
|
|
@ -70,7 +70,7 @@ struct GPIO_REGS {
|
|||
uint32_t volatile STATUS_SET; // 0x20
|
||||
uint32_t volatile STATUS_CLEAR; // 0x24
|
||||
uint32_t volatile CONF[16]; // 0x28 - 0x64
|
||||
uint32_t volatile PWM; // 0x68
|
||||
uint32_t volatile DSM; // 0x68
|
||||
uint32_t volatile RTC_CALIB; // 0x6c
|
||||
uint32_t volatile RTC_CALIB_RESULT; // 0x70
|
||||
};
|
||||
|
@ -117,9 +117,9 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
|||
* GPIO_CONF_OPEN_DRAIN does not appear to work on all pins.
|
||||
*
|
||||
*
|
||||
* GPIO_CONF_SOURCE_PWM (boolean)
|
||||
* When set, GPIO pin output will be connected to the sigma-delta PWM
|
||||
* generator (controlled by the GPIO.PWM register). When cleared, pin
|
||||
* GPIO_CONF_SOURCE_DSM (boolean)
|
||||
* When set, GPIO pin output will be connected to the sigma-delta
|
||||
* generator (controlled by the GPIO.DSM register). When cleared, pin
|
||||
* output will function as a normal GPIO output (controlled by the
|
||||
* GPIO.OUT* registers).
|
||||
*/
|
||||
|
@ -130,7 +130,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
|||
#define GPIO_CONF_INTTYPE_M 0x00000007
|
||||
#define GPIO_CONF_INTTYPE_S 7
|
||||
#define GPIO_CONF_OPEN_DRAIN BIT(2)
|
||||
#define GPIO_CONF_SOURCE_PWM BIT(0)
|
||||
#define GPIO_CONF_SOURCE_DSM BIT(0)
|
||||
|
||||
/* Valid values for the GPIO_CONF_INTTYPE field */
|
||||
typedef enum {
|
||||
|
@ -142,13 +142,13 @@ typedef enum {
|
|||
GPIO_INTTYPE_LEVEL_HIGH = 5,
|
||||
} gpio_inttype_t;
|
||||
|
||||
/* Details for PWM register */
|
||||
/* Details for DSM register */
|
||||
|
||||
#define GPIO_PWM_ENABLE BIT(16)
|
||||
#define GPIO_PWM_PRESCALER_M 0x000000ff
|
||||
#define GPIO_PWM_PRESCALER_S 8
|
||||
#define GPIO_PWM_TARGET_M 0x000000ff
|
||||
#define GPIO_PWM_TARGET_S 0
|
||||
#define GPIO_DSM_ENABLE BIT(16)
|
||||
#define GPIO_DSM_PRESCALER_M 0x000000ff
|
||||
#define GPIO_DSM_PRESCALER_S 8
|
||||
#define GPIO_DSM_TARGET_M 0x000000ff
|
||||
#define GPIO_DSM_TARGET_S 0
|
||||
|
||||
/* Details for RTC_CALIB register */
|
||||
|
||||
|
|
|
@ -35,19 +35,37 @@ typedef enum {
|
|||
INUM_TIMER_FRC2 = 10,
|
||||
} xt_isr_num_t;
|
||||
|
||||
void sdk__xt_int_exit (void);
|
||||
void _xt_user_exit (void);
|
||||
void sdk__xt_tick_timer_init (void);
|
||||
void sdk__xt_timer_int(void);
|
||||
void sdk__xt_int_exit(void);
|
||||
void _xt_user_exit(void);
|
||||
void sdk__xt_tick_timer_init(void);
|
||||
void sdk__xt_timer_int(void *);
|
||||
void sdk__xt_timer_int1(void);
|
||||
|
||||
/* The normal running level is 0.
|
||||
* The system tick isr, timer frc2_isr, sv_isr etc run at level 1.
|
||||
* Debug exceptions run at level 2?
|
||||
* The wdev nmi runs at level 3.
|
||||
*/
|
||||
static inline uint32_t _xt_get_intlevel(void)
|
||||
{
|
||||
uint32_t level;
|
||||
__asm__ volatile("rsr %0, intlevel" : "=a"(level));
|
||||
return level;
|
||||
__asm__ volatile("rsr %0, ps" : "=a"(level));
|
||||
return level & 0xf;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are conflicting definitions for XCHAL_EXCM_LEVEL. Newlib
|
||||
* defines it to be 1 and xtensa_rtos.h defines it to be 3. Don't want
|
||||
* 3 as that is for the NMI and might want to check that the OS apis
|
||||
* are not entered in level 3. Setting the interrupt level to 3 does
|
||||
* not disable the NMI anyway. So set the level to 2.
|
||||
*/
|
||||
|
||||
#ifdef XCHAL_EXCM_LEVEL
|
||||
#undef XCHAL_EXCM_LEVEL
|
||||
#define XCHAL_EXCM_LEVEL 2
|
||||
#endif
|
||||
|
||||
/* Disable interrupts and return the old ps value, to pass into
|
||||
_xt_restore_interrupts later.
|
||||
|
||||
|
@ -68,25 +86,27 @@ static inline void _xt_restore_interrupts(uint32_t new_ps)
|
|||
__asm__ volatile ("wsr %0, ps; rsync" :: "a" (new_ps));
|
||||
}
|
||||
|
||||
/* ESPTODO: the mask/unmask functions aren't thread safe */
|
||||
|
||||
static inline void _xt_isr_unmask(uint32_t unmask)
|
||||
static inline uint32_t _xt_isr_unmask(uint32_t unmask)
|
||||
{
|
||||
uint32_t old_level = _xt_disable_interrupts();
|
||||
uint32_t intenable;
|
||||
asm volatile ("rsr %0, intenable" : "=a" (intenable));
|
||||
intenable |= unmask;
|
||||
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
|
||||
asm volatile ("wsr %0, intenable;" :: "a" (intenable | unmask));
|
||||
_xt_restore_interrupts(old_level);
|
||||
return intenable;
|
||||
}
|
||||
|
||||
static inline void _xt_isr_mask (uint32_t mask)
|
||||
static inline uint32_t _xt_isr_mask(uint32_t mask)
|
||||
{
|
||||
uint32_t old_level = _xt_disable_interrupts();
|
||||
uint32_t intenable;
|
||||
asm volatile ("rsr %0, intenable" : "=a" (intenable));
|
||||
intenable &= ~mask;
|
||||
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
|
||||
asm volatile ("wsr %0, intenable;" :: "a" (intenable & ~mask));
|
||||
_xt_restore_interrupts(old_level);
|
||||
return intenable;
|
||||
}
|
||||
|
||||
static inline uint32_t _xt_read_ints (void)
|
||||
static inline uint32_t _xt_read_ints(void)
|
||||
{
|
||||
uint32_t interrupt;
|
||||
asm volatile ("rsr %0, interrupt" : "=a" (interrupt));
|
||||
|
@ -98,9 +118,7 @@ static inline void _xt_clear_ints(uint32_t mask)
|
|||
asm volatile ("wsr %0, intclear; esync" :: "a" (mask));
|
||||
}
|
||||
|
||||
typedef void (* _xt_isr)(void);
|
||||
/* This function is implemeneted in FreeRTOS port.c at the moment,
|
||||
should be moved or converted to an inline */
|
||||
void _xt_isr_attach (uint8_t i, _xt_isr func);
|
||||
typedef void (* _xt_isr)(void *arg);
|
||||
void _xt_isr_attach (uint8_t i, _xt_isr func, void *arg);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,15 @@
|
|||
#define SPI_FREQ_DIV_40M SPI_GET_FREQ_DIV(1, 2) ///< 40MHz
|
||||
#define SPI_FREQ_DIV_80M SPI_GET_FREQ_DIV(1, 1) ///< 80MHz
|
||||
|
||||
/*
|
||||
* Possible Data Structure of SPI Transaction
|
||||
*
|
||||
* [COMMAND]+[ADDRESS]+[DataOUT]+[DUMMYBITS]+[DataIN]
|
||||
*
|
||||
* [COMMAND]+[ADDRESS]+[DUMMYBITS]+[DataOUT]
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -265,6 +274,158 @@ uint32_t spi_transfer_32(uint8_t bus, uint32_t data);
|
|||
*/
|
||||
size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len, spi_word_size_t word_size);
|
||||
|
||||
/**
|
||||
* \brief Add permanent command bits when transfert data over SPI
|
||||
* Example:
|
||||
*
|
||||
* spi_set_command(1, 1, 0x01); // Set one command bit to 1
|
||||
* for (uint8_t i = 0; i < x; i++ ) {
|
||||
* spi_transfer_8(1, 0x55); // Send 1 bit command + 8 bits data x times
|
||||
* }
|
||||
* spi_clear_command(1); // Clear command
|
||||
* spi_transfer_8(1, 0x55); // Send 8 bits data
|
||||
*
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param bits Number of bits (max: 16).
|
||||
* \param data Command to send for each transfert.
|
||||
*/
|
||||
static inline void spi_set_command(uint8_t bus, uint8_t bits, uint16_t data)
|
||||
{
|
||||
if (!bits) return;
|
||||
|
||||
SPI(bus).USER0 |= SPI_USER0_COMMAND; //enable COMMAND function in SPI module
|
||||
uint16_t command;
|
||||
// Commands are always sent using little endian byte order
|
||||
if (!spi_get_msb(bus)) {
|
||||
// "data" are natively little endian, with LSB bit order
|
||||
// this makes all bits of the command ready to be sent as-is
|
||||
command = data;
|
||||
} else {
|
||||
// MSB
|
||||
command = data << (16 - bits); //align command data to high bits
|
||||
command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00); //swap byte order
|
||||
}
|
||||
SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_BITLEN, --bits);
|
||||
SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_VALUE, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add permanent address bits when transfert data over SPI
|
||||
* Example:
|
||||
*
|
||||
* spi_set_address(1,8,0x45); // Set one address byte to 0x45
|
||||
* for (uint8_t i = 0 ; i < x ; i++ ) {
|
||||
* spi_transfer_16(1,0xC584); // Send 16 bits address + 16 bits data x times
|
||||
* }
|
||||
* spi_clear_address(1); // Clear command
|
||||
* spi_transfer_16(1,0x55); // Send 16 bits data
|
||||
*
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param bits Number of bits (max: 32).
|
||||
* \param data Address to send for each transfert.
|
||||
*/
|
||||
static inline void spi_set_address(uint8_t bus, uint8_t bits, uint32_t data)
|
||||
{
|
||||
if (!bits) return;
|
||||
|
||||
SPI(bus).USER0 |= SPI_USER0_ADDR; //enable ADDRess function in SPI module
|
||||
// addresses are always sent using big endian byte order
|
||||
if (spi_get_msb(bus)) {
|
||||
SPI(bus).ADDR = data << (32 - bits); //align address data to high bits
|
||||
} else {
|
||||
// swap bytes from native little to command's big endian order
|
||||
// bits in each byte are already arranged properly for LSB
|
||||
SPI(bus).ADDR = (data & 0xff) << 24 | (data & 0xff00) << 8 | ((data >> 8) & 0xff00) | ((data >> 24) & 0xff);
|
||||
}
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_ADDR_BITLEN, --bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add permanent dummy bits when transfert data over SPI
|
||||
* Example:
|
||||
*
|
||||
* spi_set_dummy_bits(1, 4, false); // Set 4 dummy bit before Dout
|
||||
* for (uint8_t i = 0; i < x; i++ ) {
|
||||
* spi_transfer_16(1, 0xC584); // Send 4 bits dummy + 16 bits Dout x times
|
||||
* }
|
||||
* spi_set_dummy_bits(1, 4, true); // Set 4 dummy bit between Dout and Din
|
||||
* spi_transfer_8(1, 0x55); // Send 8 bits Dout + 4 bits dummy + 8 bits Din
|
||||
*
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param bits Number of bits
|
||||
* \param pos Position of dummy bit, between Dout and Din if true.
|
||||
*/
|
||||
static inline void spi_set_dummy_bits(uint8_t bus, uint8_t bits, bool pos)
|
||||
{
|
||||
if (!bits) return;
|
||||
if (pos)
|
||||
SPI(bus).USER0 |= SPI_USER0_MISO; // Dummy bit will be between Dout and Din data if set
|
||||
SPI(bus).USER0 |= SPI_USER0_DUMMY; //enable dummy bits
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_DUMMY_CYCLELEN, --bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear adress Bits
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
*/
|
||||
static inline void spi_clear_address(uint8_t bus)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_ADDR);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear command Bits
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
*/
|
||||
|
||||
static inline void spi_clear_command(uint8_t bus)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_COMMAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear dummy Bits
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
*/
|
||||
static inline void spi_clear_dummy(uint8_t bus)
|
||||
{
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_DUMMY | SPI_USER0_MISO);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send many 8 bits template over SPI
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param data Byte template (8 bits)
|
||||
* \param repeats Copy byte number
|
||||
*/
|
||||
void spi_repeat_send_8(uint8_t bus, uint8_t data, int32_t repeats);
|
||||
|
||||
/**
|
||||
* \brief Send many 16 bits template over SPI
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param data Word template (16 bits)
|
||||
* \param repeats Copy word number
|
||||
*/
|
||||
void spi_repeat_send_16(uint8_t bus, uint16_t data, int32_t repeats);
|
||||
|
||||
/**
|
||||
* \brief Send many 32 bits template over SPI
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param data Dualword template (32 bits)
|
||||
* \param repeats Copy dword number
|
||||
*/
|
||||
void spi_repeat_send_32(uint8_t bus, uint32_t data, int32_t repeats);
|
||||
|
||||
/**
|
||||
* \brief Repeatedly send byte over SPI and receive data
|
||||
* \param bus Bus ID: 0 - system, 1 - user
|
||||
* \param out_byte Byte to send
|
||||
* \param in_data Receive buffer
|
||||
* \param len Buffer size in words
|
||||
* \param word_size Size of the word
|
||||
*/
|
||||
void spi_read(uint8_t bus, uint8_t out_byte, void *in_data, size_t len, spi_word_size_t word_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -124,4 +124,50 @@ static inline int uart_get_baud(int uart_num)
|
|||
return APB_CLK_FREQ / FIELD2VAL(UART_CLOCK_DIVIDER_VALUE, UART(uart_num).CLOCK_DIVIDER);
|
||||
}
|
||||
|
||||
/* Set uart stop bit count to the desired value */
|
||||
static inline void uart_set_stopbits(int uart_num, UART_StopBits stop_bits) {
|
||||
UART(uart_num).CONF0 = SET_FIELD(UART(uart_num).CONF0, UART_CONF0_STOP_BITS, stop_bits);
|
||||
}
|
||||
|
||||
/* Returns the current stopbit count for the UART */
|
||||
static inline UART_StopBits uart_get_stopbits(int uart_num) {
|
||||
return (UART_StopBits)(FIELD2VAL(UART_CONF0_STOP_BITS, UART(uart_num).CONF0));
|
||||
}
|
||||
|
||||
/* Set if uart parity bit should be enabled */
|
||||
static inline void uart_set_parity_enabled(int uart_num, bool enable) {
|
||||
if(enable)
|
||||
UART(uart_num).CONF0 = SET_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY_ENABLE);
|
||||
else
|
||||
UART(uart_num).CONF0 = CLEAR_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY_ENABLE);
|
||||
}
|
||||
|
||||
/* Set uart parity bit type */
|
||||
static inline void uart_set_parity(int uart_num, UART_Parity parity) {
|
||||
if(parity == UART_PARITY_EVEN)
|
||||
UART(uart_num).CONF0 = CLEAR_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY);
|
||||
else
|
||||
UART(uart_num).CONF0 = SET_MASK_BITS(UART(uart_num).CONF0, UART_CONF0_PARITY);
|
||||
}
|
||||
|
||||
/* Returns if parity bit is currently enabled for UART uart_num */
|
||||
static inline bool uart_get_parity_enabled(int uart_num) {
|
||||
return ((UART(uart_num).CONF0 & UART_CONF0_PARITY_ENABLE) != 0);
|
||||
}
|
||||
|
||||
/* Returns the current parity bit type for UART uart_num (also if parity bit is not enabled) */
|
||||
static inline UART_Parity uart_get_parity(int uart_num) {
|
||||
return (UART_Parity)((UART(uart_num).CONF0 & UART_CONF0_PARITY) != 0);
|
||||
}
|
||||
|
||||
/* Set uart data bits length to the desired value */
|
||||
static inline void uart_set_byte_length(int uart_num, UART_ByteLength byte_length) {
|
||||
UART(uart_num).CONF0 = SET_FIELD(UART(uart_num).CONF0, UART_CONF0_BYTE_LEN, byte_length);
|
||||
}
|
||||
|
||||
/* Returns the current data bits length for the UART */
|
||||
static inline UART_ByteLength uart_get_byte_length(int uart_num) {
|
||||
return (UART_ByteLength)(FIELD2VAL(UART_CONF0_BYTE_LEN, UART(uart_num).CONF0));
|
||||
}
|
||||
|
||||
#endif /* _ESP_UART_H */
|
||||
|
|
|
@ -50,6 +50,25 @@ struct UART_REGS {
|
|||
|
||||
_Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size");
|
||||
|
||||
typedef enum {
|
||||
UART_STOPBITS_0 = 0b00,
|
||||
UART_STOPBITS_1 = 0b01,
|
||||
UART_STOPBITS_1_5 = 0b10,
|
||||
UART_STOPBITS_2 = 0b11
|
||||
} UART_StopBits;
|
||||
|
||||
typedef enum {
|
||||
UART_PARITY_EVEN = 0b0,
|
||||
UART_PARITY_ODD = 0b1
|
||||
} UART_Parity;
|
||||
|
||||
typedef enum {
|
||||
UART_BYTELENGTH_5 = 0b00,
|
||||
UART_BYTELENGTH_6 = 0b01,
|
||||
UART_BYTELENGTH_7 = 0b10,
|
||||
UART_BYTELENGTH_8 = 0b11,
|
||||
} UART_ByteLength;
|
||||
|
||||
/* Details for FIFO register */
|
||||
|
||||
#define UART_FIFO_DATA_M 0x000000ff
|
||||
|
@ -153,7 +172,7 @@ _Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size");
|
|||
#define UART_CONF0_BYTE_LEN_M 0x00000003
|
||||
#define UART_CONF0_BYTE_LEN_S 2
|
||||
#define UART_CONF0_PARITY_ENABLE BIT(1)
|
||||
#define UART_CONF0_PARITY BIT(0) //FIXME: does this indicate odd or even?
|
||||
#define UART_CONF0_PARITY BIT(0) //where 0 means even
|
||||
|
||||
/* Details for CONF1 register */
|
||||
|
||||
|
|
|
@ -36,4 +36,6 @@ typedef struct {
|
|||
uint32_t status_mask;
|
||||
} sdk_flashchip_t;
|
||||
|
||||
extern sdk_flashchip_t sdk_flashchip;
|
||||
|
||||
#endif /* _FLASHCHIP_H */
|
||||
|
|
|
@ -14,23 +14,111 @@
|
|||
// 'info' is declared in app_main.o at .bss+0x4
|
||||
|
||||
struct sdk_info_st {
|
||||
uint32_t _unknown0; // 0x00
|
||||
uint32_t _unknown4; // 0x04
|
||||
uint32_t _unknown8; // 0x08
|
||||
ip_addr_t ipaddr; // 0x0c
|
||||
ip_addr_t netmask; // 0x10
|
||||
ip_addr_t gw; // 0x14
|
||||
ip4_addr_t softap_ipaddr; // 0x00
|
||||
ip4_addr_t softap_netmask; // 0x04
|
||||
ip4_addr_t softap_gw; // 0x08
|
||||
ip4_addr_t sta_ipaddr; // 0x0c
|
||||
ip4_addr_t sta_netmask; // 0x10
|
||||
ip4_addr_t sta_gw; // 0x14
|
||||
uint8_t softap_mac_addr[6]; // 0x18
|
||||
uint8_t sta_mac_addr[6]; // 0x1e
|
||||
};
|
||||
|
||||
extern struct sdk_info_st sdk_info;
|
||||
|
||||
// 'rst_if' is declared in user_interface.o at .bss+0xfc
|
||||
extern struct sdk_rst_info sdk_rst_if;
|
||||
struct wl_channel {
|
||||
uint8_t _unknown00;
|
||||
uint8_t _unknown01;
|
||||
uint8_t _unknown02;
|
||||
uint8_t _unknown03;
|
||||
uint8_t _unknown04;
|
||||
uint8_t _unknown05;
|
||||
uint8_t num; // eagle_auth_done
|
||||
};
|
||||
|
||||
|
||||
struct _unknown_softap2 {
|
||||
uint32_t _unknown00;
|
||||
uint32_t _unknown04;
|
||||
uint32_t _unknown08;
|
||||
uint32_t _unknown0c;
|
||||
uint32_t _unknown10[8]; // block copied from sdk_g_ic.s._unknown28c
|
||||
uint32_t _unknown30;
|
||||
uint32_t _unknown34;
|
||||
uint32_t *_unknown38;
|
||||
uint8_t *_unknown3c; // string copied from sdk_g_ic.s._unknown2ac
|
||||
uint32_t _unknown40[29];
|
||||
uint32_t _unknownb4; // 300
|
||||
uint32_t _unknownb8[5];
|
||||
};
|
||||
|
||||
|
||||
struct _unknown_softap1 {
|
||||
uint32_t _unknown00;
|
||||
struct _unknown_softap2 *_unknown04;
|
||||
uint32_t _unknown08[4];
|
||||
uint32_t *_unknown18; // result of sdk_wpa_init, dynamically allocated object.
|
||||
};
|
||||
|
||||
|
||||
struct _unknown_wpa1 {
|
||||
uint32_t _unknown00; // 1, 2, 3
|
||||
uint32_t _unknown04; // 2
|
||||
uint32_t _unknown08; // 10
|
||||
uint32_t _unknown0c;
|
||||
uint32_t _unknown10;
|
||||
uint32_t _unknown14;
|
||||
uint32_t _unknown18;
|
||||
uint32_t _unknown1c;
|
||||
uint32_t _unknown20; // 10
|
||||
uint32_t _unknown24;
|
||||
uint32_t _unknown28;
|
||||
uint32_t _unknown2c;
|
||||
uint32_t _unknown30;
|
||||
uint32_t _unknown34;
|
||||
uint32_t _unknown38;
|
||||
uint32_t _unknown3c;
|
||||
uint32_t _unknown40; // 2
|
||||
uint32_t _unknown44;
|
||||
uint32_t _unknown48;
|
||||
};
|
||||
|
||||
|
||||
struct sdk_cnx_node {
|
||||
uint8_t mac_addr[6];
|
||||
uint8_t _unknown07[2];
|
||||
|
||||
uint32_t _unknown08; // eagle_auth_done
|
||||
|
||||
uint32_t _unknown0c[3];
|
||||
|
||||
int8_t _unknown18; // eagle_auth_done
|
||||
int8_t _unknown19;
|
||||
int8_t _unknown1a;
|
||||
int8_t _unknown1b;
|
||||
|
||||
uint32_t _unknown1c[23];
|
||||
|
||||
struct wl_channel *channel; // 0x78 eagle_auth_done
|
||||
|
||||
uint32_t _unknown7c[8];
|
||||
|
||||
uint16_t _unknown9c; // ieee80211_hostap. increases by one one each timer func called.
|
||||
uint16_t _unknown9e;
|
||||
|
||||
uint32_t _unknowna0[17];
|
||||
|
||||
void *_unknowne4;
|
||||
|
||||
uint8_t _unknowne8; //
|
||||
uint8_t _unknowne9; // ppInstallKey
|
||||
int8_t _unknownea;
|
||||
int8_t _unknowneb;
|
||||
|
||||
uint32_t _unknownec[7];
|
||||
|
||||
uint32_t _unknown108; // hostap_handle_timer count
|
||||
};
|
||||
|
||||
// 'g_ic' is declared in libnet80211/ieee80211.o at .bss+0x0
|
||||
// See also: http://esp8266-re.foogod.com/wiki/G_ic_(IoT_RTOS_SDK_0.9.9)
|
||||
|
||||
struct sdk_g_ic_netif_info {
|
||||
struct netif *netif; // 0x00
|
||||
|
@ -38,16 +126,22 @@ struct sdk_g_ic_netif_info {
|
|||
uint8_t _unknown20[28]; // 0x20 - 0x3c
|
||||
uint32_t _unknown3c; // 0x3c (referenced by sdk_wifi_station_disconnect)
|
||||
uint8_t _unknown40[6]; // 0x40 - 0x46
|
||||
uint8_t _unknown46[66]; // 0x46 - 0x88
|
||||
struct sdk_netif_conninfo *_unknown88; // 0x88
|
||||
uint8_t _unknown46[2]; // 0x46 - 0x47
|
||||
uint32_t _unknown48; // 0x48
|
||||
uint8_t _unknown4c; // 0x4c
|
||||
uint8_t _unknown4d[59]; // 0x4d - 0x88
|
||||
struct sdk_cnx_node *_unknown88; // 0x88
|
||||
uint32_t _unknown8c; // 0x8c
|
||||
struct sdk_netif_conninfo *conninfo[6]; // 0x90 - 0xa8
|
||||
uint8_t _unknowna8[16]; // 0xa8 - 0xb8
|
||||
uint8_t _unknownb8; // 0xb8 (referenced by sdk_wifi_station_connect / sdk_wifi_station_disconnect)
|
||||
uint8_t _unknownb9; // 0xb9 (referenced by sdk_wifi_station_connect / sdk_wifi_station_disconnect)
|
||||
uint8_t connect_status; // 0xba (referenced by sdk_system_station_got_ip_set / sdk_wifi_station_disconnect)
|
||||
struct sdk_cnx_node *cnx_nodes[6]; // 0x90 - 0xa8
|
||||
uint8_t _unknowna8[12]; // 0xa8 - 0xb4
|
||||
struct _unknown_softap1 *_unknownb4;
|
||||
uint8_t statusb8; // 0xb8 (arg of sta_status_set)
|
||||
uint8_t statusb9; // 0xb9 (compared to arg of sta_status_set)
|
||||
uint8_t connect_status; // 0xba (result of wifi_station_get_connect_status)
|
||||
uint8_t started; // 0xbb (referenced by sdk_wifi_station_start / sdk_wifi_station_stop)
|
||||
};
|
||||
|
||||
|
||||
// This is the portion of g_ic which is not loaded/saved to the flash ROM, and
|
||||
// starts out zeroed on every boot.
|
||||
struct sdk_g_ic_volatile_st {
|
||||
|
@ -73,9 +167,11 @@ struct sdk_g_ic_volatile_st {
|
|||
uint8_t _unknown7e;
|
||||
uint8_t _unknown7f;
|
||||
|
||||
uint8_t _unknown80[204];
|
||||
uint32_t _unknown80;
|
||||
|
||||
void *_unknown14c;
|
||||
uint32_t _unknown84[50]; // wifi_softap_start, channels.
|
||||
|
||||
void * volatile _unknown14c; // wifi_softap_start, current channel, arg to ieee80211_chan2ieee
|
||||
|
||||
uint8_t _unknown150[20];
|
||||
|
||||
|
@ -92,8 +188,7 @@ struct sdk_g_ic_volatile_st {
|
|||
void *_unknown184;
|
||||
struct station_info *station_info_head;
|
||||
struct station_info *station_info_tail;
|
||||
uint32_t _unknown190;
|
||||
uint32_t _unknown194;
|
||||
void *_unknown190[2]; // cnx_sta_leave
|
||||
|
||||
uint8_t _unknown198[40];
|
||||
|
||||
|
@ -112,9 +207,10 @@ struct sdk_g_ic_volatile_st {
|
|||
uint8_t _unknown1d5[3];
|
||||
};
|
||||
|
||||
struct sdk_g_ic_unk0_st {
|
||||
uint32_t _unknown1e4;
|
||||
uint8_t _unknown1e8[32];
|
||||
|
||||
struct sdk_g_ic_ssid_with_length {
|
||||
uint32_t ssid_length; // 0x1e4 sdk_wpa_config_profile
|
||||
uint8_t ssid[32]; // 0x1e8 Station ssid. Null terminated string.
|
||||
};
|
||||
|
||||
// This is the portion of g_ic which is loaded/saved to the flash ROM, and thus
|
||||
|
@ -127,40 +223,46 @@ struct sdk_g_ic_saved_st {
|
|||
uint8_t wifi_mode;
|
||||
uint8_t wifi_led_enable;
|
||||
uint8_t wifi_led_gpio;
|
||||
uint8_t _unknown1e3;
|
||||
uint8_t wifi_led_state; // 0 or 1.
|
||||
|
||||
struct sdk_g_ic_unk0_st _unknown1e4;
|
||||
// Current station ap config ssid and length.
|
||||
struct sdk_g_ic_ssid_with_length sta_ssid; // 0x1e4
|
||||
|
||||
uint8_t _unknown208;
|
||||
uint8_t _unknown209;
|
||||
uint8_t _unknown20a;
|
||||
uint8_t _unknown209; // sdk_wpa_config_profile
|
||||
uint8_t _unknown20a; // sdk_wpa_config_profile
|
||||
uint8_t _unknown20b;
|
||||
uint8_t _unknown20c;
|
||||
uint8_t _unknown20c; // sdk_wpa_config_profile
|
||||
uint8_t _unknown20d;
|
||||
uint8_t _unknown20e;
|
||||
uint8_t _unknown20f[64];
|
||||
uint8_t sta_password[64]; // 0x20f Null terminated string.
|
||||
uint8_t _unknown24f;
|
||||
|
||||
uint8_t _unknown250[49];
|
||||
|
||||
uint8_t _unknown281;
|
||||
uint8_t sta_bssid_set; // 0x281 One if bssid is used, otherwise zero.
|
||||
|
||||
uint8_t _unknown282[6];
|
||||
uint8_t sta_bssid[6]; // 0x282
|
||||
|
||||
uint32_t _unknown288;
|
||||
uint16_t _unknown288;
|
||||
uint16_t _unknown28a;
|
||||
uint8_t _unknown28c;
|
||||
|
||||
uint8_t _unknown28d[31];
|
||||
uint8_t _unknown28d[21];
|
||||
|
||||
uint8_t _unknown2ac[64];
|
||||
uint8_t _unknown2a0; // used in dhcp_bind_check wpa_main.o
|
||||
|
||||
uint8_t _unknown2a1[9];
|
||||
|
||||
char _unknown2ac[64]; // string.
|
||||
uint8_t _unknonwn2ec;
|
||||
|
||||
uint8_t _unknown2ed[32];
|
||||
|
||||
uint8_t _unknown30d;
|
||||
uint8_t _unknown30d; // result of ieee80211_chan2ieee
|
||||
uint8_t _unknown30e;
|
||||
uint8_t _unknown30f;
|
||||
uint8_t _unknown310;
|
||||
uint8_t _unknown310; // count of entries in the softap cnx_node array, less two.
|
||||
|
||||
uint8_t _unknown311[3];
|
||||
|
||||
|
@ -194,7 +296,20 @@ struct sdk_g_ic_st {
|
|||
struct sdk_g_ic_saved_st s; // 0x1d8 - 0x548
|
||||
};
|
||||
|
||||
extern struct sdk_g_ic_st sdk_g_ic;
|
||||
|
||||
|
||||
struct esf_buf {
|
||||
struct pbuf *pbuf1; // 0x00
|
||||
struct pbuf *pbuf2; // 0x04
|
||||
uint32_t *_unknown8_; // 0x08
|
||||
uint32_t *_unknownc_; // 0x0c
|
||||
uint8_t *frame; // 0x10 IEEE-802.11 payload data?
|
||||
uint16_t _unknown14_; // 0x14
|
||||
uint16_t length; // 0x16
|
||||
uint32_t *_unknown18_; // 0x18
|
||||
struct esf_buf *next; // 0x1c Free list.
|
||||
void *extra; // 0x20
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The above structures all refer to data regions outside our control, and a
|
||||
|
@ -205,35 +320,60 @@ extern struct sdk_g_ic_st sdk_g_ic;
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
_Static_assert(sizeof(struct sdk_info_st) == 0x24, "info_st is the wrong size!");
|
||||
_Static_assert(offsetof(struct sdk_info_st, sta_mac_addr) == 0x1e, "bad struct");
|
||||
|
||||
_Static_assert(offsetof(struct wl_channel, num) == 0x06, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct _unknown_softap2) == 0xcc, "_unknown_softap2 is the wrong size!");
|
||||
_Static_assert(offsetof(struct _unknown_softap2, _unknownb8) == 0xb8, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct _unknown_softap1) == 0x1c, "_unknown_softap1 is the wrong size!");
|
||||
_Static_assert(offsetof(struct _unknown_softap1, _unknown18) == 0x18, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct _unknown_wpa1) == 0x4c, "_unknown_wpa1 is the wrong size!");
|
||||
_Static_assert(offsetof(struct _unknown_wpa1, _unknown48) == 0x48, "bad struct");
|
||||
|
||||
_Static_assert(offsetof(struct sdk_cnx_node, channel) == 0x78, "bad struct");
|
||||
_Static_assert(offsetof(struct sdk_cnx_node, _unknown108) == 0x108, "bad struct");
|
||||
|
||||
_Static_assert(offsetof(struct sdk_g_ic_netif_info, started) == 0xbb, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct sdk_g_ic_volatile_st) == 0x1d8, "sdk_g_ic_volatile_st is the wrong size!");
|
||||
_Static_assert(offsetof(struct sdk_g_ic_volatile_st, _unknown1d5) == 0x1d5, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct sdk_g_ic_saved_st) == 0x370, "sdk_g_ic_saved_st is the wrong size!");
|
||||
_Static_assert(offsetof(struct sdk_g_ic_saved_st, sta_ssid) == 0x1e4 - 0x1d8, "bad struct");
|
||||
_Static_assert(offsetof(struct sdk_g_ic_saved_st, _unknown546) == 0x546 - 0x1d8, "bad struct");
|
||||
|
||||
_Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Function Prototypes //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
_Static_assert(sizeof(struct esf_buf) == 0x24, "struct esf_buf: wrong size");
|
||||
_Static_assert(offsetof(struct esf_buf, extra) == 0x20, "bad struct");
|
||||
_Static_assert(offsetof(struct esf_buf, length) == 0x16, "bad struct");
|
||||
|
||||
sdk_SpiFlashOpResult sdk_SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
|
||||
sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
|
||||
void sdk_cnx_attach(struct sdk_g_ic_st *);
|
||||
void sdk_ets_timer_init(void);
|
||||
void sdk_ieee80211_ifattach(struct sdk_g_ic_st *, uint8_t *);
|
||||
void sdk_ieee80211_phy_init(enum sdk_phy_mode);
|
||||
void sdk_lmacInit(void);
|
||||
void sdk_phy_disable_agc(void);
|
||||
void sdk_phy_enable_agc(void);
|
||||
void sdk_pm_attach(void);
|
||||
void sdk_pp_attach(void);
|
||||
void sdk_pp_soft_wdt_init(void);
|
||||
int sdk_register_chipv6_phy(sdk_phy_info_t *);
|
||||
void sdk_sleep_reset_analog_rtcreg_8266(void);
|
||||
uint32_t sdk_system_get_checksum(uint8_t *, uint32_t);
|
||||
void sdk_wDevEnableRx(void);
|
||||
void sdk_wDev_Initialize(void);
|
||||
void sdk_wifi_mode_set(uint8_t);
|
||||
void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *);
|
||||
void sdk_wifi_softap_set_default_ssid(void);
|
||||
void sdk_wifi_softap_start(void);
|
||||
void sdk_wifi_station_start(void);
|
||||
// The SDK access some slots in lwip structures.
|
||||
|
||||
// The netif->state is initialized in netif_add within lwip with a struct
|
||||
// sdk_g_ic_netif_info, see sdk_wifi_station_start and sdk_wifi_softap_start.
|
||||
// There is a known sdk read of the netif->state in ieee80211_output.o
|
||||
// ieee80211_output_pbuf and perhaps elsewhere. The value is just passed through
|
||||
// lwip and and not used by lwip so just ensure this slot is at the expected
|
||||
// offset.
|
||||
_Static_assert(offsetof(struct netif, state) == 4, "netif->state offset wrong!");
|
||||
|
||||
// Some sdk uses of netif->hwaddr have been converted to source code, but many
|
||||
// remain, but the content of this slot should not change in future versions of
|
||||
// lwip, so just ensure it is at the expected offset. Note the sdk binary
|
||||
// libraries have been patched to move this offset from 41 to 42 to keep it
|
||||
// 16-bit aligned to keep lwip v2 happy.
|
||||
_Static_assert(offsetof(struct netif, hwaddr) == 8, "netif->hwaddr offset wrong!");
|
||||
|
||||
_Static_assert(offsetof(struct pbuf, esf_buf) == 16, "pbuf->esf_buf offset wrong!");
|
||||
|
||||
|
||||
/// Misc.
|
||||
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
void ethernetif_input(struct netif *netif, struct pbuf *p);
|
||||
|
||||
#endif /* _INTERNAL_SDK_STRUCTURES_H */
|
||||
|
|
|
@ -21,14 +21,14 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __ESP_SPIFFS_FLASH_H__
|
||||
#define __ESP_SPIFFS_FLASH_H__
|
||||
#ifndef __SPIFLASH_H__
|
||||
#define __SPIFLASH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "common_macros.h"
|
||||
|
||||
#define ESP_SPIFFS_FLASH_OK 0
|
||||
#define ESP_SPIFFS_FLASH_ERROR 1
|
||||
#define SPI_FLASH_SECTOR_SIZE 4096
|
||||
|
||||
/**
|
||||
* Read data from SPI flash.
|
||||
|
@ -37,9 +37,9 @@
|
|||
* @param buf Buffer to read to. Doesn't have to be aligned.
|
||||
* @param size Size of data to read. Buffer size must be >= than data size.
|
||||
*
|
||||
* @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR
|
||||
* @return true if success, otherwise false
|
||||
*/
|
||||
uint32_t IRAM esp_spiffs_flash_read(uint32_t addr, uint8_t *buf, uint32_t size);
|
||||
bool IRAM spiflash_read(uint32_t addr, uint8_t *buf, uint32_t size);
|
||||
|
||||
/**
|
||||
* Write data to SPI flash.
|
||||
|
@ -48,17 +48,17 @@ uint32_t IRAM esp_spiffs_flash_read(uint32_t addr, uint8_t *buf, uint32_t size);
|
|||
* @param buf Buffer of data to write to flash. Doesn't have to be aligned.
|
||||
* @param size Size of data to write. Buffer size must be >= than data size.
|
||||
*
|
||||
* @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR
|
||||
* @return true if success, otherwise false
|
||||
*/
|
||||
uint32_t IRAM esp_spiffs_flash_write(uint32_t addr, uint8_t *buf, uint32_t size);
|
||||
bool IRAM spiflash_write(uint32_t addr, uint8_t *buf, uint32_t size);
|
||||
|
||||
/**
|
||||
* Erase a sector.
|
||||
*
|
||||
* @param addr Address of sector to erase. Must be sector aligned.
|
||||
*
|
||||
* @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR
|
||||
* @return true if success, otherwise false
|
||||
*/
|
||||
uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr);
|
||||
bool IRAM spiflash_erase_sector(uint32_t addr);
|
||||
|
||||
#endif // __ESP_SPIFFS_FLASH_H__
|
||||
#endif // __SPIFLASH_H__
|
45
core/include/stdout_redirect.h
Normal file
45
core/include/stdout_redirect.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2016 Oto Petrik <oto.petrik@gmail.com>
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
|
||||
#ifndef _STDOUT_REDIRECT_H_
|
||||
#define _STDOUT_REDIRECT_H_
|
||||
|
||||
#include <sys/reent.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef ssize_t _WriteFunction(struct _reent *r, int fd, const void *ptr, size_t len);
|
||||
|
||||
/** Set implementation of write syscall for stdout.
|
||||
*
|
||||
* Use this function to redirect stdout for further processing (save to file, send over network).
|
||||
* It may be good idea to save result of `get_write_stdout()` beforehand and call
|
||||
* it at the end of the supplied function.
|
||||
*
|
||||
* NOTE: use NULL to reset to default implementation.
|
||||
*
|
||||
* @param[in] f New code to handle stdout output
|
||||
*
|
||||
*/
|
||||
void set_write_stdout(_WriteFunction *f);
|
||||
|
||||
/** Get current implementation of write syscall for stdout.
|
||||
*
|
||||
* Save returned value before calling `set_write_stdout`, it allows for chaining
|
||||
* multiple independent handlers.
|
||||
*
|
||||
* @returns current stdout handler
|
||||
*/
|
||||
_WriteFunction *get_write_stdout();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STDOUT_REDIRECT_H_ */
|
|
@ -138,6 +138,17 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, uint16_t num_sectors,
|
|||
*/
|
||||
sysparam_status_t sysparam_get_info(uint32_t *base_addr, uint32_t *num_sectors);
|
||||
|
||||
/** Compact the sysparam area.
|
||||
*
|
||||
* This also flattens the log.
|
||||
*
|
||||
* @retval ::SYSPARAM_OK Completed successfully
|
||||
* @retval ::SYSPARAM_ERR_NOINIT No current sysparam area is active
|
||||
* @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data
|
||||
* @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash
|
||||
*/
|
||||
sysparam_status_t sysparam_compact();
|
||||
|
||||
/** Get the value associated with a key
|
||||
*
|
||||
* This is the core "get value" function. It will retrieve the value for the
|
||||
|
@ -169,24 +180,20 @@ sysparam_status_t sysparam_get_info(uint32_t *base_addr, uint32_t *num_sectors);
|
|||
*/
|
||||
sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary);
|
||||
|
||||
/** Get the value associated with a key (static buffers only)
|
||||
/** Get the value associated with a key (static value buffer)
|
||||
*
|
||||
* This performs the same function as sysparam_get_data() but without
|
||||
* performing any memory allocations. It can thus be used before the heap has
|
||||
* been configured or in other cases where using the heap would be a problem
|
||||
* (i.e. in an OOM handler, etc). It requires that the caller pass in a
|
||||
* suitably sized buffer for the value to be read (if the supplied buffer is
|
||||
* not large enough, the returned value will be truncated and the full
|
||||
* required length will be returned in `actual_length`).
|
||||
*
|
||||
* NOTE: In addition to being large enough for the value, the supplied buffer
|
||||
* must also be at least as large as the length of the key being requested.
|
||||
* If it is not, an error will be returned.
|
||||
* allocating memory for the result value. It can thus be used before the heap
|
||||
* has been configured or in other cases where using the heap would be a
|
||||
* problem (i.e. in an OOM handler, etc). It requires that the caller pass in
|
||||
* a suitably sized buffer for the value to be read (if the supplied buffer is
|
||||
* not large enough, the returned value will be truncated and the full required
|
||||
* length will be returned in `actual_length`).
|
||||
*
|
||||
* @param[in] key Key name (zero-terminated string)
|
||||
* @param[in] buffer Pointer to a buffer to hold the returned value
|
||||
* @param[in] buffer_size Length of the supplied buffer in bytes
|
||||
* @param[out] actual_length pointer to a location to hold the actual length
|
||||
* @param[in] dest Pointer to a buffer to hold the returned value.
|
||||
* @param[in] dest_size Length of the supplied buffer in bytes.
|
||||
* @param[out] actual_length Pointer to a location to hold the actual length
|
||||
* of the data which was associated with the key
|
||||
* (may be NULL).
|
||||
* @param[out] is_binary Pointer to a bool to hold whether the returned
|
||||
|
@ -199,7 +206,7 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *
|
|||
* @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data
|
||||
* @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash
|
||||
*/
|
||||
sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, size_t buffer_size, size_t *actual_length, bool *is_binary);
|
||||
sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary);
|
||||
|
||||
/** Get the string value associated with a key
|
||||
*
|
||||
|
@ -231,7 +238,8 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr);
|
|||
/** Get the int32_t value associated with a key
|
||||
*
|
||||
* This routine can be used if you know that the value in a key will (or at
|
||||
* least should) be an int32_t value.
|
||||
* least should) be an int32_t value. This is done without allocating any
|
||||
* memory.
|
||||
*
|
||||
* Note: If the status result is anything other than ::SYSPARAM_OK, the value
|
||||
* in `result` is not changed. This means it is possible to set a default
|
||||
|
@ -255,7 +263,8 @@ sysparam_status_t sysparam_get_int32(const char *key, int32_t *result);
|
|||
/** Get the int8_t value associated with a key
|
||||
*
|
||||
* This routine can be used if you know that the value in a key will (or at
|
||||
* least should) be a uint8_t binary value.
|
||||
* least should) be a uint8_t binary value. This is done without allocating any
|
||||
* memory.
|
||||
*
|
||||
* Note: If the status result is anything other than ::SYSPARAM_OK, the value
|
||||
* in `result` is not changed. This means it is possible to set a default
|
||||
|
@ -309,7 +318,7 @@ sysparam_status_t sysparam_get_bool(const char *key, bool *result);
|
|||
*
|
||||
* The supplied value can be any data, up to 255 bytes in length. If `value`
|
||||
* is NULL or `value_len` is 0, this is treated as a request to delete any
|
||||
* current entry matching `key`.
|
||||
* current entry matching `key`. This is done without allocating any memory.
|
||||
*
|
||||
* If `binary` is true, the data will be considered binary (unprintable) data,
|
||||
* and this will be annotated in the saved entry. This does not affect the
|
||||
|
@ -357,7 +366,8 @@ sysparam_status_t sysparam_set_string(const char *key, const char *value);
|
|||
/** Set a key's value as a number
|
||||
*
|
||||
* Write an int32_t binary value to the specified key. This does the inverse of
|
||||
* the sysparam_get_int32() function.
|
||||
* the sysparam_get_int32() function. This is done without allocating any
|
||||
* memory.
|
||||
*
|
||||
* @param[in] key Key name (zero-terminated string)
|
||||
* @param[in] value Value to set
|
||||
|
@ -375,10 +385,8 @@ sysparam_status_t sysparam_set_int32(const char *key, int32_t value);
|
|||
/** Set a key's value as a number
|
||||
*
|
||||
* Write an int8_t binary value to the specified key. This does the inverse of
|
||||
* the sysparam_get_int8() function.
|
||||
*
|
||||
* Note that if the key already contains a value which parses to the same
|
||||
* boolean (true/false) value, it is left unchanged.
|
||||
* the sysparam_get_int8() function. This is done without allocating any
|
||||
* memory.
|
||||
*
|
||||
* @param[in] key Key name (zero-terminated string)
|
||||
* @param[in] value Value to set
|
||||
|
|
9
core/include/user_exception.h
Normal file
9
core/include/user_exception.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* Allows the user to set their own exception handler. */
|
||||
|
||||
#ifndef _USER_EXCEPTION_H
|
||||
#define _USER_EXCEPTION_H
|
||||
|
||||
void set_user_exception_handler(void (*fn)(void));
|
||||
|
||||
#endif
|
||||
|
|
@ -12,10 +12,31 @@
|
|||
#include <xtensa_ops.h>
|
||||
#include <esp/uart.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdout_redirect.h>
|
||||
#include <sys/time.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <sys/lock.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
#include <esp/hwrand.h>
|
||||
|
||||
/*
|
||||
* The file descriptor index space is allocated in blocks. The first block of 3
|
||||
* is for newlib I/O the stdin stdout and stderr. The next block of
|
||||
* MEMP_NUM_NETCONN is allocated for lwip sockets, and the remainer to file
|
||||
* system descriptors. The newlib default FD_SETSIZE is 64.
|
||||
*/
|
||||
#if LWIP_SOCKET_OFFSET < 3
|
||||
#error Expecting a LWIP_SOCKET_OFFSET >= 3, to allow room for the standard I/O descriptors.
|
||||
#endif
|
||||
#define FILE_DESCRIPTOR_OFFSET (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
|
||||
#if FILE_DESCRIPTOR_OFFSET > FD_SETSIZE
|
||||
#error Too many lwip sockets for the FD_SETSIZE.
|
||||
#endif
|
||||
|
||||
extern void *xPortSupervisorStackPointer;
|
||||
|
||||
IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
|
||||
IRAM void *_sbrk_r (struct _reent *r, ptrdiff_t incr)
|
||||
{
|
||||
extern char _heap_start; /* linker script defined */
|
||||
static char * heap_end;
|
||||
|
@ -40,44 +61,118 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
|
|||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
|
||||
/* Insert a disjoint region into the nano malloc pool. Create a malloc chunk,
|
||||
* filling the size as newlib nano malloc expects, and then free it. */
|
||||
void nano_malloc_insert_chunk(void *start, size_t size) {
|
||||
*(uint32_t *)start = size;
|
||||
free(start + sizeof(size_t));
|
||||
}
|
||||
|
||||
/* syscall implementation for stdio write to UART */
|
||||
__attribute__((weak)) long _write_r(struct _reent *r, int fd, const char *ptr, int len )
|
||||
__attribute__((weak)) ssize_t _write_stdout_r(struct _reent *r, int fd, const void *ptr, size_t len )
|
||||
{
|
||||
if(fd != r->_stdout->_file) {
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
for(int i = 0; i < len; i++) {
|
||||
/* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */
|
||||
if(ptr[i] == '\r')
|
||||
if(((char *)ptr)[i] == '\r')
|
||||
continue;
|
||||
if(ptr[i] == '\n')
|
||||
if(((char *)ptr)[i] == '\n')
|
||||
uart_putc(0, '\r');
|
||||
uart_putc(0, ptr[i]);
|
||||
uart_putc(0, ((char *)ptr)[i]);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static _WriteFunction *current_stdout_write_r = &_write_stdout_r;
|
||||
|
||||
void set_write_stdout(_WriteFunction *f)
|
||||
{
|
||||
if (f != NULL) {
|
||||
current_stdout_write_r = f;
|
||||
} else {
|
||||
current_stdout_write_r = &_write_stdout_r;
|
||||
}
|
||||
}
|
||||
|
||||
_WriteFunction *get_write_stdout()
|
||||
{
|
||||
return current_stdout_write_r;
|
||||
}
|
||||
|
||||
/* default implementation, replace in a filesystem */
|
||||
__attribute__((weak)) ssize_t _write_filesystem_r(struct _reent *r, int fd, const void *ptr, size_t len)
|
||||
{
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
__attribute__((weak)) ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len)
|
||||
{
|
||||
if (fd >= FILE_DESCRIPTOR_OFFSET) {
|
||||
return _write_filesystem_r(r, fd, ptr, len);
|
||||
}
|
||||
if (fd >= LWIP_SOCKET_OFFSET) {
|
||||
return lwip_write(fd, ptr, len);
|
||||
}
|
||||
if (fd == r->_stdout->_file) {
|
||||
return current_stdout_write_r(r, fd, ptr, len);
|
||||
}
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* syscall implementation for stdio read from UART */
|
||||
__attribute__((weak)) long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len)
|
||||
__attribute__((weak)) ssize_t _read_stdin_r(struct _reent *r, int fd, void *ptr, size_t len)
|
||||
{
|
||||
int ch, i;
|
||||
uart_rxfifo_wait(0, 1);
|
||||
for(i = 0; i < len; i++) {
|
||||
ch = uart_getc_nowait(0);
|
||||
if (ch < 0) break;
|
||||
ptr[i] = ch;
|
||||
((char *)ptr)[i] = ch;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
__attribute__((weak)) long _read_r( struct _reent *r, int fd, char *ptr, int len )
|
||||
/* default implementation, replace in a filesystem */
|
||||
__attribute__((weak)) ssize_t _read_filesystem_r( struct _reent *r, int fd, void *ptr, size_t len )
|
||||
{
|
||||
if(fd != r->_stdin->_file) {
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
__attribute__((weak)) ssize_t _read_r( struct _reent *r, int fd, void *ptr, size_t len )
|
||||
{
|
||||
if (fd >= FILE_DESCRIPTOR_OFFSET) {
|
||||
return _read_filesystem_r(r, fd, ptr, len);
|
||||
}
|
||||
if (fd >= LWIP_SOCKET_OFFSET) {
|
||||
return lwip_read(fd, ptr, len);
|
||||
}
|
||||
if (fd == r->_stdin->_file) {
|
||||
return _read_stdin_r(r, fd, ptr, len);
|
||||
}
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* default implementation, replace in a filesystem */
|
||||
__attribute__((weak)) int _close_filesystem_r(struct _reent *r, int fd)
|
||||
{
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _close_r(struct _reent *r, int fd)
|
||||
{
|
||||
if (fd >= FILE_DESCRIPTOR_OFFSET) {
|
||||
return _close_filesystem_r(r, fd);
|
||||
}
|
||||
if (fd >= LWIP_SOCKET_OFFSET) {
|
||||
return lwip_close(fd);
|
||||
}
|
||||
r->_errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Stub syscall implementations follow, to allow compiling newlib functions that
|
||||
|
@ -86,21 +181,26 @@ __attribute__((weak)) long _read_r( struct _reent *r, int fd, char *ptr, int len
|
|||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
int _open_r(struct _reent *r, const char *pathname, int flags, int mode);
|
||||
|
||||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
int _close_r(struct _reent *r, int fd);
|
||||
|
||||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
int _unlink_r(struct _reent *r, const char *path);
|
||||
|
||||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
int _fstat_r(struct _reent *r, int fd, void *buf);
|
||||
int _fstat_r(struct _reent *r, int fd, struct stat *buf);
|
||||
|
||||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
int _stat_r(struct _reent *r, const char *pathname, void *buf);
|
||||
int _stat_r(struct _reent *r, const char *pathname, struct stat *buf);
|
||||
|
||||
__attribute__((weak, alias("syscall_returns_enosys")))
|
||||
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence);
|
||||
|
||||
__attribute__((weak, alias("_gettimeofday_r")))
|
||||
int _gettimeofday_r (struct _reent *ptr, struct timeval *ptimeval, void *ptimezone) {
|
||||
ptimeval->tv_sec = 0;
|
||||
ptimeval->tv_usec = 0;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Generic stub for any newlib syscall that fails with errno ENOSYS
|
||||
("Function not implemented") and a return value equivalent to
|
||||
(int)-1. */
|
||||
|
@ -109,3 +209,125 @@ static int syscall_returns_enosys(struct _reent *r)
|
|||
r->_errno=ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getentropy(void *ptr, size_t n)
|
||||
{
|
||||
hwrand_fill(ptr, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _arc4random_getentropy_fail(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Newlib lock implementation. Some newlib locks are statically allocated, but
|
||||
* can not be statically initialized so are set to NULL and initialized at
|
||||
* startup. The malloc lock is used before it can be initialized so there are
|
||||
* runtime checks on the functions that use it early.
|
||||
*/
|
||||
static int locks_initialized = 0;
|
||||
|
||||
extern _lock_t __arc4random_mutex;
|
||||
extern _lock_t __at_quick_exit_mutex;
|
||||
//extern _lock_t __dd_hash_mutex;
|
||||
extern _lock_t __tz_mutex;
|
||||
|
||||
extern _lock_t __atexit_recursive_mutex;
|
||||
extern _lock_t __env_recursive_mutex;
|
||||
extern _lock_t __malloc_recursive_mutex;
|
||||
extern _lock_t __sfp_recursive_mutex;
|
||||
extern _lock_t __sinit_recursive_mutex;
|
||||
|
||||
void init_newlib_locks()
|
||||
{
|
||||
#if 0
|
||||
/* Used a separate mutex for each lock.
|
||||
* Each mutex uses about 96 bytes which adds up. */
|
||||
_lock_init(&__arc4random_mutex);
|
||||
_lock_init(&__at_quick_exit_mutex);
|
||||
//_lock_init(&__dd_hash_mutex);
|
||||
_lock_init(&__tz_mutex);
|
||||
|
||||
_lock_init_recursive(&__atexit_recursive_mutex);
|
||||
_lock_init_recursive(&__env_recursive_mutex);
|
||||
_lock_init_recursive(&__malloc_recursive_mutex);
|
||||
_lock_init_recursive(&__sfp_recursive_mutex);
|
||||
_lock_init_recursive(&__sinit_recursive_mutex);
|
||||
#else
|
||||
/* Reuse one mutex and one recursive mutex for this set, reducing memory
|
||||
* usage. Newlib will still allocate other locks dynamically and some of
|
||||
* those need to be separate such as the file lock where a thread might
|
||||
* block with them held. */
|
||||
_lock_init(&__arc4random_mutex);
|
||||
__at_quick_exit_mutex = __arc4random_mutex;
|
||||
//__dd_hash_mutex = __arc4random_mutex;
|
||||
__tz_mutex = __arc4random_mutex;
|
||||
|
||||
_lock_init_recursive(&__atexit_recursive_mutex);
|
||||
__env_recursive_mutex = __atexit_recursive_mutex;
|
||||
__malloc_recursive_mutex = __atexit_recursive_mutex;
|
||||
__sfp_recursive_mutex = __atexit_recursive_mutex;
|
||||
__sinit_recursive_mutex = __atexit_recursive_mutex;
|
||||
#endif
|
||||
|
||||
locks_initialized = 1;
|
||||
}
|
||||
|
||||
void _lock_init(_lock_t *lock) {
|
||||
*lock = (_lock_t)xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
void _lock_init_recursive(_lock_t *lock) {
|
||||
*lock = (_lock_t)xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
|
||||
void _lock_close(_lock_t *lock) {
|
||||
vSemaphoreDelete((QueueHandle_t)*lock);
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
void _lock_close_recursive(_lock_t *lock) {
|
||||
vSemaphoreDelete((QueueHandle_t)*lock);
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
void _lock_acquire(_lock_t *lock) {
|
||||
xSemaphoreTake((QueueHandle_t)*lock, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void _lock_acquire_recursive(_lock_t *lock) {
|
||||
if (locks_initialized) {
|
||||
if (sdk_NMIIrqIsOn) {
|
||||
uart_putc(0, ':');
|
||||
return;
|
||||
}
|
||||
xSemaphoreTakeRecursive((QueueHandle_t)*lock, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
int _lock_try_acquire(_lock_t *lock) {
|
||||
return xSemaphoreTake((QueueHandle_t)*lock, 0);
|
||||
}
|
||||
|
||||
int _lock_try_acquire_recursive(_lock_t *lock) {
|
||||
return xSemaphoreTakeRecursive((QueueHandle_t)*lock, 0);
|
||||
}
|
||||
|
||||
void _lock_release(_lock_t *lock) {
|
||||
xSemaphoreGive((QueueHandle_t)*lock);
|
||||
}
|
||||
|
||||
void _lock_release_recursive(_lock_t *lock) {
|
||||
if (locks_initialized) {
|
||||
if (sdk_NMIIrqIsOn) {
|
||||
return;
|
||||
}
|
||||
xSemaphoreGiveRecursive((QueueHandle_t)*lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "esp_spiffs_flash.h"
|
||||
#include "flashchip.h"
|
||||
#include "espressif/spi_flash.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "esp/rom.h"
|
||||
#include "esp/spi_regs.h"
|
||||
#include "include/spiflash.h"
|
||||
|
||||
#include "include/flashchip.h"
|
||||
#include "include/esp/rom.h"
|
||||
#include "include/esp/spi_regs.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
|
@ -52,25 +53,6 @@
|
|||
#define SPI_READ_MAX_SIZE 60
|
||||
|
||||
|
||||
/**
|
||||
* Copy unaligned data to 4-byte aligned destination buffer.
|
||||
*
|
||||
* @param words Number of 4-byte words to write.
|
||||
*
|
||||
* @see unaligned_memcpy.S
|
||||
*/
|
||||
void memcpy_unaligned_src(volatile uint32_t *dst, uint8_t *src, uint8_t words);
|
||||
|
||||
/**
|
||||
* Copy 4-byte aligned source data to unaligned destination buffer.
|
||||
*
|
||||
* @param bytes Number of byte to copy to dst.
|
||||
*
|
||||
* @see unaligned_memcpy.S
|
||||
*/
|
||||
void memcpy_unaligned_dst(uint8_t *dst, volatile uint32_t *src, uint8_t bytes);
|
||||
|
||||
|
||||
/**
|
||||
* Low level SPI flash write. Write block of data up to 64 bytes.
|
||||
*/
|
||||
|
@ -86,7 +68,9 @@ static inline void IRAM spi_write_data(sdk_flashchip_t *chip, uint32_t addr,
|
|||
|
||||
SPI(0).ADDR = (addr & 0x00FFFFFF) | (size << 24);
|
||||
|
||||
memcpy_unaligned_src(SPI(0).W, buf, words);
|
||||
memcpy((void*)SPI(0).W, buf, words<<2);
|
||||
|
||||
__asm__ volatile("memw");
|
||||
|
||||
SPI_write_enable(chip);
|
||||
|
||||
|
@ -97,16 +81,16 @@ static inline void IRAM spi_write_data(sdk_flashchip_t *chip, uint32_t addr,
|
|||
/**
|
||||
* Write a page of flash. Data block should not cross page boundary.
|
||||
*/
|
||||
static uint32_t IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_addr,
|
||||
static bool IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_addr,
|
||||
uint8_t *buf, uint32_t size)
|
||||
{
|
||||
// check if block to write doesn't cross page boundary
|
||||
if (flashchip->page_size < size + (dest_addr % flashchip->page_size)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size < 1) {
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
while (size >= SPI_WRITE_MAX_SIZE) {
|
||||
|
@ -117,58 +101,58 @@ static uint32_t IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_ad
|
|||
buf += SPI_WRITE_MAX_SIZE;
|
||||
|
||||
if (size < 1) {
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
spi_write_data(flashchip, dest_addr, buf, size);
|
||||
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split block of data into pages and write pages.
|
||||
*/
|
||||
static uint32_t IRAM spi_write(uint32_t addr, uint8_t *dst, uint32_t size)
|
||||
static bool IRAM spi_write(uint32_t addr, uint8_t *dst, uint32_t size)
|
||||
{
|
||||
if (sdk_flashchip.chip_size < (addr + size)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t write_bytes_to_page = sdk_flashchip.page_size -
|
||||
(addr % sdk_flashchip.page_size); // TODO: place for optimization
|
||||
|
||||
if (size < write_bytes_to_page) {
|
||||
if (spi_write_page(&sdk_flashchip, addr, dst, size)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
if (!spi_write_page(&sdk_flashchip, addr, dst, size)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
if (!spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = write_bytes_to_page;
|
||||
uint32_t pages_to_write = (size - offset) / sdk_flashchip.page_size;
|
||||
for (uint8_t i = 0; i != pages_to_write; i++) {
|
||||
if (spi_write_page(&sdk_flashchip, addr + offset,
|
||||
for (uint32_t i = 0; i < pages_to_write; i++) {
|
||||
if (!spi_write_page(&sdk_flashchip, addr + offset,
|
||||
dst + offset, sdk_flashchip.page_size)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
offset += sdk_flashchip.page_size;
|
||||
}
|
||||
|
||||
if (spi_write_page(&sdk_flashchip, addr + offset,
|
||||
if (!spi_write_page(&sdk_flashchip, addr + offset,
|
||||
dst + offset, size - offset)) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t IRAM esp_spiffs_flash_write(uint32_t addr, uint8_t *buf, uint32_t size)
|
||||
bool IRAM spiflash_write(uint32_t addr, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
uint32_t result = ESP_SPIFFS_FLASH_ERROR;
|
||||
bool result = false;
|
||||
|
||||
if (buf) {
|
||||
vPortEnterCritical();
|
||||
|
@ -197,21 +181,23 @@ static inline void IRAM read_block(sdk_flashchip_t *chip, uint32_t addr,
|
|||
|
||||
while (SPI(0).CMD) {};
|
||||
|
||||
memcpy_unaligned_dst(buf, SPI(0).W, size);
|
||||
__asm__ volatile("memw");
|
||||
|
||||
memcpy(buf, (const void*)SPI(0).W, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read SPI flash data. Data region doesn't need to be page aligned.
|
||||
*/
|
||||
static inline uint32_t IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr,
|
||||
static inline bool IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr,
|
||||
uint8_t *dst, uint32_t size)
|
||||
{
|
||||
if (size < 1) {
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((addr + size) > flashchip->chip_size) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (size >= SPI_READ_MAX_SIZE) {
|
||||
|
@ -225,12 +211,12 @@ static inline uint32_t IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr,
|
|||
read_block(flashchip, addr, dst, size);
|
||||
}
|
||||
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t IRAM esp_spiffs_flash_read(uint32_t dest_addr, uint8_t *buf, uint32_t size)
|
||||
bool IRAM spiflash_read(uint32_t dest_addr, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
uint32_t result = ESP_SPIFFS_FLASH_ERROR;
|
||||
bool result = false;
|
||||
|
||||
if (buf) {
|
||||
vPortEnterCritical();
|
||||
|
@ -245,14 +231,14 @@ uint32_t IRAM esp_spiffs_flash_read(uint32_t dest_addr, uint8_t *buf, uint32_t s
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr)
|
||||
bool IRAM spiflash_erase_sector(uint32_t addr)
|
||||
{
|
||||
if ((addr + sdk_flashchip.sector_size) > sdk_flashchip.chip_size) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (addr & 0xFFF) {
|
||||
return ESP_SPIFFS_FLASH_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
vPortEnterCritical();
|
||||
|
@ -269,5 +255,5 @@ uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr)
|
|||
Cache_Read_Enable(0, 0, 1);
|
||||
vPortExitCritical();
|
||||
|
||||
return ESP_SPIFFS_FLASH_OK;
|
||||
return true;
|
||||
}
|
361
core/sysparam.c
361
core/sysparam.c
|
@ -8,14 +8,12 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sysparam.h>
|
||||
#include <espressif/spi_flash.h>
|
||||
#include "spiflash.h"
|
||||
#include "flashchip.h"
|
||||
#include <common_macros.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
//TODO: make this properly threadsafe
|
||||
//TODO: reduce stack usage
|
||||
|
||||
/* The "magic" value that indicates the start of a sysparam region in flash.
|
||||
*/
|
||||
#define SYSPARAM_MAGIC 0x70524f45 // "EORp" in little-endian
|
||||
|
@ -33,11 +31,14 @@
|
|||
*/
|
||||
#define SCAN_BUFFER_SIZE 8 // words
|
||||
|
||||
/* The size of the temporary buffer used for reading back and verifying data
|
||||
* written to flash. Making this larger will make the write-and-verify
|
||||
* operation slightly faster, but will use more heap during writes
|
||||
/* The size in words of the buffer used for reading keys when searching for a
|
||||
* match, for reading payloads to check if the value has changed, and reading
|
||||
* back from the flash to verify writes. Will work well if big enough for
|
||||
* commonly used keys, and must be at least one word. Stack allocated so not too
|
||||
* large!
|
||||
*/
|
||||
#define VERIFY_BUF_SIZE 64
|
||||
#define BOUNCE_BUFFER_WORDS 3
|
||||
#define BOUNCE_BUFFER_SIZE (BOUNCE_BUFFER_WORDS * sizeof(uint32_t))
|
||||
|
||||
/* Size of region/entry headers. These should not normally need tweaking (and
|
||||
* will probably require some code changes if they are tweaked).
|
||||
|
@ -76,14 +77,16 @@
|
|||
/******************************* Useful Macros *******************************/
|
||||
|
||||
#define ROUND_TO_WORD_BOUNDARY(x) (((x) + 3) & 0xfffffffc)
|
||||
#define ENTRY_SIZE(payload_len) (ENTRY_HEADER_SIZE + ROUND_TO_WORD_BOUNDARY(payload_len))
|
||||
#define ENTRY_SIZE(payload_len) (ENTRY_HEADER_SIZE + payload_len)
|
||||
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
#define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); }
|
||||
|
||||
#define CHECK_FLASH_OP(x) do { int __x = (x); if ((__x) != SPI_FLASH_RESULT_OK) { debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; } } while (0);
|
||||
#define CHECK_FLASH_OP(x) do { bool __x = (x); if (!(__x)) { \
|
||||
debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; \
|
||||
} } while (0);
|
||||
|
||||
/********************* Internal datatypes and structures *********************/
|
||||
|
||||
|
@ -119,50 +122,28 @@ static struct {
|
|||
|
||||
/***************************** Internal routines *****************************/
|
||||
|
||||
static inline IRAM sysparam_status_t _do_write(uint32_t addr, const void *data, size_t data_size) {
|
||||
CHECK_FLASH_OP(sdk_spi_flash_write(addr, (void*) data, data_size));
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
static sysparam_status_t _write_and_verify(uint32_t addr, const void *data, size_t data_size) {
|
||||
uint8_t bounce[BOUNCE_BUFFER_SIZE];
|
||||
|
||||
static inline IRAM sysparam_status_t _do_verify(uint32_t addr, const void *data, void *buffer, size_t len) {
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(addr, buffer, len));
|
||||
if (memcmp(data, buffer, len)) {
|
||||
for (int i = 0; i < data_size; i += BOUNCE_BUFFER_SIZE) {
|
||||
size_t count = min(data_size - i, BOUNCE_BUFFER_SIZE);
|
||||
memcpy(bounce, data + i, count);
|
||||
CHECK_FLASH_OP(spiflash_write(addr + i, bounce, count));
|
||||
CHECK_FLASH_OP(spiflash_read(addr + i, bounce, count));
|
||||
if (memcmp(data + i, bounce, count) != 0) {
|
||||
debug(1, "Flash write (@ 0x%08x) verify failed!", addr);
|
||||
return SYSPARAM_ERR_IO;
|
||||
}
|
||||
}
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
/*FIXME: Eventually, this should probably be implemented down at the SPI flash library layer, where it can just compare bytes/words straight from the SPI hardware buffer instead of allocating a whole separate temp buffer, reading chunks into that, and then doing a memcmp.. */
|
||||
static IRAM sysparam_status_t _write_and_verify(uint32_t addr, const void *data, size_t data_size) {
|
||||
int i;
|
||||
size_t count;
|
||||
sysparam_status_t status = SYSPARAM_OK;
|
||||
uint8_t *verify_buf = malloc(VERIFY_BUF_SIZE);
|
||||
|
||||
if (!verify_buf) return SYSPARAM_ERR_NOMEM;
|
||||
do {
|
||||
status = _do_write(addr, data, data_size);
|
||||
if (status != SYSPARAM_OK) break;
|
||||
for (i = 0; i < data_size; i += VERIFY_BUF_SIZE) {
|
||||
count = min(data_size - i, VERIFY_BUF_SIZE);
|
||||
status = _do_verify(addr + i, data + i, verify_buf, count);
|
||||
if (status != SYSPARAM_OK) {
|
||||
debug(1, "Flash write (@ 0x%08x) verify failed!", addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
free(verify_buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Erase the sectors of a region */
|
||||
static sysparam_status_t _format_region(uint32_t addr, uint16_t num_sectors) {
|
||||
uint16_t sector = addr / sdk_flashchip.sector_size;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_sectors; i++) {
|
||||
CHECK_FLASH_OP(sdk_spi_flash_erase_sector(sector + i));
|
||||
CHECK_FLASH_OP(spiflash_erase_sector(addr + (i * SPI_FLASH_SECTOR_SIZE)));
|
||||
}
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
@ -212,7 +193,7 @@ static sysparam_status_t init_write_context(struct sysparam_context *ctx) {
|
|||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->addr = _sysparam_info.end_addr;
|
||||
debug(3, "read entry header @ 0x%08x", ctx->addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE));
|
||||
CHECK_FLASH_OP(spiflash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE));
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
|
@ -238,7 +219,10 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc
|
|||
// workaround is to make sure that the next write operation
|
||||
// will always start with a compaction, which will leave off
|
||||
// the invalid data at the end and fix the issue going forward.
|
||||
debug(1, "Encountered entry with invalid length (0x%04x) @ 0x%08x (region end is 0x%08x). Truncating entries.", ctx->entry.len, ctx->addr, _sysparam_info.end_addr);
|
||||
debug(1, "Encountered entry with invalid length (0x%04x) @ 0x%08x (region end is 0x%08x). Truncating entries.",
|
||||
ctx->entry.len,
|
||||
ctx->addr, _sysparam_info.end_addr);
|
||||
|
||||
_sysparam_info.force_compact = true;
|
||||
break;
|
||||
}
|
||||
|
@ -251,7 +235,7 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc
|
|||
}
|
||||
|
||||
debug(3, "read entry header @ 0x%08x", ctx->addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE));
|
||||
CHECK_FLASH_OP(spiflash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE));
|
||||
debug(3, " idflags = 0x%04x", ctx->entry.idflags);
|
||||
if (ctx->entry.idflags == 0xffff) {
|
||||
// 0xffff is never a valid id field, so this means we've hit the
|
||||
|
@ -295,17 +279,39 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc
|
|||
}
|
||||
|
||||
/** Read the payload from the current entry pointed to by `ctx` */
|
||||
|
||||
static inline sysparam_status_t _read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) {
|
||||
debug(3, "read payload (%d) @ 0x%08x", min(buffer_size, ctx->entry.len), ctx->addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr + ENTRY_HEADER_SIZE, (void*) buffer, min(buffer_size, ctx->entry.len)));
|
||||
uint32_t addr = ctx->addr + ENTRY_HEADER_SIZE;
|
||||
size_t size = min(buffer_size, ctx->entry.len);
|
||||
debug(3, "read payload (%d) @ 0x%08x", size, addr);
|
||||
|
||||
CHECK_FLASH_OP(spiflash_read(addr, buffer, buffer_size));
|
||||
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
static inline sysparam_status_t _compare_payload(struct sysparam_context *ctx, uint8_t *value, size_t size) {
|
||||
debug(3, "compare payload (%d) @ 0x%08x", size, ctx->addr);
|
||||
if (ctx->entry.len != size) return SYSPARAM_NOTFOUND;
|
||||
uint32_t bounce[BOUNCE_BUFFER_WORDS];
|
||||
uint32_t addr = ctx->addr + ENTRY_HEADER_SIZE;
|
||||
int i;
|
||||
for (i = 0; i < size; i += BOUNCE_BUFFER_SIZE) {
|
||||
int len = min(size - i, BOUNCE_BUFFER_SIZE);
|
||||
CHECK_FLASH_OP(spiflash_read(addr + i, (void*)bounce, len));
|
||||
if (memcmp(value + i, bounce, len)) {
|
||||
// Mismatch.
|
||||
return SYSPARAM_NOTFOUND;
|
||||
}
|
||||
}
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
/** Find the entry corresponding to the specified key name */
|
||||
static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key, uint16_t key_len, uint8_t *buffer) {
|
||||
static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key, uint16_t key_len) {
|
||||
sysparam_status_t status;
|
||||
|
||||
debug(3, "find key: %s", key ? key : "(null)");
|
||||
debug(3, "find key len %d: %s", key_len, key ? key : "(null)");
|
||||
while (true) {
|
||||
// Find the next key entry
|
||||
status = _find_entry(ctx, ENTRY_ID_ANY, false);
|
||||
|
@ -316,12 +322,12 @@ static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key
|
|||
break;
|
||||
}
|
||||
if (ctx->entry.len == key_len) {
|
||||
status = _read_payload(ctx, buffer, key_len);
|
||||
if (status < 0) return status;
|
||||
if (!memcmp(key, buffer, key_len)) {
|
||||
status = _compare_payload(ctx, (uint8_t *)key, key_len);
|
||||
if (status == SYSPARAM_OK) {
|
||||
// We have a match
|
||||
break;
|
||||
}
|
||||
if (status != SYSPARAM_NOTFOUND) return status;
|
||||
debug(3, "entry payload does not match");
|
||||
} else {
|
||||
debug(3, "key length (%d) does not match (%d)", ctx->entry.len, key_len);
|
||||
|
@ -394,20 +400,18 @@ static inline sysparam_status_t _delete_entry(uint32_t addr) {
|
|||
|
||||
debug(2, "Deleting entry @ 0x%08x", addr);
|
||||
debug(3, "read entry header @ 0x%08x", addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(addr, (void*) &entry, ENTRY_HEADER_SIZE));
|
||||
CHECK_FLASH_OP(spiflash_read(addr, (uint8_t*) &entry, ENTRY_HEADER_SIZE));
|
||||
// Set the ID to zero to mark it as "deleted"
|
||||
entry.idflags &= ~ENTRY_FLAG_ALIVE;
|
||||
debug(3, "write entry header @ 0x%08x", addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_write(addr, (void*) &entry, ENTRY_HEADER_SIZE));
|
||||
|
||||
return SYSPARAM_OK;
|
||||
return _write_and_verify(addr, &entry, ENTRY_HEADER_SIZE);
|
||||
}
|
||||
|
||||
/** Compact the current region, removing all deleted/unused entries, and write
|
||||
* the result to the alternate region, then make the new alternate region the
|
||||
* active one.
|
||||
*
|
||||
* @param key_id A pointer to the "current" key ID.
|
||||
* @param key_id A pointer to the "current" key ID, or NULL if none.
|
||||
*
|
||||
* NOTE: The value corresponding to the passed key ID will not be written to
|
||||
* the output (because it is assumed it will be overwritten as the next step
|
||||
|
@ -424,7 +428,11 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_
|
|||
uint16_t binary_flag;
|
||||
uint16_t num_sectors = _sysparam_info.region_size / sdk_flashchip.sector_size;
|
||||
|
||||
debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys > 0) ? "+ (unused keys present)" : "");
|
||||
debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...",
|
||||
_sysparam_info.end_addr - _sysparam_info.cur_base,
|
||||
ctx ? ctx->compactable : 0,
|
||||
(ctx && ctx->unused_keys > 0) ? "+ (unused keys present)" : "");
|
||||
|
||||
status = _format_region(new_base, num_sectors);
|
||||
if (status < 0) return status;
|
||||
status = sysparam_iter_start(&iter);
|
||||
|
@ -442,7 +450,7 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_
|
|||
if (status < 0) break;
|
||||
addr += ENTRY_SIZE(iter.key_len);
|
||||
|
||||
if ((iter.ctx->entry.idflags & ENTRY_MASK_ID) == *key_id) {
|
||||
if (key_id && (iter.ctx->entry.idflags & ENTRY_MASK_ID) == *key_id) {
|
||||
// Update key_id to have the correct id for the compacted result
|
||||
*key_id = current_key_id;
|
||||
// Don't copy the old value, since we'll just be deleting it
|
||||
|
@ -476,10 +484,12 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_
|
|||
_sysparam_info.end_addr = addr;
|
||||
_sysparam_info.force_compact = false;
|
||||
|
||||
if (ctx) {
|
||||
// Fix up ctx so it doesn't point to invalid stuff
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->addr = addr;
|
||||
ctx->max_key_id = current_key_id;
|
||||
}
|
||||
|
||||
debug(1, "done compacting (current size %d)", _sysparam_info.end_addr - _sysparam_info.cur_base);
|
||||
|
||||
|
@ -495,6 +505,8 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
|||
struct sysparam_context ctx;
|
||||
uint16_t num_sectors;
|
||||
|
||||
_sysparam_info.sem = xSemaphoreCreateMutex();
|
||||
|
||||
// Make sure we're starting at the beginning of the sector
|
||||
base_addr -= (base_addr % sdk_flashchip.sector_size);
|
||||
|
||||
|
@ -503,7 +515,7 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
|||
top_addr = base_addr + sdk_flashchip.sector_size;
|
||||
}
|
||||
for (addr0 = base_addr; addr0 < top_addr; addr0 += sdk_flashchip.sector_size) {
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(addr0, (void*) &header0, REGION_HEADER_SIZE));
|
||||
CHECK_FLASH_OP(spiflash_read(addr0, (void*) &header0, REGION_HEADER_SIZE));
|
||||
if (header0.magic == SYSPARAM_MAGIC) {
|
||||
// Found a starting point...
|
||||
break;
|
||||
|
@ -521,7 +533,7 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
|||
} else {
|
||||
addr1 = addr0 + num_sectors * sdk_flashchip.sector_size;
|
||||
}
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(addr1, (void*) &header1, REGION_HEADER_SIZE));
|
||||
CHECK_FLASH_OP(spiflash_read(addr1, (uint8_t*) &header1, REGION_HEADER_SIZE));
|
||||
|
||||
if (header1.magic == SYSPARAM_MAGIC) {
|
||||
// Yay! Found the other one. Sanity-check it..
|
||||
|
@ -574,8 +586,6 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
|||
_sysparam_info.end_addr = ctx.addr;
|
||||
}
|
||||
|
||||
_sysparam_info.sem = xSemaphoreCreateMutex();
|
||||
|
||||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
|
@ -596,9 +606,9 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, uint16_t num_sectors,
|
|||
if (!force) {
|
||||
// First, scan through the area and make sure it's actually empty and
|
||||
// we're not going to be clobbering something else important.
|
||||
for (addr = base_addr; addr < base_addr + region_size * 2; addr += SCAN_BUFFER_SIZE) {
|
||||
for (addr = base_addr; addr < base_addr + region_size * 2; addr += SCAN_BUFFER_SIZE * sizeof(uint32_t)) {
|
||||
debug(3, "read %d words @ 0x%08x", SCAN_BUFFER_SIZE, addr);
|
||||
CHECK_FLASH_OP(sdk_spi_flash_read(addr, buffer, SCAN_BUFFER_SIZE * 4));
|
||||
CHECK_FLASH_OP(spiflash_read(addr, (uint8_t*)buffer, SCAN_BUFFER_SIZE * sizeof(uint32_t)));
|
||||
for (i = 0; i < SCAN_BUFFER_SIZE; i++) {
|
||||
if (buffer[i] != 0xffffffff) {
|
||||
// Uh oh, not empty.
|
||||
|
@ -634,34 +644,54 @@ sysparam_status_t sysparam_get_info(uint32_t *base_addr, uint32_t *num_sectors)
|
|||
return SYSPARAM_OK;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_compact() {
|
||||
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
|
||||
sysparam_status_t status;
|
||||
|
||||
if (_sysparam_info.cur_base) {
|
||||
status = _compact_params(NULL, NULL);
|
||||
} else {
|
||||
status = SYSPARAM_ERR_NOINIT;
|
||||
}
|
||||
|
||||
xSemaphoreGive(_sysparam_info.sem);
|
||||
return status;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary) {
|
||||
struct sysparam_context ctx;
|
||||
sysparam_status_t status;
|
||||
size_t key_len = strlen(key);
|
||||
uint8_t *buffer;
|
||||
uint8_t *newbuf;
|
||||
|
||||
if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
|
||||
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
|
||||
|
||||
if (actual_length) *actual_length = 0;
|
||||
|
||||
if (!_sysparam_info.cur_base) {
|
||||
status = SYSPARAM_ERR_NOINIT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
buffer = malloc(key_len + 2);
|
||||
if (!buffer) return SYSPARAM_ERR_NOMEM;
|
||||
do {
|
||||
_init_context(&ctx);
|
||||
status = _find_key(&ctx, key, key_len, buffer);
|
||||
if (status != SYSPARAM_OK) break;
|
||||
status = _find_key(&ctx, key, key_len);
|
||||
if (status != SYSPARAM_OK) goto done;
|
||||
|
||||
// Find the associated value
|
||||
status = _find_value(&ctx, ctx.entry.idflags);
|
||||
if (status != SYSPARAM_OK) break;
|
||||
if (status != SYSPARAM_OK) goto done;
|
||||
|
||||
newbuf = realloc(buffer, ctx.entry.len + 1);
|
||||
if (!newbuf) {
|
||||
buffer = malloc(ctx.entry.len + 1);
|
||||
if (!buffer) {
|
||||
status = SYSPARAM_ERR_NOMEM;
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
buffer = newbuf;
|
||||
|
||||
status = _read_payload(&ctx, buffer, ctx.entry.len);
|
||||
if (status != SYSPARAM_OK) break;
|
||||
if (status != SYSPARAM_OK) {
|
||||
free(buffer);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Zero-terminate the result, just in case (doesn't hurt anything for
|
||||
// non-string data, and can avoid nasty mistakes if the caller wants to
|
||||
|
@ -671,38 +701,41 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *
|
|||
*destptr = buffer;
|
||||
if (actual_length) *actual_length = ctx.entry.len;
|
||||
if (is_binary) *is_binary = (bool)(ctx.entry.idflags & ENTRY_FLAG_BINARY);
|
||||
return SYSPARAM_OK;
|
||||
} while (false);
|
||||
status = SYSPARAM_OK;
|
||||
|
||||
free(buffer);
|
||||
if (actual_length) *actual_length = 0;
|
||||
done:
|
||||
xSemaphoreGive(_sysparam_info.sem);
|
||||
return status;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, size_t buffer_size, size_t *actual_length, bool *is_binary) {
|
||||
sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary) {
|
||||
struct sysparam_context ctx;
|
||||
sysparam_status_t status = SYSPARAM_OK;
|
||||
size_t key_len = strlen(key);
|
||||
|
||||
if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
|
||||
|
||||
// Supplied buffer must be at least as large as the key, or 2 bytes,
|
||||
// whichever is larger.
|
||||
if (buffer_size < max(key_len, 2)) return SYSPARAM_ERR_NOMEM;
|
||||
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
|
||||
|
||||
if (actual_length) *actual_length = 0;
|
||||
|
||||
if (!_sysparam_info.cur_base) {
|
||||
status = SYSPARAM_ERR_NOINIT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_init_context(&ctx);
|
||||
status = _find_key(&ctx, key, key_len, buffer);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
status = _find_key(&ctx, key, key_len);
|
||||
if (status != SYSPARAM_OK) goto done;
|
||||
status = _find_value(&ctx, ctx.entry.idflags);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
status = _read_payload(&ctx, buffer, buffer_size);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
if (status != SYSPARAM_OK) goto done;
|
||||
status = _read_payload(&ctx, dest, dest_size);
|
||||
if (status != SYSPARAM_OK) goto done;
|
||||
|
||||
if (actual_length) *actual_length = ctx.entry.len;
|
||||
if (is_binary) *is_binary = (bool)(ctx.entry.idflags & ENTRY_FLAG_BINARY);
|
||||
return SYSPARAM_OK;
|
||||
|
||||
done:
|
||||
xSemaphoreGive(_sysparam_info.sem);
|
||||
return status;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_get_string(const char *key, char **destptr) {
|
||||
|
@ -725,63 +758,82 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr) {
|
|||
}
|
||||
|
||||
sysparam_status_t sysparam_get_int32(const char *key, int32_t *result) {
|
||||
char *buffer;
|
||||
char *endptr;
|
||||
int32_t value;
|
||||
size_t actual_length;
|
||||
bool is_binary;
|
||||
sysparam_status_t status;
|
||||
|
||||
status = sysparam_get_string(key, &buffer);
|
||||
status = sysparam_get_data_static(key, (uint8_t *)&value, sizeof(int32_t),
|
||||
&actual_length, &is_binary);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
value = strtol(buffer, &endptr, 0);
|
||||
if (*endptr) {
|
||||
// There was extra crap at the end of the string.
|
||||
free(buffer);
|
||||
if (!is_binary || actual_length != sizeof(int32_t))
|
||||
return SYSPARAM_PARSEFAILED;
|
||||
}
|
||||
|
||||
*result = value;
|
||||
free(buffer);
|
||||
return SYSPARAM_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_get_int8(const char *key, int8_t *result) {
|
||||
int32_t value;
|
||||
int8_t value;
|
||||
size_t actual_length;
|
||||
bool is_binary;
|
||||
sysparam_status_t status;
|
||||
|
||||
status = sysparam_get_int32(key, &value);
|
||||
if (status == SYSPARAM_OK) {
|
||||
status = sysparam_get_data_static(key, (uint8_t *)&value, sizeof(int8_t),
|
||||
&actual_length, &is_binary);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
if (!is_binary || actual_length != sizeof(int8_t))
|
||||
return SYSPARAM_PARSEFAILED;
|
||||
*result = value;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_get_bool(const char *key, bool *result) {
|
||||
char *buffer;
|
||||
const size_t buf_size = 8;
|
||||
char buf[buf_size + 1]; // extra byte for zero termination
|
||||
size_t data_len = 0;
|
||||
bool binary = false;
|
||||
sysparam_status_t status;
|
||||
|
||||
status = sysparam_get_string(key, &buffer);
|
||||
status = sysparam_get_data_static(key, (uint8_t*)buf,
|
||||
buf_size, &data_len, &binary);
|
||||
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
do {
|
||||
if (!strcasecmp(buffer, "y") ||
|
||||
!strcasecmp(buffer, "yes") ||
|
||||
!strcasecmp(buffer, "t") ||
|
||||
!strcasecmp(buffer, "true") ||
|
||||
!strcmp(buffer, "1")) {
|
||||
if (binary) {
|
||||
if (data_len == 1) { // int8 value
|
||||
uint8_t value;
|
||||
memcpy(&value, buf, sizeof(value));
|
||||
*result = value ? true : false;
|
||||
} else if (data_len == 4) { // int32 value
|
||||
uint32_t value;
|
||||
memcpy(&value, buf, sizeof(value));
|
||||
*result = value ? true : false;
|
||||
} else {
|
||||
status = SYSPARAM_PARSEFAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
buf[data_len] = 0;
|
||||
|
||||
if (!strcasecmp(buf, "y") ||
|
||||
!strcasecmp(buf, "yes") ||
|
||||
!strcasecmp(buf, "t") ||
|
||||
!strcasecmp(buf, "true") ||
|
||||
!strcmp(buf, "1")) {
|
||||
*result = true;
|
||||
break;
|
||||
}
|
||||
if (!strcasecmp(buffer, "n") ||
|
||||
!strcasecmp(buffer, "no") ||
|
||||
!strcasecmp(buffer, "f") ||
|
||||
!strcasecmp(buffer, "false") ||
|
||||
!strcmp(buffer, "0")) {
|
||||
if (!strcasecmp(buf, "n") ||
|
||||
!strcasecmp(buf, "no") ||
|
||||
!strcasecmp(buf, "f") ||
|
||||
!strcasecmp(buf, "false") ||
|
||||
!strcmp(buf, "0")) {
|
||||
*result = false;
|
||||
break;
|
||||
}
|
||||
status = SYSPARAM_PARSEFAILED;
|
||||
} while (0);
|
||||
|
||||
free(buffer);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -790,48 +842,30 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
|
|||
struct sysparam_context write_ctx;
|
||||
sysparam_status_t status = SYSPARAM_OK;
|
||||
uint16_t key_len = strlen(key);
|
||||
uint8_t *buffer;
|
||||
uint8_t *newbuf;
|
||||
size_t free_space;
|
||||
size_t needed_space;
|
||||
bool free_value = false;
|
||||
int key_id = -1;
|
||||
uint32_t old_value_addr = 0;
|
||||
uint16_t binary_flag;
|
||||
|
||||
if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
|
||||
if (!key_len) return SYSPARAM_ERR_BADVALUE;
|
||||
if (key_len > MAX_KEY_LEN) return SYSPARAM_ERR_BADVALUE;
|
||||
if (value_len > MAX_VALUE_LEN) return SYSPARAM_ERR_BADVALUE;
|
||||
|
||||
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
|
||||
|
||||
if (!value) value_len = 0;
|
||||
|
||||
debug(1, "updating value for '%s' (%d bytes)", key, value_len);
|
||||
if (value_len && ((intptr_t)value & 0x3)) {
|
||||
// The passed value isn't word-aligned. This will be a problem later
|
||||
// when calling `sdk_spi_flash_write`, so make a word-aligned copy.
|
||||
buffer = malloc(value_len);
|
||||
if (!buffer) {
|
||||
status = SYSPARAM_ERR_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
memcpy(buffer, value, value_len);
|
||||
value = buffer;
|
||||
free_value = true;
|
||||
}
|
||||
// Create a working buffer for `_find_key` to use.
|
||||
buffer = malloc(key_len);
|
||||
if (!buffer) {
|
||||
if (free_value) free((void *)value);
|
||||
status = SYSPARAM_ERR_NOMEM;
|
||||
|
||||
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
|
||||
|
||||
if (!_sysparam_info.cur_base) {
|
||||
status = SYSPARAM_ERR_NOINIT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
do {
|
||||
_init_context(&ctx);
|
||||
status = _find_key(&ctx, key, key_len, buffer);
|
||||
status = _find_key(&ctx, key, key_len);
|
||||
if (status == SYSPARAM_OK) {
|
||||
// Key already exists, see if there's a current value.
|
||||
key_id = ctx.entry.idflags & ENTRY_MASK_ID;
|
||||
|
@ -846,24 +880,17 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
|
|||
|
||||
if (value_len) {
|
||||
if (old_value_addr) {
|
||||
if ((ctx.entry.idflags & ENTRY_FLAG_BINARY) == binary_flag && ctx.entry.len == value_len) {
|
||||
if ((ctx.entry.idflags & ENTRY_FLAG_BINARY) == binary_flag &&
|
||||
ctx.entry.len == value_len) {
|
||||
// Are we trying to write the same value that's already there?
|
||||
if (value_len > key_len) {
|
||||
newbuf = realloc(buffer, value_len);
|
||||
if (!newbuf) {
|
||||
status = SYSPARAM_ERR_NOMEM;
|
||||
break;
|
||||
}
|
||||
buffer = newbuf;
|
||||
}
|
||||
status = _read_payload(&ctx, buffer, value_len);
|
||||
if (status < 0) break;
|
||||
if (!memcmp(buffer, value, value_len)) {
|
||||
status = _compare_payload(&ctx, (uint8_t *)value, value_len);
|
||||
if (status == SYSPARAM_OK) {
|
||||
// Yup, it's a match! No need to do anything further,
|
||||
// just leave the current value as-is.
|
||||
status = SYSPARAM_OK;
|
||||
break;
|
||||
}
|
||||
if (status != SYSPARAM_NOTFOUND) goto done;
|
||||
}
|
||||
|
||||
// Since we will be deleting the old value (if any) make sure
|
||||
|
@ -965,9 +992,6 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
|
|||
debug(1, "New addr is 0x%08x (%d bytes remaining)", _sysparam_info.end_addr, _sysparam_info.cur_base + _sysparam_info.region_size - _sysparam_info.end_addr);
|
||||
} while (false);
|
||||
|
||||
if (free_value) free((void *)value);
|
||||
free(buffer);
|
||||
|
||||
done:
|
||||
xSemaphoreGive(_sysparam_info.sem);
|
||||
|
||||
|
@ -979,15 +1003,11 @@ sysparam_status_t sysparam_set_string(const char *key, const char *value) {
|
|||
}
|
||||
|
||||
sysparam_status_t sysparam_set_int32(const char *key, int32_t value) {
|
||||
uint8_t buffer[12];
|
||||
int len;
|
||||
|
||||
len = snprintf((char *)buffer, 12, "%d", value);
|
||||
return sysparam_set_data(key, buffer, len, false);
|
||||
return sysparam_set_data(key, (const uint8_t *)&value, sizeof(value), true);
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_set_int8(const char *key, int8_t value) {
|
||||
return sysparam_set_int32(key, value);
|
||||
return sysparam_set_data(key, (const uint8_t *)&value, sizeof(value), true);
|
||||
}
|
||||
|
||||
sysparam_status_t sysparam_set_bool(const char *key, bool value) {
|
||||
|
@ -1027,7 +1047,6 @@ sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) {
|
|||
}
|
||||
|
||||
sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
|
||||
uint8_t buffer[2];
|
||||
sysparam_status_t status;
|
||||
size_t required_len;
|
||||
struct sysparam_context *ctx = iter->ctx;
|
||||
|
@ -1036,7 +1055,7 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
|
|||
char *newbuf;
|
||||
|
||||
while (true) {
|
||||
status = _find_key(ctx, NULL, 0, buffer);
|
||||
status = _find_key(ctx, NULL, 0);
|
||||
if (status != SYSPARAM_OK) return status;
|
||||
memcpy(&value_ctx, ctx, sizeof(value_ctx));
|
||||
|
||||
|
@ -1044,7 +1063,7 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
|
|||
if (status < 0) return status;
|
||||
if (status == SYSPARAM_NOTFOUND) continue;
|
||||
|
||||
key_space = ROUND_TO_WORD_BOUNDARY(ctx->entry.len + 1);
|
||||
key_space = ctx->entry.len + 1;
|
||||
required_len = key_space + value_ctx.entry.len + 1;
|
||||
if (required_len > iter->bufsize) {
|
||||
newbuf = realloc(iter->key, required_len);
|
||||
|
|
|
@ -2,6 +2,7 @@ EXAMPLES = $(shell find $(dir $(lastword $(MAKEFILE_LIST))) -mindepth 2 -name Ma
|
|||
# Generate some dummy .dummybuild/.dummyrebuild target files
|
||||
EXAMPLES_BUILD = $(patsubst %,%.dummybuild,$(EXAMPLES))
|
||||
EXAMPLES_REBUILD = $(patsubst %,%.dummyrebuild,$(EXAMPLES))
|
||||
EXAMPLES_CLEAN = $(patsubst %,%.dummyclean,$(EXAMPLES))
|
||||
|
||||
warning:
|
||||
@echo "******************************************************"
|
||||
|
@ -21,12 +22,17 @@ build-examples: $(EXAMPLES_BUILD)
|
|||
|
||||
rebuild-examples: $(EXAMPLES_REBUILD)
|
||||
|
||||
clean-examples: $(EXAMPLES_CLEAN)
|
||||
|
||||
%.dummybuild:
|
||||
$(MAKE) -C $(dir $@)
|
||||
|
||||
%.dummyrebuild:
|
||||
$(MAKE) -C $(dir $@) rebuild
|
||||
|
||||
.PHONY: warning rebuild-examples build-examples
|
||||
%.dummyclean:
|
||||
$(MAKE) -C $(dir $@) clean
|
||||
|
||||
.PHONY: warning rebuild-examples build-examples clean-examples
|
||||
.NOTPARALLEL:
|
||||
.ONESHELL:
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* Very basic example showing usage of access point mode and the DHCP server.
|
||||
|
||||
The ESP in the example runs a telnet server on 172.16.0.1 (port 23) that
|
||||
outputs some status information if you connect to it, then closes
|
||||
the connection.
|
||||
|
||||
This example code is in the public domain.
|
||||
*/
|
||||
/**
|
||||
* Very basic example showing usage of access point mode and the DHCP server.
|
||||
* The ESP in the example runs a telnet server on 172.16.0.1 (port 23) that
|
||||
* outputs some status information if you connect to it, then closes
|
||||
* the connection.
|
||||
*
|
||||
* This example code is in the public domain.
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include <espressif/esp_common.h>
|
||||
|
@ -36,44 +36,39 @@ void user_init(void)
|
|||
IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0);
|
||||
sdk_wifi_set_ip_info(1, &ap_ip);
|
||||
|
||||
struct sdk_softap_config ap_config = {
|
||||
.ssid = AP_SSID,
|
||||
.ssid_hidden = 0,
|
||||
.channel = 3,
|
||||
.ssid_len = strlen(AP_SSID),
|
||||
.authmode = AUTH_WPA_WPA2_PSK,
|
||||
.password = AP_PSK,
|
||||
.max_connection = 3,
|
||||
.beacon_interval = 100,
|
||||
};
|
||||
struct sdk_softap_config ap_config = { .ssid = AP_SSID, .ssid_hidden = 0, .channel = 3, .ssid_len = strlen(AP_SSID), .authmode =
|
||||
AUTH_WPA_WPA2_PSK, .password = AP_PSK, .max_connection = 3, .beacon_interval = 100, };
|
||||
sdk_wifi_softap_set_config(&ap_config);
|
||||
|
||||
ip_addr_t first_client_ip;
|
||||
IP4_ADDR(&first_client_ip, 172, 16, 0, 2);
|
||||
dhcpserver_start(&first_client_ip, 4);
|
||||
|
||||
xTaskCreate(telnetTask, "telnetTask", 512, NULL, 2, NULL);
|
||||
}
|
||||
|
||||
/* Telnet task listens on port 23, returns some status information and then closes
|
||||
the connection if you connect to it.
|
||||
*/
|
||||
*/
|
||||
static void telnetTask(void *pvParameters)
|
||||
{
|
||||
struct netconn *nc = netconn_new (NETCONN_TCP);
|
||||
if(!nc) {
|
||||
ip_addr_t first_client_ip;
|
||||
IP4_ADDR(&first_client_ip, 172, 16, 0, 2);
|
||||
dhcpserver_start(&first_client_ip, 4);
|
||||
|
||||
struct netconn *nc = netconn_new(NETCONN_TCP);
|
||||
if (!nc)
|
||||
{
|
||||
printf("Status monitor: Failed to allocate socket.\r\n");
|
||||
return;
|
||||
}
|
||||
netconn_bind(nc, IP_ADDR_ANY, TELNET_PORT);
|
||||
netconn_bind(nc, IP_ANY_TYPE, TELNET_PORT);
|
||||
netconn_listen(nc);
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
struct netconn *client = NULL;
|
||||
err_t err = netconn_accept(nc, &client);
|
||||
|
||||
if ( err != ERR_OK ) {
|
||||
if(client)
|
||||
if (err != ERR_OK)
|
||||
{
|
||||
if (client)
|
||||
netconn_delete(client);
|
||||
continue;
|
||||
}
|
||||
|
@ -83,14 +78,12 @@ static void telnetTask(void *pvParameters)
|
|||
netconn_peer(client, &client_addr, &port_ignore);
|
||||
|
||||
char buf[80];
|
||||
snprintf(buf, sizeof(buf), "Uptime %d seconds\r\n",
|
||||
xTaskGetTickCount()*portTICK_PERIOD_MS/1000);
|
||||
snprintf(buf, sizeof(buf), "Uptime %d seconds\r\n", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
|
||||
netconn_write(client, buf, strlen(buf), NETCONN_COPY);
|
||||
snprintf(buf, sizeof(buf), "Free heap %d bytes\r\n", (int)xPortGetFreeHeapSize());
|
||||
snprintf(buf, sizeof(buf), "Free heap %d bytes\r\n", (int) xPortGetFreeHeapSize());
|
||||
netconn_write(client, buf, strlen(buf), NETCONN_COPY);
|
||||
snprintf(buf, sizeof(buf), "Your address is %d.%d.%d.%d\r\n\r\n",
|
||||
ip4_addr1(&client_addr), ip4_addr2(&client_addr),
|
||||
ip4_addr3(&client_addr), ip4_addr4(&client_addr));
|
||||
char abuf[40];
|
||||
snprintf(buf, sizeof(buf), "Your address is %s\r\n\r\n", ipaddr_ntoa_r(&client_addr, abuf, sizeof(abuf)));
|
||||
netconn_write(client, buf, strlen(buf), NETCONN_COPY);
|
||||
netconn_delete(client);
|
||||
}
|
||||
|
|
4
examples/ad770x/Makefile
Normal file
4
examples/ad770x/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROGRAM = ad770x
|
||||
EXTRA_COMPONENTS = extras/ad770x
|
||||
#ESPBAUD = 460800
|
||||
include ../../common.mk
|
49
examples/ad770x/main.c
Normal file
49
examples/ad770x/main.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Example of using AD7705/AD7706 driver
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2017 Ruslan V. Uss <unclerus@gmail.com>
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#include <esp/uart.h>
|
||||
#include <espressif/esp_common.h>
|
||||
#include <stdio.h>
|
||||
#include <ad770x/ad770x.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#define CS_PIN 2
|
||||
#define AIN_CHANNEL 0 // AIN1+,AIN1- for AD7705
|
||||
|
||||
static const ad770x_params_t dev = {
|
||||
.cs_pin = CS_PIN,
|
||||
.master_clock = AD770X_MCLK_4_9152MHz, // 4.9152 MHz
|
||||
.bipolar = false, // Unipolar mode
|
||||
.gain = AD770X_GAIN_1, // No gain
|
||||
.update_rate = AD770X_RATE_50 // 50 Hz output update rate
|
||||
};
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_set_baud(0, 115200);
|
||||
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||
|
||||
while (ad770x_init(&dev, AIN_CHANNEL) != 0)
|
||||
{
|
||||
printf("Cannot initialize AD7705\n");
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
// wait for data
|
||||
while (!ad770x_data_ready(&dev, AIN_CHANNEL)) {}
|
||||
|
||||
// Read result
|
||||
uint16_t raw = ad770x_raw_adc_value(&dev, AIN_CHANNEL);
|
||||
|
||||
printf("Raw ADC value: %d\n", raw);
|
||||
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
4
examples/ads1115_test/Makefile
Normal file
4
examples/ads1115_test/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROGRAM = ads1115_test
|
||||
EXTRA_COMPONENTS = extras/i2c extras/ads111x
|
||||
#ESPBAUD = 460800
|
||||
include ../../common.mk
|
60
examples/ads1115_test/main.c
Normal file
60
examples/ads1115_test/main.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Example of using DS1302 RTC driver
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>
|
||||
* Pavel Merzlyakov <merzlyakovpavel@gmail.com>
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#include <esp/uart.h>
|
||||
#include <espressif/esp_common.h>
|
||||
#include <stdio.h>
|
||||
#include <i2c/i2c.h>
|
||||
#include <ads111x/ads111x.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
// Connect ADDR pin to GND
|
||||
#define ADDR ADS111X_ADDR_GND
|
||||
|
||||
#define I2C_BUS 0
|
||||
#define SCL_PIN 5
|
||||
#define SDA_PIN 4
|
||||
|
||||
// +-4.096V
|
||||
#define GAIN ADS111X_GAIN_4V096
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_set_baud(0, 115200);
|
||||
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||
|
||||
i2c_dev_t dev = {
|
||||
.addr = ADDR,
|
||||
.bus = I2C_BUS,
|
||||
};
|
||||
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
ads111x_set_mode(&dev, ADS111X_MODE_CONTUNOUS);
|
||||
ads111x_set_data_rate(&dev, ADS111X_DATA_RATE_32);
|
||||
|
||||
ads111x_set_input_mux(&dev, ADS111X_MUX_0_GND);
|
||||
ads111x_set_gain(&dev, GAIN);
|
||||
|
||||
float gain_val = ads111x_gain_values[GAIN];
|
||||
|
||||
while (true)
|
||||
{
|
||||
// wait for conversion end
|
||||
while (ads111x_busy(&dev)) {}
|
||||
|
||||
// Read result
|
||||
int16_t raw = ads111x_get_value(&dev);
|
||||
|
||||
float voltage = gain_val / ADS111X_MAX_VALUE * raw;
|
||||
|
||||
printf("Raw ADC value: %d, voltage: %.04f volts\n", raw, voltage);
|
||||
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
// this must be ahead of any mbedtls header files so the local mbedtls/config.h can be properly referenced
|
||||
#include "mbedtls/config.h"
|
||||
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
|
|
3
examples/bh1750/Makefile
Normal file
3
examples/bh1750/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=bh1750_example
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bh1750
|
||||
include ../../common.mk
|
44
examples/bh1750/bh1750_example.c
Normal file
44
examples/bh1750/bh1750_example.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "i2c/i2c.h"
|
||||
#include "bh1750/bh1750.h"
|
||||
|
||||
#define SCL_PIN 5
|
||||
#define SDA_PIN 4
|
||||
#define I2C_BUS 0
|
||||
|
||||
static void measure(void *pvParameters)
|
||||
{
|
||||
i2c_dev_t dev = {
|
||||
.addr = BH1750_ADDR_LO,
|
||||
.bus = I2C_BUS,
|
||||
};
|
||||
bh1750_configure(&dev, BH1750_CONTINUOUS_MODE | BH1750_HIGH_RES_MODE);
|
||||
|
||||
while (1) {
|
||||
while(1) {
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
printf("Lux: %d\n", bh1750_read(&dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_set_baud(0, 115200);
|
||||
|
||||
// Just some information
|
||||
printf("\n");
|
||||
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
||||
printf("GIT version : %s\n", GITSHORTREV);
|
||||
|
||||
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
xTaskCreate(measure, "measure_task", 256, NULL, 2, NULL);
|
||||
}
|
|
@ -17,13 +17,13 @@ const int freq_frc2 = 10;
|
|||
static volatile uint32_t frc1_count;
|
||||
static volatile uint32_t frc2_count;
|
||||
|
||||
void frc1_interrupt_handler(void)
|
||||
void frc1_interrupt_handler(void *arg)
|
||||
{
|
||||
frc1_count++;
|
||||
gpio_toggle(gpio_frc1);
|
||||
}
|
||||
|
||||
void frc2_interrupt_handler(void)
|
||||
void frc2_interrupt_handler(void *arg)
|
||||
{
|
||||
/* FRC2 needs the match register updated on each timer interrupt */
|
||||
timer_set_frequency(FRC2, freq_frc2);
|
||||
|
@ -47,8 +47,8 @@ void user_init(void)
|
|||
timer_set_run(FRC2, false);
|
||||
|
||||
/* set up ISRs */
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler, NULL);
|
||||
|
||||
/* configure timer frequencies */
|
||||
timer_set_frequency(FRC1, freq_frc1);
|
||||
|
|
46
examples/bme680/README.md
Normal file
46
examples/bme680/README.md
Normal file
|
@ -0,0 +1,46 @@
|
|||
# BME680 Driver Examples
|
||||
|
||||
These examples demonstrate the usage of the BME680 driver with only one and multiple BME680 sensors.
|
||||
|
||||
## Hardware setup
|
||||
|
||||
There are examples that are using either I2C or SPI with one or two sensors.
|
||||
|
||||
For examples using BME680 sensor as I2C slave, just use GPIO5 (SCL) and GPIO4 (SDA) to connect to the BME680 sensor's I2C interface.
|
||||
|
||||
```
|
||||
+-------------------------+ +--------+
|
||||
| ESP8266 Bus 0 | | BME680 |
|
||||
| GPIO 14 (SCL) ------> SCL |
|
||||
| GPIO 13 (SDA) <-----> SDA |
|
||||
| | +--------+
|
||||
+-------------------------+
|
||||
```
|
||||
|
||||
For examples that are using SPI, BME680 sensor has to be connected to SPI bus 1. Since GPIO15 used as default CS signal of SPI bus 1 does not work correctly together with BME680, you have to connect CS to another GPIO pin, e.g., GPIO2.
|
||||
|
||||
```
|
||||
+-------------------------+ +----------+
|
||||
| ESP8266 Bus 1 | | BME680 |
|
||||
| GPIO 14 (SCK) ------> SCK |
|
||||
| GPIO 13 (MOSI) ------> SDI |
|
||||
| GPIO 12 (MISO) <------ SDO |
|
||||
| GPIO 2 (CS) ------> CS |
|
||||
+-------------------------+ +----------+
|
||||
```
|
||||
|
||||
The example with two sensors use the combination of I2C and SPI.
|
||||
|
||||
## Example description
|
||||
|
||||
__*bme680_one_sensor*__
|
||||
|
||||
This simple example uses only **one sensor** connected either to **I2C** or to **SPI**. Which of these interfaces is used is defined by constant **SPI_USED**. The user task triggers a measurement every second and uses function ```vTaskDelay``` to wait for the measurement results.
|
||||
|
||||
__*bme680_two_sensors*__
|
||||
|
||||
This example uses **two sensors**. One sensor is connected to **I2C** bus 0 and one sensor is connected to **SPI**. It defines two different user tasks, one for each sensor. It demonstrate the possible approaches to wait for measurement results, active busy waiting using ```bme680_is_measuring``` and passive waiting using *vTaskDelay*.
|
||||
|
||||
__*bme680_heating_profiles*__
|
||||
|
||||
This simple example uses one **only sensor** connected to **I2C** bus 0 and a sequence of heating profiles. The heating profile is changed with each cycle.
|
3
examples/bme680/bme680_heating_profiles/Makefile
Normal file
3
examples/bme680/bme680_heating_profiles/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_heating_profiles
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* Simple example with one sensor connected to I2C bus 0 and a sequence of
|
||||
* heating profiles. The heating profile is changed with each cycle.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* I2C +-------------------------+ +----------+
|
||||
* | ESP8266 Bus 0 | | BME680 |
|
||||
* | GPIO 14 (SCL) ------> SCL |
|
||||
* | GPIO 13 (SDA) ------- SDA |
|
||||
* +-------------------------+ +----------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include communication interface driver
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// include BME680 driver
|
||||
#include "bme680/bme680.h"
|
||||
|
||||
// define I2C interface for BME680 sensors
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
|
||||
static bme680_sensor_t* sensor;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor every seconds. It uses
|
||||
* function *vTaskDelay* to wait for measurement results and changes the
|
||||
* heating profile in each cycle.
|
||||
*/
|
||||
void user_task(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (count++ < 60)
|
||||
// disable gas measurement for cycle counter < 60
|
||||
bme680_use_heater_profile (sensor, BME680_HEATER_NOT_USED);
|
||||
else
|
||||
// change heating profile in each cycle
|
||||
switch (count % 5)
|
||||
{
|
||||
case 0: bme680_use_heater_profile (sensor, 0); break;
|
||||
case 1: bme680_use_heater_profile (sensor, 1); break;
|
||||
case 2: bme680_use_heater_profile (sensor, 2); break;
|
||||
case 3: bme680_use_heater_profile (sensor, 3); break;
|
||||
case 4: bme680_use_heater_profile (sensor, 4); break;
|
||||
}
|
||||
|
||||
// measurement duration changes in each cycle
|
||||
uint32_t duration = bme680_get_measurement_duration(sensor);
|
||||
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor))
|
||||
{
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// get the results and do something with them
|
||||
if (bme680_get_results_float (sensor, &values))
|
||||
printf("%.3f BME680 Sensor: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
#ifdef SPI_USED
|
||||
// Init the sensor connected to SPI.
|
||||
sensor = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
#else
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init the sensor connected to I2C.
|
||||
sensor = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
#endif
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
/** -- SENSOR CONFIGURATION PART (optional) --- */
|
||||
|
||||
// Changes the oversampling rates to 4x oversampling for temperature
|
||||
// and 2x oversampling for humidity. Pressure measurement is skipped.
|
||||
bme680_set_oversampling_rates(sensor, osr_4x, osr_none, osr_2x);
|
||||
|
||||
// Change the IIR filter size for temperature and pressure to 7.
|
||||
bme680_set_filter_size(sensor, iir_size_7);
|
||||
|
||||
// Define a number of different heating profiles
|
||||
bme680_set_heater_profile (sensor, 0, 200, 100);
|
||||
bme680_set_heater_profile (sensor, 1, 250, 120);
|
||||
bme680_set_heater_profile (sensor, 2, 300, 140);
|
||||
bme680_set_heater_profile (sensor, 3, 350, 160);
|
||||
bme680_set_heater_profile (sensor, 4, 400, 180);
|
||||
|
||||
/** -- TASK CREATION PART --- */
|
||||
|
||||
// must be done last to avoid concurrency situations with the sensor
|
||||
// configuration part
|
||||
|
||||
// Create a task that uses the sensor
|
||||
xTaskCreate(user_task, "user_task", 256, NULL, 2, NULL);
|
||||
}
|
||||
else
|
||||
printf("Could not initialize BME680 sensor\n");
|
||||
}
|
3
examples/bme680/bme680_one_sensor/Makefile
Normal file
3
examples/bme680/bme680_one_sensor/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_One_Sensor
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
167
examples/bme680/bme680_one_sensor/bme680_one_sensor.c
Normal file
167
examples/bme680/bme680_one_sensor/bme680_one_sensor.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/**
|
||||
* Simple example with one sensor connected either to I2C bus 0 or
|
||||
* SPI bus 1.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* I2C
|
||||
*
|
||||
* +-----------------+ +----------+
|
||||
* | ESP8266 / ESP32 | | BME680 |
|
||||
* | | | |
|
||||
* | GPIO 14 (SCL) ----> SCL |
|
||||
* | GPIO 13 (SDA) <---> SDA |
|
||||
* +-----------------+ +----------+
|
||||
*
|
||||
* SPI
|
||||
*
|
||||
* +-----------------+ +----------+ +-----------------+ +----------+
|
||||
* | ESP8266 | | BME680 | | ESP32 | | BME680 |
|
||||
* | | | | | | | |
|
||||
* | GPIO 14 (SCK) ----> SCK | | GPIO 16 (SCK) ----> SCK |
|
||||
* | GPIO 13 (MOSI)----> SDI | | GPIO 17 (MOSI)----> SDI |
|
||||
* | GPIO 12 (MISO)<---- SDO | | GPIO 18 (MISO)<---- SDO |
|
||||
* | GPIO 2 (CS) ----> CS | | GPIO 19 (CS) ----> CS |
|
||||
* +-----------------+ +---------+ +-----------------+ +----------+
|
||||
*/
|
||||
|
||||
/* -- use following constants to define the example mode ----------- */
|
||||
|
||||
// #define SPI_USED
|
||||
|
||||
/* -- includes ----------------------------------------------------- */
|
||||
|
||||
#include "bme680.h"
|
||||
|
||||
/* -- platform dependent definitions ------------------------------- */
|
||||
|
||||
#ifdef ESP_PLATFORM // ESP32 (ESP-IDF)
|
||||
|
||||
// user task stack depth for ESP32
|
||||
#define TASK_STACK_DEPTH 2048
|
||||
|
||||
// SPI interface definitions for ESP32
|
||||
#define SPI_BUS HSPI_HOST
|
||||
#define SPI_SCK_GPIO 16
|
||||
#define SPI_MOSI_GPIO 17
|
||||
#define SPI_MISO_GPIO 18
|
||||
#define SPI_CS_GPIO 19
|
||||
|
||||
#else // ESP8266 (esp-open-rtos)
|
||||
|
||||
// user task stack depth for ESP8266
|
||||
#define TASK_STACK_DEPTH 256
|
||||
|
||||
// SPI interface definitions for ESP8266
|
||||
#define SPI_BUS 1
|
||||
#define SPI_SCK_GPIO 14
|
||||
#define SPI_MOSI_GPIO 13
|
||||
#define SPI_MISO_GPIO 12
|
||||
#define SPI_CS_GPIO 2 // GPIO 15, the default CS of SPI bus 1, can't be used
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
// I2C interface defintions for ESP32 and ESP8266
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
#define I2C_FREQ I2C_FREQ_100K
|
||||
|
||||
/* -- user tasks --------------------------------------------------- */
|
||||
|
||||
static bme680_sensor_t* sensor = 0;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor every seconds. It uses
|
||||
* function *vTaskDelay* to wait for measurement results. Busy wating
|
||||
* alternative is shown in comments
|
||||
*/
|
||||
void user_task(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
// as long as sensor configuration isn't changed, duration is constant
|
||||
uint32_t duration = bme680_get_measurement_duration(sensor);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor))
|
||||
{
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// alternatively: busy waiting until measurement results are available
|
||||
// while (bme680_is_measuring (sensor)) ;
|
||||
|
||||
// get the results and do something with them
|
||||
if (bme680_get_results_float (sensor, &values))
|
||||
printf("%.3f BME680 Sensor: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- main program ------------------------------------------------- */
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter.
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
vTaskDelay(1);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
#ifdef SPI_USED
|
||||
|
||||
spi_bus_init (SPI_BUS, SPI_SCK_GPIO, SPI_MISO_GPIO, SPI_MOSI_GPIO);
|
||||
|
||||
// init the sensor connected to SPI_BUS with SPI_CS_GPIO as chip select.
|
||||
sensor = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
|
||||
#else // I2C
|
||||
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ);
|
||||
|
||||
// init the sensor with slave address BME680_I2C_ADDRESS_2 connected to I2C_BUS.
|
||||
sensor = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
|
||||
#endif // SPI_USED
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
/** -- SENSOR CONFIGURATION PART (optional) --- */
|
||||
|
||||
// Changes the oversampling rates to 4x oversampling for temperature
|
||||
// and 2x oversampling for humidity. Pressure measurement is skipped.
|
||||
bme680_set_oversampling_rates(sensor, osr_4x, osr_none, osr_2x);
|
||||
|
||||
// Change the IIR filter size for temperature and pressure to 7.
|
||||
bme680_set_filter_size(sensor, iir_size_7);
|
||||
|
||||
// Change the heater profile 0 to 200 degree Celcius for 100 ms.
|
||||
bme680_set_heater_profile (sensor, 0, 200, 100);
|
||||
bme680_use_heater_profile (sensor, 0);
|
||||
|
||||
// Set ambient temperature to 10 degree Celsius
|
||||
bme680_set_ambient_temperature (sensor, 10);
|
||||
|
||||
/** -- TASK CREATION PART --- */
|
||||
|
||||
// must be done last to avoid concurrency situations with the sensor
|
||||
// configuration part
|
||||
|
||||
// Create a task that uses the sensor
|
||||
xTaskCreate(user_task, "user_task", TASK_STACK_DEPTH, NULL, 2, NULL);
|
||||
}
|
||||
else
|
||||
printf("Could not initialize BME680 sensor\n");
|
||||
}
|
3
examples/bme680/bme680_two_sensors/Makefile
Normal file
3
examples/bme680/bme680_two_sensors/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_Tow_Sensors
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
158
examples/bme680/bme680_two_sensors/bme680_two_sensors.c
Normal file
158
examples/bme680/bme680_two_sensors/bme680_two_sensors.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* Simple example with two sensors, one sensor connected to I2C bus 0 and
|
||||
* one sensor connected to SPI. It defines two different user tasks, one for
|
||||
* each sensor. It demonstrates the possible approaches to wait for measurement
|
||||
* results, active busy waiting using ```bme680_is_measuring``` and passive
|
||||
* waiting using *vTaskDelay*.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* +-------------------------+ +----------+
|
||||
* | ESP8266 I2C Bus 1 | | BME680_1 |
|
||||
* | GPIO 5 (SCL) ------> SCL |
|
||||
* | GPIO 4 (SDA) <-----> SDA |
|
||||
* | | +----------+
|
||||
* | SPI Bus 1 | | BME680_2 |
|
||||
* | GPIO 14 (SCK) >-----> SCK |
|
||||
* | GPIO 13 (MOSI) >-----> SDI |
|
||||
* | GPIO 12 (MISO) <------ SDO |
|
||||
* | GPIO 2 (CS) >-----> CS |
|
||||
* +-------------------------+ +----------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include communication interface driver
|
||||
#include "esp/spi.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// include BME680 driver
|
||||
#include "bme680/bme680.h"
|
||||
|
||||
// define I2C interface for BME680 sensor 1
|
||||
#define SPI_BUS 1
|
||||
#define SPI_CS_GPIO 2 // GPIO 15, the default CS of SPI bus 1, can't be used
|
||||
// define SPI interface for BME680 sensor 2
|
||||
#define I2C_BUS 1
|
||||
#define I2C_SCL_PIN 5
|
||||
#define I2C_SDA_PIN 4
|
||||
|
||||
static bme680_sensor_t* sensor1;
|
||||
static bme680_sensor_t* sensor2;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor1 every 5 seconds and
|
||||
* uses *vTaskDelay* to wait for measurement results.
|
||||
*/
|
||||
void user_task_sensor1(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
uint32_t duration = bme680_get_measurement_duration (sensor1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor1))
|
||||
{
|
||||
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// get the results and so something with them
|
||||
if (bme680_get_results_float (sensor1, &values))
|
||||
printf("%.3f BME680 Sensor1: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
|
||||
// passive waiting until 5 seconds are over
|
||||
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor1 every 2 seconds and
|
||||
* uses *bme680_is_measuring* to wait for measurement results.
|
||||
*/
|
||||
void user_task_sensor2(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor2))
|
||||
{
|
||||
// busy waiting until measurement results are available
|
||||
while (bme680_is_measuring (sensor2)) ;
|
||||
|
||||
// get the results and so something with them
|
||||
if (bme680_get_results_float (sensor2, &values))
|
||||
printf("%.3f BME680 Sensor2: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
|
||||
// passive waiting until 2 seconds are over
|
||||
vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init the sensors
|
||||
sensor1 = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
sensor2 = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
|
||||
if (sensor1 && sensor2)
|
||||
{
|
||||
/** -- SENSOR CONFIGURATION PART (optional) --- */
|
||||
|
||||
// Changes the oversampling rates for both sensor to different values
|
||||
bme680_set_oversampling_rates(sensor1, osr_4x, osr_2x, osr_1x);
|
||||
bme680_set_oversampling_rates(sensor2, osr_8x, osr_8x, osr_8x);
|
||||
|
||||
// Change the IIR filter size for temperature and and pressure to 7.
|
||||
bme680_set_filter_size(sensor1, iir_size_7);
|
||||
bme680_set_filter_size(sensor2, iir_size_7);
|
||||
|
||||
// Change the heater profile 0 to 200 degree Celcius for 150 ms.
|
||||
bme680_set_heater_profile (sensor1, 0, 200, 150);
|
||||
bme680_set_heater_profile (sensor2, 0, 200, 150);
|
||||
|
||||
// Activate the heater profile 0
|
||||
bme680_use_heater_profile (sensor1, 0);
|
||||
bme680_use_heater_profile (sensor2, 0);
|
||||
|
||||
/** -- TASK CREATION PART --- */
|
||||
|
||||
// must be done last to avoid concurrency situations with the sensor
|
||||
// configuration part
|
||||
|
||||
// Create the tasks that use the sensors
|
||||
xTaskCreate(user_task_sensor1, "user_task_sensor1", 256, NULL, 2, 0);
|
||||
xTaskCreate(user_task_sensor2, "user_task_sensor2", 256, NULL, 2, 0);
|
||||
}
|
||||
}
|
|
@ -13,18 +13,25 @@
|
|||
// BMP180 driver
|
||||
#include "bmp180/bmp180.h"
|
||||
|
||||
#define MY_EVT_TIMER 0x01
|
||||
#define MY_EVT_BMP180 0x02
|
||||
|
||||
#define I2C_BUS 0
|
||||
#define SCL_PIN GPIO_ID_PIN((0))
|
||||
#define SDA_PIN GPIO_ID_PIN((2))
|
||||
|
||||
#define MY_EVT_TIMER 0x01
|
||||
#define MY_EVT_BMP180 0x02
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t event_type;
|
||||
bmp180_result_t bmp180_data;
|
||||
} my_event_t;
|
||||
|
||||
//device descriptor
|
||||
i2c_dev_t dev = {
|
||||
.addr = BMP180_DEVICE_ADDRESS,
|
||||
.bus = I2C_BUS,
|
||||
};
|
||||
|
||||
// Communication Queue
|
||||
static QueueHandle_t mainqueue;
|
||||
static TimerHandle_t timerHandle;
|
||||
|
@ -70,7 +77,7 @@ void bmp180_task(void *pvParameters)
|
|||
case MY_EVT_TIMER:
|
||||
printf("%s: Received Timer Event\n", __FUNCTION__);
|
||||
|
||||
bmp180_trigger_measurement(com_queue);
|
||||
bmp180_trigger_measurement(&dev, com_queue);
|
||||
break;
|
||||
case MY_EVT_BMP180:
|
||||
printf("%s: Received BMP180 Event temp:=%d.%dC press=%d.%02dhPa\n", __FUNCTION__, \
|
||||
|
@ -91,6 +98,9 @@ void user_setup(void)
|
|||
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
// Init I2C bus Interface
|
||||
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);
|
||||
}
|
||||
|
||||
void user_init(void)
|
||||
|
@ -107,7 +117,7 @@ void user_init(void)
|
|||
bmp180_informUser = bmp180_i2c_informUser;
|
||||
|
||||
// Init BMP180 Interface
|
||||
bmp180_init(SCL_PIN, SDA_PIN);
|
||||
bmp180_init(&dev);
|
||||
|
||||
// Create Main Communication Queue
|
||||
mainqueue = xQueueCreate(10, sizeof(my_event_t));
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// In forced mode user initiate measurement each time.
|
||||
// In normal mode measurement is done continuously with specified standby time.
|
||||
// #define MODE_FORCED
|
||||
|
||||
const uint8_t i2c_bus = 0;
|
||||
const uint8_t scl_pin = 0;
|
||||
const uint8_t sda_pin = 2;
|
||||
|
||||
|
@ -26,7 +26,8 @@ static void bmp280_task_forced(void *pvParameters)
|
|||
params.mode = BMP280_MODE_FORCED;
|
||||
|
||||
bmp280_t bmp280_dev;
|
||||
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||
bmp280_dev.i2c_dev.bus = i2c_bus;
|
||||
bmp280_dev.i2c_dev.addr = BMP280_I2C_ADDRESS_0;
|
||||
|
||||
while (1) {
|
||||
while (!bmp280_init(&bmp280_dev, ¶ms)) {
|
||||
|
@ -67,7 +68,8 @@ static void bmp280_task_normal(void *pvParameters)
|
|||
bmp280_init_default_params(¶ms);
|
||||
|
||||
bmp280_t bmp280_dev;
|
||||
bmp280_dev.i2c_addr = BMP280_I2C_ADDRESS_0;
|
||||
bmp280_dev.i2c_dev.bus = i2c_bus;
|
||||
bmp280_dev.i2c_dev.addr = BMP280_I2C_ADDRESS_0;
|
||||
|
||||
while (1) {
|
||||
while (!bmp280_init(&bmp280_dev, ¶ms)) {
|
||||
|
@ -103,7 +105,7 @@ void user_init(void)
|
|||
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
||||
printf("GIT version : %s\n", GITSHORTREV);
|
||||
|
||||
i2c_init(scl_pin, sda_pin);
|
||||
i2c_init(i2c_bus, scl_pin, sda_pin, I2C_FREQ_400K);
|
||||
|
||||
#ifdef MODE_FORCED
|
||||
xTaskCreate(bmp280_task_forced, "bmp280_task", 256, NULL, 2, NULL);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
const int gpio = 0; /* gpio 0 usually has "PROGRAM" button attached */
|
||||
const int active = 0; /* active == 0 for active low */
|
||||
const gpio_inttype_t int_type = GPIO_INTTYPE_EDGE_NEG;
|
||||
#define GPIO_HANDLER gpio00_interrupt_handler
|
||||
|
||||
|
||||
/* This task polls for the button and prints the tick
|
||||
|
@ -39,6 +38,8 @@ void buttonPollTask(void *pvParameters)
|
|||
}
|
||||
}
|
||||
|
||||
void gpio_intr_handler(uint8_t gpio_num);
|
||||
|
||||
/* This task configures the GPIO interrupt and uses it to tell
|
||||
when the button is pressed.
|
||||
|
||||
|
@ -51,7 +52,7 @@ void buttonIntTask(void *pvParameters)
|
|||
{
|
||||
printf("Waiting for button press interrupt on gpio %d...\r\n", gpio);
|
||||
QueueHandle_t *tsqueue = (QueueHandle_t *)pvParameters;
|
||||
gpio_set_interrupt(gpio, int_type);
|
||||
gpio_set_interrupt(gpio, int_type, gpio_intr_handler);
|
||||
|
||||
uint32_t last = 0;
|
||||
while(1) {
|
||||
|
@ -67,7 +68,7 @@ void buttonIntTask(void *pvParameters)
|
|||
|
||||
static QueueHandle_t tsqueue;
|
||||
|
||||
void GPIO_HANDLER(void)
|
||||
void gpio_intr_handler(uint8_t gpio_num)
|
||||
{
|
||||
uint32_t now = xTaskGetTickCountFromISR();
|
||||
xQueueSendToBackFromISR(tsqueue, &now, NULL);
|
||||
|
|
57
examples/ccs811/README.md
Normal file
57
examples/ccs811/README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# CCS811 Driver Examples
|
||||
|
||||
These examples demonstrate the usage of the CCS811 driver with only one sensors.
|
||||
|
||||
## Hardware setup
|
||||
|
||||
Most examples use only one CCS811 sensor. Following figure shows the hardware configuration if no interrupt is used.
|
||||
|
||||
```
|
||||
+------------------------+ +--------+
|
||||
| ESP8266 Bus 0 | | CCS811 |
|
||||
| GPIO 5 (SCL) -----> SCL |
|
||||
| GPIO 4 (SDA) <----> SDA |
|
||||
| GND -----> /WAKE |
|
||||
+------------------------+ +--------+
|
||||
```
|
||||
|
||||
If *nINT* interrupt is used to fetch new data, additionally the interrupt pin has to be connected to a GPIO pin.
|
||||
|
||||
```
|
||||
+------------------------+ +--------+
|
||||
| ESP8266 Bus 0 | | CCS811 |
|
||||
| GPIO 5 (SCL) -----> SCL |
|
||||
| GPIO 4 (SDA) <----> SDA |
|
||||
| GPIO 2 <----- /nINT |
|
||||
| GND -----> /WAKE |
|
||||
+------------------------+ +--------+
|
||||
```
|
||||
|
||||
In examples where CCS811 sensor is used in conjunction with a SHT3x sensor, the hardware configuration looks like following:
|
||||
|
||||
```
|
||||
+------------------------+ +--------+
|
||||
| ESP8266 Bus 0 | | CCS811 |
|
||||
| GPIO 5 (SCL) ---+----> SCL |
|
||||
| GPIO 4 (SDA) <--|-+--> SDA |
|
||||
| GND ---|-|--> /WAKE |
|
||||
| | | | +--------+
|
||||
| | | | | SHT3x |
|
||||
| | +----> SCL |
|
||||
| | +--> SDA |
|
||||
+------------------------+ +--------+
|
||||
```
|
||||
|
||||
## Example description
|
||||
|
||||
__*ccs811_one_sensor*__
|
||||
|
||||
Simple example with one CCS811 sensor connected to I2C bus 0. It demonstrates the different approaches to fetch the data. Either the interrupt *nINT* is used when new data are available or exceed defined thresholds or the new data are fetched periodically. Which approach is used is defined by the constants ```INT_DATA_RDY_USED``` and ```INT_THRESHOLD_USED```.
|
||||
|
||||
__*ccs811_plus_sht3x*__
|
||||
|
||||
Simple example with one CCS811 sensor connected to I2C bus 0 and one SHT3x sensor to determine ambient temperature. New data are fetched peridically every 2 seconds.
|
||||
|
||||
__*ccs811_temperature*__
|
||||
|
||||
Simple example with one CCS811 sensor connected to I2C bus 0. It demonstrates how to use CCS811 with an external NTC resistor to determine ambient temperature.
|
4
examples/ccs811/ccs811_one_sensor/Makefile
Normal file
4
examples/ccs811/ccs811_one_sensor/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROGRAM=CCS811_One_Sensor
|
||||
EXTRA_COMPONENTS = extras/i2c extras/ccs811
|
||||
include ../../../common.mk
|
||||
|
180
examples/ccs811/ccs811_one_sensor/ccs811_one_sensor.c
Normal file
180
examples/ccs811/ccs811_one_sensor/ccs811_one_sensor.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* Simple example with one sensor connected to I2C bus 0. It demonstrates the
|
||||
* different approaches to fetch the data. Either the interrupt *nINT* is used
|
||||
* whenever new data are available or exceed defined thresholds or the new
|
||||
* data are fetched periodically.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* +-----------------+ +----------+
|
||||
* | ESP8266 / ESP32 | | CCS811 |
|
||||
* | | | |
|
||||
* | GPIO 14 (SCL) ----> SCL |
|
||||
* | GPIO 13 (SDA) <---> SDA |
|
||||
* | GPIO 5 <---- INT1 |
|
||||
* | GND ----> /WAKE |
|
||||
* +-----------------+ +----------+
|
||||
*/
|
||||
|
||||
/* -- use following constants to define the example mode ----------- */
|
||||
|
||||
// #define INT_DATA_RDY_USED
|
||||
// #define INT_THRESHOLD_USED
|
||||
|
||||
#if defined(INT_DATA_RDY_USED) || defined(INT_THRESHOLD_USED)
|
||||
#define INT_USED
|
||||
#endif
|
||||
|
||||
/* -- includes ----------------------------------------------------- */
|
||||
|
||||
#include "ccs811.h"
|
||||
|
||||
/* -- platform dependent definitions ------------------------------- */
|
||||
|
||||
#ifdef ESP_PLATFORM // ESP32 (ESP-IDF)
|
||||
|
||||
// user task stack depth for ESP32
|
||||
#define TASK_STACK_DEPTH 2048
|
||||
|
||||
#else // ESP8266 (esp-open-rtos)
|
||||
|
||||
// user task stack depth for ESP8266
|
||||
#define TASK_STACK_DEPTH 256
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
// I2C interface defintions for ESP32 and ESP8266
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
#define I2C_FREQ I2C_FREQ_100K
|
||||
|
||||
// interrupt GPIOs defintions for ESP8266 and ESP32
|
||||
#define nINT_PIN 13
|
||||
|
||||
/* -- user tasks --------------------------------------------------- */
|
||||
|
||||
static ccs811_sensor_t* sensor;
|
||||
|
||||
#ifdef INT_USED
|
||||
/**
|
||||
* In this example, the interrupt *nINT* is used. It is triggered every time
|
||||
* new data are available (INT_DATA_RDY_USED) or exceed defined thresholds
|
||||
* (INT_THRESHOLD_USED). In this case, the user has to define an interrupt
|
||||
* handler that fetches the data directly or triggers a task, that is waiting
|
||||
* to fetch the data. In this example, a task is defined which suspends itself
|
||||
* in each cycle to wait for fetching the data. The task is resumed by the
|
||||
* the interrupt handler.
|
||||
*/
|
||||
|
||||
TaskHandle_t nINT_task;
|
||||
|
||||
// User task that fetches the sensor values.
|
||||
|
||||
void user_task_interrupt (void *pvParameters)
|
||||
{
|
||||
uint16_t tvoc;
|
||||
uint16_t eco2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// task suspends itself and waits to be resumed by interrupt handler
|
||||
vTaskSuspend (NULL);
|
||||
|
||||
// after resume get the results and do something with them
|
||||
if (ccs811_get_results (sensor, &tvoc, &eco2, 0, 0))
|
||||
printf("%.3f CCS811 Sensor interrupt: TVOC %d ppb, eCO2 %d ppm\n",
|
||||
(double)sdk_system_get_time()*1e-3, tvoc, eco2);
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt handler which resumes user_task_interrupt on interrupt
|
||||
|
||||
static void IRAM nINT_handler(uint8_t gpio)
|
||||
{
|
||||
xTaskResumeFromISR (nINT_task);
|
||||
}
|
||||
|
||||
#else // !INT_USED
|
||||
|
||||
/*
|
||||
* In this example, user task fetches the sensor values every seconds.
|
||||
*/
|
||||
|
||||
void user_task_periodic(void *pvParameters)
|
||||
{
|
||||
uint16_t tvoc;
|
||||
uint16_t eco2;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// get environmental data from another sensor and set them
|
||||
// ccs811_set_environmental_data (sensor, 25.3, 47.8);
|
||||
|
||||
// get the results and do something with them
|
||||
if (ccs811_get_results (sensor, &tvoc, &eco2, 0, 0))
|
||||
printf("%.3f CCS811 Sensor periodic: TVOC %d ppb, eCO2 %d ppm\n",
|
||||
(double)sdk_system_get_time()*1e-3, tvoc, eco2);
|
||||
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INT_USED
|
||||
|
||||
/* -- main program ------------------------------------------------- */
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter.
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
vTaskDelay(1);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
// init all I2C bus interfaces at which CCS811 sensors are connected
|
||||
i2c_init (I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ);
|
||||
|
||||
// longer clock stretching is required for CCS811
|
||||
i2c_set_clock_stretch (I2C_BUS, CCS811_I2C_CLOCK_STRETCH);
|
||||
|
||||
// init the sensor with slave address CCS811_I2C_ADDRESS_1 connected I2C_BUS.
|
||||
sensor = ccs811_init_sensor (I2C_BUS, CCS811_I2C_ADDRESS_1);
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
#if !defined (INT_USED)
|
||||
|
||||
// create a periodic task that uses the sensor
|
||||
xTaskCreate(user_task_periodic, "user_task_periodic", TASK_STACK_DEPTH, NULL, 2, NULL);
|
||||
|
||||
#else // INT_USED
|
||||
|
||||
// create a task that is resumed by interrupt handler to use the sensor
|
||||
xTaskCreate(user_task_interrupt, "user_task_interrupt", TASK_STACK_DEPTH, NULL, 2, &nINT_task);
|
||||
|
||||
// activate the interrupt for nINT_PIN and set the interrupt handler
|
||||
gpio_enable(nINT_PIN, GPIO_INPUT);
|
||||
gpio_set_interrupt(nINT_PIN, GPIO_INTTYPE_EDGE_NEG, nINT_handler);
|
||||
|
||||
#ifdef INT_DATA_RDY_USED
|
||||
// enable the data ready interrupt
|
||||
ccs811_enable_interrupt (sensor, true);
|
||||
#else // INT_THRESHOLD_USED
|
||||
// set threshold parameters and enable threshold interrupt mode
|
||||
ccs811_set_eco2_thresholds (sensor, 600, 1100, 40);
|
||||
#endif
|
||||
|
||||
#endif // !defined(INT_USED)
|
||||
|
||||
// start periodic measurement with one measurement per second
|
||||
ccs811_set_mode (sensor, ccs811_mode_1s);
|
||||
}
|
||||
else
|
||||
printf("Could not initialize the CCS811 sensor\n");
|
||||
}
|
||||
|
3
examples/ccs811/ccs811_plus_sht3x/Makefile
Normal file
3
examples/ccs811/ccs811_plus_sht3x/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=CCS811_Plus_SHT3x
|
||||
EXTRA_COMPONENTS = extras/i2c extras/ccs811 extras/sht3x
|
||||
include ../../../common.mk
|
106
examples/ccs811/ccs811_plus_sht3x/ccs811_plus_sht3x.c
Normal file
106
examples/ccs811/ccs811_plus_sht3x/ccs811_plus_sht3x.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Simple example with one CCS811 sensor connected to I2C bus 0 and one SHT3x
|
||||
* sensor to determine ambient temperature. New data are fetched peridically.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* +------------------------+ +--------+
|
||||
* | ESP8266 Bus 0 | | CCS811 |
|
||||
* | GPIO 14 (SCL) ---+----> SCL |
|
||||
* | GPIO 13 (SDA) <--|-+--> SDA |
|
||||
* | GND ---|-|--> /WAKE |
|
||||
* | | | | +--------+
|
||||
* | | | | | SHT3x |
|
||||
* | | +----> SCL |
|
||||
* | | +--> SDA |
|
||||
* +------------------------+ +--------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include <task.h>
|
||||
|
||||
// include CCS811 driver
|
||||
#include "ccs811/ccs811.h"
|
||||
|
||||
// include SHT3x driver
|
||||
#include "sht3x/sht3x.h"
|
||||
|
||||
// define I2C interfaces at which CCS811 and SHT3x sensors are connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
|
||||
static ccs811_sensor_t* ccs811; // CCS811 device data structure
|
||||
static sht3x_sensor_t* sht3x; // SHT3x device data structure
|
||||
|
||||
/*
|
||||
* User task that fetches the sensor values every 2 seconds.
|
||||
*/
|
||||
void user_task(void *pvParameters)
|
||||
{
|
||||
uint16_t tvoc;
|
||||
uint16_t eco2;
|
||||
|
||||
float temperature;
|
||||
float humidity;
|
||||
|
||||
// start periodic measurement with 1 measurement per second
|
||||
ccs811_set_mode (ccs811, ccs811_mode_1s);
|
||||
|
||||
// start periodic measurements with 1 measurement per second
|
||||
sht3x_start_measurement (sht3x, sht3x_periodic_1mps, sht3x_high);
|
||||
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (sht3x_get_measurement_duration (sht3x_high));
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// get the results from CCS811 and do something with them
|
||||
if (ccs811_get_results (ccs811, &tvoc, &eco2, 0, 0))
|
||||
printf("%.3f CCS811 Sensor periodic: TVOC %d ppb, eCO2 %d ppm\n",
|
||||
(double)sdk_system_get_time()*1e-3, tvoc, eco2);
|
||||
|
||||
// get the values from SHT3x and do something with them
|
||||
if (sht3x_get_results (sht3x, &temperature, &humidity))
|
||||
{
|
||||
printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n",
|
||||
(double)sdk_system_get_time()*1e-3, temperature, humidity);
|
||||
|
||||
// set CCS811 environmental data with values fetched from SHT3x
|
||||
ccs811_set_environmental_data (ccs811, temperature, humidity);
|
||||
}
|
||||
// passive waiting until 2 seconds is over
|
||||
vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
// init all I2C bus interfaces at which CCS811 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// longer clock stretching is required for CCS811
|
||||
i2c_set_clock_stretch (I2C_BUS, CCS811_I2C_CLOCK_STRETCH);
|
||||
|
||||
// init the sensors
|
||||
ccs811 = ccs811_init_sensor (I2C_BUS, CCS811_I2C_ADDRESS_1);
|
||||
sht3x = sht3x_init_sensor (I2C_BUS, SHT3x_ADDR_2);
|
||||
|
||||
if (ccs811 && sht3x)
|
||||
// create a task that uses the sensor
|
||||
xTaskCreate(user_task, "user_task", 256, NULL, 2, NULL);
|
||||
}
|
4
examples/ccs811/ccs811_temperature/Makefile
Normal file
4
examples/ccs811/ccs811_temperature/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROGRAM=CCS811_Temperature
|
||||
EXTRA_COMPONENTS = extras/i2c extras/ccs811
|
||||
LIBS ?= gcc hal m
|
||||
include ../../../common.mk
|
131
examples/ccs811/ccs811_temperature/ccs811_temperature.c
Normal file
131
examples/ccs811/ccs811_temperature/ccs811_temperature.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* Simple example with one sensor connected to I2C bus 0. It demonstrates
|
||||
* how to use CCS811 with an external NTC thermistor to determine ambient
|
||||
* temperature.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* +------------------------+ +--------+
|
||||
* | ESP8266 Bus 0 | | CCS811 |
|
||||
* | GPIO 14 (SCL) >----> SCL |
|
||||
* | GPIO 13 (SDA) <----> SDA |
|
||||
* | GND -----> /WAKE |
|
||||
* +------------------------+ +--------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include <task.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// include CCS811 driver
|
||||
#include "ccs811/ccs811.h"
|
||||
|
||||
// define I2C interfaces at which CCS811 sensors can be connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
|
||||
|
||||
static ccs811_sensor_t* sensor;
|
||||
|
||||
|
||||
/*
|
||||
* In this example, user task fetches the sensor values every seconds.
|
||||
*/
|
||||
|
||||
// parameters of the Adafruit CCS811 Air Quality Sensor Breakout
|
||||
#define CCS811_R_REF 100000
|
||||
#define CCS811_R_NTC 10000
|
||||
#define CCS811_R_NTC_TEMP 25
|
||||
#define CCS811_BCONSTANT 3380
|
||||
|
||||
void user_task_periodic(void *pvParameters)
|
||||
{
|
||||
uint16_t tvoc;
|
||||
uint16_t eco2;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// get environmental data from another sensor and set them
|
||||
// ccs811_set_environmental_data (sensor, 25.3, 47.8);
|
||||
|
||||
// get the results and do something with them
|
||||
if (ccs811_get_results (sensor, &tvoc, &eco2, 0, 0))
|
||||
printf("%.3f CCS811 Sensor periodic: TVOC %d ppb, eCO2 %d ppm\n",
|
||||
(double)sdk_system_get_time()*1e-3, tvoc, eco2);
|
||||
|
||||
// get NTC resistance
|
||||
uint32_t r_ntc = ccs811_get_ntc_resistance (sensor, CCS811_R_REF);
|
||||
|
||||
// calculation of temperature from application note ams AN000372
|
||||
double ntc_temp;
|
||||
ntc_temp = log((double)r_ntc / CCS811_R_NTC); // 1
|
||||
ntc_temp /= CCS811_BCONSTANT; // 2
|
||||
ntc_temp += 1.0 / (CCS811_R_NTC_TEMP + 273.15); // 3
|
||||
ntc_temp = 1.0 / ntc_temp; // 4
|
||||
ntc_temp -= 273.15; // 5
|
||||
|
||||
printf("%.3f CCS811 Sensor temperature: R_NTC %u Ohm, T %f °C\n",
|
||||
(double)sdk_system_get_time()*1e-3, r_ntc, ntc_temp);
|
||||
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
// init all I2C bus interfaces at which CCS811 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// longer clock stretching is required for CCS811
|
||||
i2c_set_clock_stretch (I2C_BUS, CCS811_I2C_CLOCK_STRETCH);
|
||||
|
||||
// init the sensor with slave address CCS811_I2C_ADDRESS_1 connected I2C_BUS.
|
||||
sensor = ccs811_init_sensor (I2C_BUS, CCS811_I2C_ADDRESS_1);
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
#if defined(INT_DATA_RDY_USED) || defined(INT_THRESHOLD_USED)
|
||||
|
||||
// create a task that is resumed by interrupt handler to use the sensor
|
||||
xTaskCreate(user_task_interrupt, "user_task_interrupt", 256, NULL, 2, &nINT_task);
|
||||
|
||||
// set the GPIO and interrupt handler for *nINT* interrupt
|
||||
gpio_set_interrupt(INT_GPIO, GPIO_INTTYPE_EDGE_NEG, nINT_handler);
|
||||
|
||||
#ifdef INT_DATA_RDY_USED
|
||||
// enable the data ready interrupt
|
||||
ccs811_enable_interrupt (sensor, true);
|
||||
#else
|
||||
// set threshold parameters and enable threshold interrupt mode
|
||||
ccs811_set_eco2_thresholds (sensor, 600, 1100, 40);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// create a periodic task that uses the sensor
|
||||
xTaskCreate(user_task_periodic, "user_task_periodic", 256, NULL, 2, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
// start periodic measurement with one measurement per second
|
||||
ccs811_set_mode (sensor, ccs811_mode_1s);
|
||||
}
|
||||
}
|
||||
|
3
examples/crc_example/Makefile
Normal file
3
examples/crc_example/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=crc_example
|
||||
EXTRA_COMPONENTS = extras/crc_generic
|
||||
include ../../common.mk
|
15
examples/crc_example/crc_config_perso.h
Normal file
15
examples/crc_example/crc_config_perso.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* perso_config.h
|
||||
*
|
||||
* Created on: 11 févr. 2017
|
||||
* Author: lilian
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#define CRC_DEBUG 0
|
||||
#define CRC_4BYTE_SUPPORT 0
|
||||
/* Use the defaults for everything else */
|
||||
#include_next "crc_config.h"
|
||||
|
25
examples/crc_example/crc_config_user.h
Normal file
25
examples/crc_example/crc_config_user.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* perso_config.h
|
||||
*
|
||||
* Created on: 11 févr. 2017
|
||||
* Author: lilian
|
||||
*/
|
||||
|
||||
#ifndef CRC_CONFIG_USER_H_
|
||||
#define CRC_CONFIG_USER_H_
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#define CRC_DEBUG 0
|
||||
#define CRC_1BYTE_SUPPORT 1
|
||||
#define CRC_4BYTE_SUPPORT 0
|
||||
#define CRC_8BYTE_SUPPORT 0
|
||||
|
||||
typedef uint8_t crc_8;
|
||||
typedef uint16_t crc_16;
|
||||
typedef uint32_t crc_32;
|
||||
typedef uint64_t crc_64;
|
||||
|
||||
#endif /* CRC_CONFIG_USER_H_ */
|
||||
|
139
examples/crc_example/crc_main.c
Normal file
139
examples/crc_example/crc_main.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Example code to test crc and speed
|
||||
*/
|
||||
/////////////////////////////////Lib
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "esp8266.h"
|
||||
#include <esp/hwrand.h>
|
||||
|
||||
//crc lib
|
||||
#include "crc_generic.h"
|
||||
|
||||
#define NUMBER_COMPUTE_TEST 1000
|
||||
|
||||
unsigned char check_data[] = { "123456789" };
|
||||
uint8_t tab_data[512];
|
||||
|
||||
void crc_8bit(void *pvParameters) {
|
||||
|
||||
config_crc_8 customcrc ; // my crc object
|
||||
crc_8 tabsrc[256]; // my crc look-up table
|
||||
|
||||
//init crc parameters (MAXIM parameters)
|
||||
crc_8_generic_init(&customcrc,0x31, 8, 0x00, 0x00, 1, 1, 1);
|
||||
|
||||
//generate table
|
||||
crc_8_generate_table(&customcrc, tabsrc, sizeof(tabsrc));
|
||||
|
||||
//show setting of crc
|
||||
printf("\nCRC library v1.0 written on 11/02/2017 by Zaltora\n");
|
||||
printf("-------------------------------------------------\n");
|
||||
printf("\n");
|
||||
printf("Parameters:\n");
|
||||
printf("\n");
|
||||
printf(" polynom : 0x%02X\n", customcrc.polynom);
|
||||
printf(" order : %d\n", customcrc.order);
|
||||
printf(" crcinit : 0x%02X direct, 0x%x nondirect\n", customcrc.private.crcinit_direct, customcrc.private.crcinit_nondirect);
|
||||
printf(" crcxor : 0x%02X\n", customcrc.crcxor);
|
||||
printf(" refin : %d\n", customcrc.refin);
|
||||
printf(" refout : %d\n", customcrc.refout);
|
||||
printf("\n");
|
||||
printf("check_data : '%s' (%d bytes)\n", check_data, sizeof(check_data));
|
||||
printf("\n");
|
||||
|
||||
//show table
|
||||
printf("Lookup table generated:\n");
|
||||
printf("\n");
|
||||
printf("tabsrc[256] = {");
|
||||
for (uint16_t i = 0 ; i < 256 ; i++)
|
||||
{
|
||||
if(!(i%8)) printf("\n");
|
||||
printf("0x%02X, ",tabsrc[i]);
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
printf("Check value results with all algorithms:\n");
|
||||
printf("\n");
|
||||
|
||||
//try different crc algorithm
|
||||
crc_8_generic_select_algo(&customcrc, tabsrc, sizeof(tabsrc), CRC_TABLE);
|
||||
printf("CRC_TABLE\t\t: 0x%02X\n", crc_8_generic_compute(&customcrc, check_data, sizeof(check_data)));
|
||||
crc_8_generic_select_algo(&customcrc, tabsrc, sizeof(tabsrc), CRC_TABLE_FAST);
|
||||
printf("CRC_TABLE_FAST\t\t: 0x%02X\n", crc_8_generic_compute(&customcrc, check_data, sizeof(check_data)));
|
||||
crc_8_generic_select_algo(&customcrc, NULL, 0, CRC_BIT_TO_BIT);
|
||||
printf("CRC_BIT_TO_BIT\t\t: 0x%02X\n", crc_8_generic_compute(&customcrc, check_data, sizeof(check_data)));
|
||||
crc_8_generic_select_algo(&customcrc, NULL, 0, CRC_BIT_TO_BIT_FAST);
|
||||
printf("CRC_BIT_TO_BIT_FAST\t: 0x%02X\n", crc_8_generic_compute(&customcrc, check_data, sizeof(check_data)));
|
||||
crc_8_generic_select_algo(&customcrc, crc_8_tab_MAXIM, sizeof(crc_8_tab_MAXIM), CRC_TABLE_FAST);
|
||||
printf("CRC_TABLE_BUILTIN\t: 0x%02X\n\n", crc_8_generic_compute(&customcrc, check_data, sizeof(check_data)));
|
||||
|
||||
printf("Test speed algorithms with random data:\n");
|
||||
printf("\n");
|
||||
|
||||
//data to process
|
||||
printf("%u bytes of DATA:",sizeof(tab_data));
|
||||
for (uint16_t i = 0 ; i < sizeof(tab_data) ; i++)
|
||||
{
|
||||
tab_data[i] = (uint8_t)hwrand();
|
||||
if(!(i%32)) printf("\n");
|
||||
printf("%02X",tab_data[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
const uint32_t cst = NUMBER_COMPUTE_TEST ;
|
||||
char algo_txt[30] ;
|
||||
uint32_t time = 0;
|
||||
uint8_t select = 0;
|
||||
uint8_t result = 0;
|
||||
for(select = 0; select < 5 ; select++)
|
||||
{
|
||||
switch(select){
|
||||
case 0:
|
||||
crc_8_generic_select_algo(&customcrc, NULL, 0, CRC_BIT_TO_BIT);
|
||||
sprintf(algo_txt,"CRC_BIT_TO_BIT");
|
||||
break;
|
||||
case 1:
|
||||
crc_8_generic_select_algo(&customcrc, NULL, 0, CRC_BIT_TO_BIT_FAST);
|
||||
sprintf(algo_txt,"CRC_BIT_TO_BIT_FAST");
|
||||
break;
|
||||
case 2:
|
||||
crc_8_generic_select_algo(&customcrc, tabsrc, sizeof(tabsrc), CRC_TABLE);
|
||||
sprintf(algo_txt,"CRC_TABLE");
|
||||
break;
|
||||
case 3:
|
||||
crc_8_generic_select_algo(&customcrc, tabsrc, sizeof(tabsrc), CRC_TABLE_FAST);
|
||||
sprintf(algo_txt,"CRC_TABLE_FAST");
|
||||
break;
|
||||
case 4:
|
||||
crc_8_generic_select_algo(&customcrc, crc_8_tab_MAXIM, sizeof(crc_8_tab_MAXIM), CRC_TABLE_FAST);
|
||||
sprintf(algo_txt,"CRC_TABLE_FAST_BUILTIN");
|
||||
break;
|
||||
}
|
||||
printf("test speed algorithm %s \n",algo_txt);
|
||||
time = sdk_system_get_time();
|
||||
for (uint32_t i = 0 ; i < cst ; i++)
|
||||
{
|
||||
result = crc_8_generic_compute(&customcrc, tab_data, sizeof(tab_data));
|
||||
}
|
||||
time = sdk_system_get_time()-time ;
|
||||
printf("Speed algorithm: %.3f us\n",(float)time/(float)cst);
|
||||
printf("Result algorithm: %02X\n\n",result);
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS) ;
|
||||
}
|
||||
}
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
sdk_system_update_cpu_freq(160);
|
||||
uart_set_baud(0, 115200);
|
||||
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||
printf("Start\n\n");
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS) ;
|
||||
xTaskCreate(crc_8bit, "crc_8bit", 512, NULL, 2, NULL);
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
#include <ds1307/ds1307.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define I2C_BUS 0
|
||||
#define SCL_PIN 5
|
||||
#define SDA_PIN 4
|
||||
|
||||
|
@ -19,8 +20,12 @@ void user_init(void)
|
|||
uart_set_baud(0, 115200);
|
||||
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||
|
||||
i2c_init(SCL_PIN, SDA_PIN);
|
||||
ds1307_start(true);
|
||||
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K);
|
||||
i2c_dev_t dev = {
|
||||
.addr = DS1307_ADDR,
|
||||
.bus = I2C_BUS,
|
||||
};
|
||||
ds1307_start(&dev, true);
|
||||
|
||||
// setup datetime: 2016-10-09 13:50:10
|
||||
struct tm time = {
|
||||
|
@ -31,11 +36,11 @@ void user_init(void)
|
|||
.tm_min = 50,
|
||||
.tm_sec = 10
|
||||
};
|
||||
ds1307_set_time(&time);
|
||||
ds1307_set_time(&dev, &time);
|
||||
|
||||
while (true)
|
||||
{
|
||||
ds1307_get_time(&time);
|
||||
ds1307_get_time(&dev, &time);
|
||||
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year, time.tm_mon + 1,
|
||||
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
|
||||
|
|
|
@ -12,15 +12,21 @@
|
|||
|
||||
#include "ds3231/ds3231.h"
|
||||
|
||||
#define ADDR DS3231_ADDR
|
||||
#define I2C_BUS 0
|
||||
|
||||
void task1(void *pvParameters)
|
||||
{
|
||||
struct tm time;
|
||||
float tempFloat;
|
||||
|
||||
i2c_dev_t dev = {
|
||||
.addr = ADDR,
|
||||
.bus = I2C_BUS,
|
||||
};
|
||||
while(1) {
|
||||
vTaskDelay(100);
|
||||
ds3231_getTime(&time);
|
||||
ds3231_getTempFloat(&tempFloat);
|
||||
ds3231_getTime(&dev, &time);
|
||||
ds3231_getTempFloat(&dev, &tempFloat);
|
||||
printf("TIME:%d:%d:%d, TEMPERATURE:%.2f DegC\r\n", time.tm_hour, time.tm_min, time.tm_sec, tempFloat);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +41,7 @@ void user_init(void)
|
|||
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
||||
printf("GIT version : %s\n", GITSHORTREV);
|
||||
|
||||
ds3231_Init(scl, sda);
|
||||
i2c_init(0, scl, sda, I2C_FREQ_400K);
|
||||
|
||||
xTaskCreate(task1, "tsk1", 256, NULL, 2, NULL);
|
||||
}
|
||||
|
|
4
examples/dsm_test/Makefile
Normal file
4
examples/dsm_test/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Simple makefile for simple example
|
||||
PROGRAM=dsm_test
|
||||
EXTRA_COMPONENTS = extras/dsm
|
||||
include ../../common.mk
|
67
examples/dsm_test/dsm_test.c
Normal file
67
examples/dsm_test/dsm_test.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* Very basic example to test the dsm library
|
||||
* Led intensity from module will change over time.
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2018 zaltora (https://github.com/Zaltora)
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "dsm.h"
|
||||
|
||||
#define TEST_WITH_160MHZ (0)
|
||||
#define DSM_PIN (2)
|
||||
|
||||
void task1(void *pvParameters)
|
||||
{
|
||||
uint32_t const init_count = 0;
|
||||
uint32_t count = init_count;
|
||||
while(1)
|
||||
{
|
||||
vTaskDelay(100/portTICK_PERIOD_MS);
|
||||
printf("Target set to %3u, ", count);
|
||||
//Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128)
|
||||
//Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256)
|
||||
if (count < 128)
|
||||
{
|
||||
printf("Freqency: %.1f Hz\r\n", (80000000.0/255.0 * (count/ 256.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Freqency: %.1f Hz\r\n", 80000000.0/255.0 * ((256.0-count)/ 256.0));
|
||||
}
|
||||
dsm_set_target(count);
|
||||
count++;
|
||||
if (count > UINT8_MAX)
|
||||
count = init_count;
|
||||
}
|
||||
}
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uint8_t pins[1];
|
||||
uart_set_baud(0, 115200);
|
||||
|
||||
#if (TEST_WITH_160MHZ)
|
||||
sdk_system_update_cpu_freq(160);
|
||||
#endif
|
||||
|
||||
printf("SDK version:%s\r\n", sdk_system_get_sdk_version());
|
||||
|
||||
pins[0] = DSM_PIN;
|
||||
|
||||
/* register pin to use with DSM */
|
||||
dsm_init(1, pins);
|
||||
/* Set prescale to FF to get a proper signal */
|
||||
dsm_set_prescale(0xFF);
|
||||
/* Target initial */
|
||||
dsm_set_target(0);
|
||||
/* start dsm to pin */
|
||||
dsm_start();
|
||||
|
||||
printf("dsm start\r\n");
|
||||
|
||||
xTaskCreate(task1, "tsk1", 256, NULL, 2, NULL);
|
||||
}
|
11
examples/esphttpd/FreeRTOSConfig.h
Normal file
11
examples/esphttpd/FreeRTOSConfig.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* FreeRTOSConfig overrides.
|
||||
|
||||
This is intended as an example of overriding some of the default FreeRTOSConfig settings,
|
||||
which are otherwise found in FreeRTOS/Source/include/FreeRTOSConfig.h
|
||||
*/
|
||||
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
|
||||
/* Use the defaults for everything else */
|
||||
#include_next<FreeRTOSConfig.h>
|
||||
|
16
examples/esphttpd/Makefile
Normal file
16
examples/esphttpd/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
PROGRAM = esphttpd
|
||||
EXTRA_COMPONENTS = extras/dhcpserver extras/rboot-ota extras/libesphttpd
|
||||
|
||||
ESP_IP ?= 192.168.4.1
|
||||
|
||||
#Tag for OTA images. 0-27 characters. Change to eg your projects title.
|
||||
LIBESPHTTPD_OTA_TAGNAME ?= generic
|
||||
|
||||
LIBESPHTTPD_MAX_CONNECTIONS ?= 8
|
||||
LIBESPHTTPD_STACKSIZE ?= 2048
|
||||
|
||||
PROGRAM_CFLAGS += -DFREERTOS -DLIBESPHTTPD_OTA_TAGNAME="\"$(LIBESPHTTPD_OTA_TAGNAME)\"" -DFLASH_SIZE=$(FLASH_SIZE)
|
||||
EXTRA_CFLAGS += -DMEMP_NUM_NETCONN=$(LIBESPHTTPD_MAX_CONNECTIONS)
|
||||
|
||||
include ../../common.mk
|
||||
|
90
examples/esphttpd/cgi-test.c
Normal file
90
examples/esphttpd/cgi-test.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Cgi routines as used by the tests in the html/test subdirectory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
|
||||
* this notice you can do whatever you want with this stuff. If we meet some day,
|
||||
* and you think this stuff is worth it, you can buy me a beer in return.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <espressif/esp_common.h>
|
||||
|
||||
#include "cgi-test.h"
|
||||
|
||||
typedef struct {
|
||||
int len;
|
||||
int sendPos;
|
||||
} TestbedState;
|
||||
|
||||
|
||||
int ICACHE_FLASH_ATTR cgiTestbed(HttpdConnData *connData) {
|
||||
char buff[1024];
|
||||
int first=0;
|
||||
int l, x;
|
||||
TestbedState *state=(TestbedState*)connData->cgiData;
|
||||
|
||||
if (connData->conn==NULL) {
|
||||
//Connection aborted. Clean up.
|
||||
if (state) free(state);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
if (state==NULL) {
|
||||
//First call
|
||||
state=malloc(sizeof(TestbedState));
|
||||
memset(state, 0, sizeof(state));
|
||||
connData->cgiData=state;
|
||||
first=1;
|
||||
}
|
||||
|
||||
if (connData->requestType==HTTPD_METHOD_GET) {
|
||||
if (first) {
|
||||
httpdStartResponse(connData, 200);
|
||||
httpdHeader(connData, "content-type", "application/data");
|
||||
httpdEndHeaders(connData);
|
||||
l=httpdFindArg(connData->getArgs, "len", buff, sizeof(buff));
|
||||
state->len=1024;
|
||||
if (l!=-1) state->len=atoi(buff);
|
||||
state->sendPos=0;
|
||||
return HTTPD_CGI_MORE;
|
||||
} else {
|
||||
l=sizeof(buff);
|
||||
if (l>(state->len-state->sendPos)) l=(state->len-state->sendPos);
|
||||
//Fill with semi-random data
|
||||
for (x=0; x<l; x++) buff[x]=((x^(state->sendPos>>10))&0x1F)+'0';
|
||||
httpdSend(connData, buff, l);
|
||||
state->sendPos+=l;
|
||||
printf("Test: Uploaded %d/%d bytes\n", state->sendPos, state->len);
|
||||
if (state->len<=state->sendPos) {
|
||||
if (state) free(state);
|
||||
return HTTPD_CGI_DONE;
|
||||
} else {
|
||||
return HTTPD_CGI_MORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connData->requestType==HTTPD_METHOD_POST) {
|
||||
if (connData->post->len!=connData->post->received) {
|
||||
//Still receiving data. Ignore this.
|
||||
printf("Test: got %d/%d bytes\n", connData->post->received, connData->post->len);
|
||||
return HTTPD_CGI_MORE;
|
||||
} else {
|
||||
httpdStartResponse(connData, 200);
|
||||
httpdHeader(connData, "content-type", "text/plain");
|
||||
httpdEndHeaders(connData);
|
||||
l=sprintf(buff, "%d", connData->post->received);
|
||||
httpdSend(connData, buff, l);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
}
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
8
examples/esphttpd/cgi-test.h
Normal file
8
examples/esphttpd/cgi-test.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef CGI_TEST_H
|
||||
#define CGI_TEST_H
|
||||
|
||||
#include <libesphttpd/httpd.h>
|
||||
|
||||
int cgiTestbed(HttpdConnData *connData);
|
||||
|
||||
#endif
|
81
examples/esphttpd/cgi.c
Normal file
81
examples/esphttpd/cgi.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Some random cgi routines. Used in the LED example and the page that returns the entire
|
||||
flash as a binary. Also handles the hit counter on the main page.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
|
||||
* this notice you can do whatever you want with this stuff. If we meet some day,
|
||||
* and you think this stuff is worth it, you can buy me a beer in return.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <espressif/esp_common.h>
|
||||
|
||||
#include "cgi.h"
|
||||
#include "io.h"
|
||||
|
||||
|
||||
//cause I can't be bothered to write an ioGetLed()
|
||||
static char currLedState=0;
|
||||
|
||||
//Cgi that turns the LED on or off according to the 'led' param in the POST data
|
||||
int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
|
||||
int len;
|
||||
char buff[1024];
|
||||
|
||||
if (connData->conn==NULL) {
|
||||
//Connection aborted. Clean up.
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
len=httpdFindArg(connData->post->buff, "led", buff, sizeof(buff));
|
||||
if (len!=0) {
|
||||
currLedState=atoi(buff);
|
||||
ioLed(currLedState);
|
||||
}
|
||||
|
||||
httpdRedirect(connData, "led.tpl");
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Template code for the led page.
|
||||
int ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
|
||||
char buff[128];
|
||||
if (token==NULL) return HTTPD_CGI_DONE;
|
||||
|
||||
strcpy(buff, "Unknown");
|
||||
if (strcmp(token, "ledstate")==0) {
|
||||
if (currLedState) {
|
||||
strcpy(buff, "on");
|
||||
} else {
|
||||
strcpy(buff, "off");
|
||||
}
|
||||
}
|
||||
httpdSend(connData, buff, -1);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
static int hitCounter=0;
|
||||
|
||||
//Template code for the counter on the index page.
|
||||
int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) {
|
||||
char buff[128];
|
||||
if (token==NULL) return HTTPD_CGI_DONE;
|
||||
|
||||
if (strcmp(token, "counter")==0) {
|
||||
hitCounter++;
|
||||
sprintf(buff, "%d", hitCounter);
|
||||
}
|
||||
httpdSend(connData, buff, -1);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
10
examples/esphttpd/cgi.h
Normal file
10
examples/esphttpd/cgi.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef CGI_H
|
||||
#define CGI_H
|
||||
|
||||
#include <libesphttpd/httpd.h>
|
||||
|
||||
int cgiLed(HttpdConnData *connData);
|
||||
int tplLed(HttpdConnData *connData, char *token, void **arg);
|
||||
int tplCounter(HttpdConnData *connData, char *token, void **arg);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue