Compare commits

..

373 commits

Author SHA1 Message Date
Ruslan V. Uss
503e66a500
Merge pull request #760 from mjkillough/pca9685
Fix full on/off in pca9685.
2020-08-17 10:24:23 +05:00
Michael Killough
acfd46aa60 Fix full on/off in pca9685.
It's currently not possible to toggle between full off and full on, as
switching to full on leaves the full off control bit set. The full off
control bit takes precedence according to the datasheet, which means the
signal remains off.

The 'normal' branch does correctly clear full off/full on, as it writes
0s to the `LEDn_ON` registers unconditionally and writes 0 to the control
bit in `LEDn_OFF`.
2020-08-16 12:28:42 +01:00
Ruslan V. Uss
48e4132996
Merge pull request #747 from 0x0aa/fix-ssd1306-roboto-fonts
fix ssd1306 roboto fonts
2020-06-19 16:47:44 +05:00
Ruslan V. Uss
887143a14e
Merge pull request #748 from 0x0aa/optimize-ssd1306-fill-rectangle
optimize ssd1306_fill_rectangle
2020-06-19 16:47:08 +05:00
Ruslan V. Uss
76f3181891
Merge pull request #749 from 0x0aa/optimize-ssd1306-draw-vline
optimize ssd1306_draw_vline
2020-06-19 16:47:00 +05:00
Ruslan V. Uss
37449fabd9
Merge pull request #755 from colesnicov/master
Support for TTF font
2020-06-19 16:46:40 +05:00
Ruslan V. Uss
f2650e5b94
Merge pull request #752 from bastianhjaeger/fix/type-in-extras-bme680
Fix typo in cmoponent.mk of extra/bme680
2020-06-19 16:46:21 +05:00
Denis Colesnicov
6c993f96fb Support for TTF font 2020-06-18 11:48:20 +02:00
Basti (EliteBook)
b9879e1a98 Fix typo 2020-06-04 09:29:51 +02:00
Olli Asikainen
15d224e417 optimize ssd1306_draw_vline 2020-04-24 16:33:36 +03:00
Olli Asikainen
cc24111c05 optimize ssd1306_fill_rectangle 2020-04-24 16:31:05 +03:00
Olli Asikainen
4b2ca1d0b9 fix ssd1306 roboto fonts 2020-04-24 16:27:11 +03:00
Ruslan V. Uss
bc979883c2
Merge pull request #740 from ernicek/ernicek/support-64-48
Added support for OLED with size 64x48
2020-02-05 12:58:06 +05:00
Ernest Toth
dbef6a2c93 Added support for OLED with size 64x48 2020-02-04 19:08:26 +00:00
Ruslan V. Uss
53fa634908
Merge pull request #725 from UncleRus/Itead_si7021
Support for Itead Si7021
2019-07-24 14:39:07 +05:00
UncleRus
92fc3e8bcb Support for Itead Si7021 2019-07-22 02:21:27 +05:00
Júnio Teixeira
d02b40dce8 Http download issue when connection lost (#723)
* Fix bug when read returns -1

When the socket down the "read" function returns -1.
Then the while(read_byte > 0) only works for signed types.

* Remove printf debug line
2019-06-23 08:22:59 +02:00
Ruslan V. Uss
8f378b41c8
Merge pull request #707 from ourairquality/freertos-v10.2.0
FreeRTOS: update to v10.2.0
2019-04-11 20:30:41 +05:00
Ruslan V. Uss
3ca6b84edf
Merge pull request #713 from ourairquality/tsoftuart
tsoftuart: add a softare timer base UART driver, and example.
2019-04-11 20:26:52 +05:00
Ruslan V. Uss
7d2a1d4af6
Merge pull request #712 from ourairquality/mactimer
mactimer: add MAC NMI timer support.
2019-04-11 20:25:07 +05:00
Our Air Quality
5ab0d05768 tsoftuart: add a softare timer base UART driver, and example. 2019-04-11 23:15:44 +10:00
Our Air Quality
05da9151ee mactimer: add mactimer_disarm to remove a pending timer. 2019-04-11 22:10:41 +10:00
Our Air Quality
25e155be4e README: update FreeRTOS version 2019-04-09 22:20:32 +10:00
Our Air Quality
b4e9ceabd5 mactimer: add MAC NMI timer support.
Support for using the MAC timer, a NMI with a higher priority than the
maskable interrupts, but with similar practical limitations to the MAC layer
handler.
2019-04-09 21:07:02 +10:00
Ruslan V. Uss
a487762b2a
Merge pull request #708 from ourairquality/fix-const-loss
Fix compiler warnings over const losses.
2019-04-07 17:07:38 +05:00
Ruslan V. Uss
92baec5cfa
Merge pull request #709 from ourairquality/onewire-signed-var
onewire: fix some variable declarations that should have been signed.
2019-04-07 17:06:56 +05:00
Ruslan V. Uss
494cc554b2
Merge pull request #710 from ourairquality/tsl2561-signed-var3
tsl2561: fix a variable declaration the should have been signed.
2019-04-07 17:05:12 +05:00
Ruslan V. Uss
89746cf1fc
Merge pull request #711 from ourairquality/clean-examples-target
examples: add a clean-examples target, to clean all of the examples.
2019-04-07 17:02:09 +05:00
Our Air Quality
6c459dc746 examples: add a clean-examples target, to clean all of the examples. 2019-04-06 13:10:41 +11:00
Our Air Quality
71b6354cd0 tsl2561: fix a variable declaration the should have been signed. 2019-04-06 12:08:40 +11:00
Our Air Quality
c2267a1d55 onewire: fix some variable declarations that should have been signed. 2019-04-06 11:59:45 +11:00
Our Air Quality
2d9c701c37 Fix compiler warnings over const losses. 2019-04-06 11:39:29 +11:00
Our Air Quality
bceb096e69 FreeRTOS: update to v10.2.0 2019-04-05 21:45:00 +11:00
Zaltora
d0373af5c0 LVGL: Open-source Embedded GUI Library (#669)
* Add lvgl as main component

* update dev5.2 lvgl branch

* update lvgl 5.2 +update example + update configuration

* Update submodule and example

* update lv_drivers (fix) and example

* fix problem when merge
2019-02-26 21:58:15 +01:00
Ruslan V. Uss
bbc22571ec
Merge pull request #693 from ja2142/master
added lease time option to dhcpserver's DHCPOFFER
2019-01-17 04:37:42 +05:00
Radoslaw Olko
b6b0e5da13 added lease time option to dhcpserver's DHCPOFFER 2019-01-16 22:55:37 +01:00
Ruslan V. Uss
a721fb0bc7
Merge pull request #688 from strongly-typed/feature/http_get_host
http_get example: Make compatible with IPv4
2018-12-04 20:31:00 +05:00
Sascha Schade (strongly-typed)
d70e48eb24 http_get example: Make compatible with IPv4
ipv6.google.com is not available from an IPv4-only network.
httpbin.org gives nice answers to many requests.
2018-12-04 16:21:01 +01:00
Ruslan V. Uss
2cded08ce4
Merge pull request #683 from quietboil/master
Fixed command and address in LSB mode
2018-10-26 12:39:25 +05:00
Ruslan V. Uss
253ac0790a
Merge pull request #667 from UncleRus/sdio_cmd25_fix
CMD25 workaround for SDIO, fix #666
2018-10-17 14:15:48 +05:00
Alex Demenchuk
1a348179dd Fixed command and address in LSB mode 2018-10-11 17:47:02 -04:00
Ruslan V. Uss
f82a420b87
Merge pull request #678 from k-korn/master
Add ADS1015 support to ads111x lib.
2018-08-25 00:28:28 +05:00
Korn
b5b05286e9
Add ADS1015 support to ads111x lib. 2018-08-22 19:04:18 +03:00
Ruslan V. Uss
47cc1770c5
Merge pull request #677 from SuperHouse/revert-671-master
Revert "Shrink gpio<>iomux maps"
2018-08-22 17:40:07 +05:00
Ruslan V. Uss
d627251a32
Revert "Shrink gpio<>iomux maps" 2018-08-22 17:39:50 +05:00
Ruslan V. Uss
9353f06df6
Merge pull request #676 from quietboil/master
Fixed sysparams flash area address calculation
2018-08-22 15:46:32 +05:00
Alex Demenchuk
13d78403fd Fixed sysparams flash area address calculation 2018-08-21 15:23:22 -04:00
Ruslan V. Uss
014025df5a
Merge pull request #671 from quietboil/master
Shrink gpio<>iomux maps
2018-08-08 19:07:43 +05:00
Alex Demenchuk
d848620975 Shrink gpio<>iomux maps 2018-08-07 16:12:52 -04:00
UncleRus
e104409d52 CMD25 workaround for SDIO 2018-08-02 19:05:42 +05:00
Ruslan V. Uss
46499c0f26
Merge pull request #648 from phkehl/improve_docu
Improve documentation of http_get_bearssl example
2018-07-04 23:23:33 +05:00
Johan Kanflo
b80a00065b Really added missing include 2018-06-30 20:50:57 +02:00
Johan Kanflo
81fb2d4cae Added missing include 2018-06-30 20:32:11 +02:00
Ruslan V. Uss
a8c60e0960
Merge pull request #647 from ourairquality/libmain-save-wifi-params
libmain: add a compile option to avoid saving wifi params to flash
2018-06-17 18:55:27 +05:00
Philippe Kehl
8bec6e0e81 improve http_get_bearssl example documentation
Add text explaining how to build the 'brssl' tool, how to use it and how
to obtain the server certificate for an exiting https host.
2018-06-17 13:59:18 +02:00
Philippe Kehl
59cb689a45 Merge remote-tracking branch 'upstream/master' 2018-06-17 13:45:21 +02:00
Our Air Quality
4d072e20ed sysparam editor: avoid saving any wifi params to flash 2018-06-17 20:32:07 +10:00
Our Air Quality
7a8ee567b6 libmain: add a compile option to avoid saving wifi params to flash
Add source code for sdk_wifi_param_save_protect() and a compile time,
WIFI_PARAM_SAVE, option to skip writing the wifi state to flash. This
avoids wear on the flash and does not appear to be necessary when the
app initializes the state anyway.

Define WIFI_PARAM_SAVE to 0 for the wificfg example.
2018-06-17 20:12:29 +10:00
Ruslan V. Uss
07772c643d
Merge pull request #587 from ourairquality/newlib-locks-nmi
newlib: skip locking when within the NMI Irq.
2018-06-17 13:08:41 +05:00
Ruslan V. Uss
f89ba44f6e
Merge pull request #646 from ourairquality/wificfg-hostname
wificfg: default the hostname in all modes.
2018-06-17 12:40:30 +05:00
Ruslan V. Uss
88ff263f92
Merge pull request #585 from ourairquality/mbedtls-0318
mbedtls: update and integrate upstream fixes.
2018-06-17 12:32:14 +05:00
Ruslan V. Uss
e3a7ee66cd
Merge pull request #629 from ourairquality/uart-rx-rewrite
stdin_uart: rewrite to use a FreeRTOS queue.
2018-06-17 12:20:16 +05:00
Ruslan V. Uss
14c9e8ae6a
Merge pull request #630 from ourairquality/freertos-r2541
FreeRTOS: update to svn r2541.
2018-06-17 12:19:14 +05:00
Ruslan V. Uss
6db65e8a7a
Merge pull request #642 from ourairquality/i2c-clock-stretch-slow
i2c: increase the default clock strech timeout to 250msec.
2018-06-17 12:16:24 +05:00
Ruslan V. Uss
56f7fd2229
Merge pull request #645 from ourairquality/wificfg-shutdown-hooks
wificfg: add shutdown hooks, and add support to wait until connected.
2018-06-17 12:04:16 +05:00
Our Air Quality
024fbd0cf2 wificfg: default the hostname in all modes.
A hostname is also useful in AP mode, so also default it in AP mode -
it was previously only defaulted in station mode.

Correct the host redirection logic, to work when no hostname is defined.
2018-06-17 16:30:24 +10:00
Our Air Quality
5fb2e94fed wificfg: add shutdown hooks, and add support to wait until connected.
Remove the wificfg_got_sta_connect() function and replace it with
wificfg_wait_until_sta_connected(). This replaces a probe function with a wait
function, and this better fits the wifi layer using an event model - the wait
function can wait on a station connection event before returning.

The shutdown hooks are call when the wificfg restart function is used. It can
be used to implement a cleaner restart, for example blocking further i2c and
flash operations.
2018-06-17 16:11:08 +10:00
Our Air Quality
c8c7f97290 i2c: increase the default clock strech timeout to 250msec.
This also redefines the timeout in FreeRTOS clock ticks, and implements a two
stage wait: firstly spinning sampling frequently, and then falling back to a
longer wait while sampling less frequently and yielding.
2018-06-15 08:28:47 +10:00
Ruslan V. Uss
c4fbd770ad
Merge pull request #639 from joostn/jnsilentmdns1
Turn off mdnsresponder debugging by default
2018-06-11 08:26:22 +05:00
Joost Nieuwenhuijse
fdd3b6e20c Turn off mdnsresponder debugging by default
Currently mdnsresponder outputs debug info by default. Make this
optional by defining:

#define MDNS_RESPONDER_DEBUGGING=1
2018-06-08 22:09:15 +02:00
Joost Nieuwenhuijse
a16997dee1 Merge branch 'SuperHouse/master' 2018-06-08 21:54:16 +02:00
Ruslan V. Uss
af52af782f
Merge pull request #637 from ourairquality/i2c-stdio
i2c: include stdio.h for debugging.
2018-06-08 14:41:42 +05:00
Our Air Quality
b4271792b9 i2c: include stdio.h for debugging. 2018-06-08 19:21:21 +10:00
Ruslan V. Uss
d9c5f2eaa2
Merge pull request #635 from quietboil/improved
ssd1306: Allow SPI3 support to be disabled
2018-06-06 19:30:05 +05:00
Alex Demenchuk
c3b7a01891 Add SPI3 SUPPORT preprocessor macro to CFLAGS 2018-06-05 16:17:26 -04:00
Ruslan V. Uss
eed96df5dd
Merge pull request #634 from ourairquality/sysparam-init-sem
sysparam: always create the semaphore on init.
2018-06-05 20:05:39 +05:00
Our Air Quality
090db8da5e sysparam: always create the semaphore on init.
Otherwise when initialization was not successful it may fail with an
assertion in FreeRTOS rather than returning SYSPARAM_ERR_NOINIT.
2018-06-05 22:24:48 +10:00
Our Air Quality
182258e2c3 FreeRTOS: update to svn r2541. 2018-05-31 14:24:58 +10:00
Our Air Quality
6be0b6b20e stdin_uart: rewrite to use a FreeRTOS queue.
Rewrite to have the IRQ handler read the character and place it in a
FreeRTOS queue.
2018-05-31 14:14:50 +10:00
Ruslan V. Uss
93d43d7825
Merge pull request #622 from ourairquality/uart-nonblock-vtime
stdin_uart_interrupt: add support for nonblock and a timeout.
2018-05-20 02:48:30 +05:00
Zaltora
4dc7d825bc Initial HW PWM (Delta-Sigma) (#609) 2018-05-20 02:47:29 +05:00
Ruslan V. Uss
10f361c8ca
Merge pull request #625 from joostn/jn_cpp1
Improved C++ support, support C++ exceptions
2018-05-18 20:00:42 +05:00
Joost Nieuwenhuijse
2985d1d11e Make operator new / delete weak
so you can implement your own, e.g. if you need a throwing operator new.
2018-05-16 17:56:15 +02:00
Joost Nieuwenhuijse
233f9a6a31 Change linker script to support C++ exceptions
See:
https://github.com/espressif/esp-idf/issues/459
https://github.com/jcmvbkbc/crosstool-NG/issues/54
2018-05-16 17:54:56 +02:00
Joost Nieuwenhuijse
ee001e0231 Move large lib_a-svfwprintf to flash
lib_a-svfwprintf may get included when linking against libstdc++
This will overflow IRAM

https://github.com/SuperHouse/esp-open-rtos/issues/623
2018-05-16 17:53:17 +02:00
Our Air Quality
efff445a03 stdin_uart_interrupt: add support for nonblock and a timeout. 2018-05-05 13:00:06 +10:00
Ruslan V. Uss
5830e001cf
Merge pull request #621 from ourairquality/dhcpc-flag-stopped
sdk_wifi_station_dhcpc_stop: ensure the client is flagged as stopped.
2018-04-30 15:14:18 +05:00
Our Air Quality
6db5525fbb sdk_wifi_station_dhcpc_stop: ensure the client is flagged as stopped.
Need to flag the dhcp client as stopped, even if the netif is not yet
initialized, because the flag is used to control the starting of the
dhcpc.
2018-04-30 14:08:41 +10:00
Ruslan V. Uss
61d3f5b445
Merge pull request #615 from ourairquality/os_delay_us
sdk_os_delay_us: rewrite to avoid hal.h
2018-04-27 01:20:30 +05:00
Ruslan V. Uss
a8c0e44cc7
Merge pull request #616 from ourairquality/new-flash-sizes
Recognise some new flash size codes.
2018-04-27 01:19:47 +05:00
Ruslan V. Uss
2b818ab6e3
Merge pull request #617 from ourairquality/rboot-1_4_2
rboot: update to 1.4.2
2018-04-27 01:19:17 +05:00
Our Air Quality
c183804aa2 rboot: update to 1.4.2 2018-04-25 23:27:01 +10:00
Our Air Quality
46559496c6 Recognise some new flash size codes.
This at least recognises the 2MB-c1, 4MB-c1, 8MB, and 16MB flash
size codes.
2018-04-25 23:06:28 +10:00
Our Air Quality
cec6b7c19f sdk_os_delay_us: rewrite to avoid hal.h
Seems to fail to compile recently, missing xthal_get_ccount(), so
avoid using hal.h which is outside esp-open-rtos.
2018-04-25 13:05:25 +10:00
Ruslan V. Uss
782eaabb97
Merge pull request #612 from rerobika/sdio_send_command
Fix SDIO send_command
2018-04-21 22:05:33 +05:00
Robert Fancsik
3b5510dce1 Fix SDIO send_command
This patch fixes the problem, while receiving R1b type of response from the card.
In case of R1b response the continuous stream that the card sends must be checked whether the signal indicates busy status and wait until a non zero response.
2018-04-20 19:59:59 +02:00
Ruslan V. Uss
4581999feb
Merge pull request #608 from rerobika/sdio_write_block_fix
Fix for sdio_write_sectors
2018-04-17 01:03:38 +05:00
Robert Fancsik
b43c3cee2d Fix for sdio_write_sectors
The issue was found by using f_mkdir("directory_name").
The function always returned FR_DISK_ERR due to an unhadled case in sdio_write_sectors().
According to this documentation: http://www.convict.lu/pdf/ProdManualSDCardv1.9.pdf#page=92 stop transmission command should be sent after writing multiple blocks.
This patch fixes this bug also adds a test case for it.
2018-04-16 12:11:05 +02:00
Ruslan V. Uss
0fa4213577
Merge pull request #607 from FlavioBayer/patch-1
bugfix/ets_timer.c: race condition while disarming
2018-04-14 00:11:10 +05:00
Flavio Bayer
de426c08b6
bugfix/ets_timer.c: race condition while disarming
If `sdk_ets_timer_arm_ms_us` is called right after `vPortExitCritical` inside `sdk_ets_timer_disarm` on line 247 (by an ISR for example, which was my case), execution will loop forever on line 196, since `timer->next!=ETS_TIMER_NOT_ARMED`, which was supposed to be changed in line 248.
By delaying the IRS or context switch until `sdk_ets_timer_disarm` the problem is fixed.
2018-04-13 16:08:03 -03:00
Our Air Quality
9277bea8c9 mbedtls: update and integrate upstream fixes. 2018-04-03 15:30:25 +10:00
Ruslan V. Uss
524a98ed1a
Merge pull request #583 from ourairquality/global-stdio-streams
newlib: rebuild with the global stdio streams enabled.
2018-04-02 11:22:48 +05:00
Ruslan V. Uss
1ef7e85e05
Merge pull request #602 from ourairquality/freertos-r2536
FreeRTOS: Update to r2536.
2018-04-02 11:22:09 +05:00
Ruslan V. Uss
94047dd765
Merge pull request #601 from ourairquality/rom-skip-wrap
Skip calling wrappers from a number of the ROM functions.
2018-04-02 11:21:23 +05:00
Ruslan V. Uss
ace502a533
Merge pull request #597 from nicogrx/upstreamable_work
uart: add ability to configure byte length
2018-04-02 11:20:41 +05:00
Ruslan V. Uss
05af33fe0d
Merge pull request #595 from Zaltora/ws2812_init_fix
ws2812 fix possible memory leak
2018-04-02 11:20:18 +05:00
Our Air Quality
a6fa0ee497 FreeRTOS: Update to r2536.
* Introduce sbBYTES_TO_STORE_MESSAGE_LENGTH

* Fix bug in ucStreamBufferGetStreamBufferType() - which is only used by the
  Percepio trace tool.

* Update the line within vTaskStartScheduler() that was setting xTickCount to 0
  to instead set it to configINITIAL_TICK_COUNT.

* Introduce xMessageBufferNextLengthBytes() and tests for the same.

* Add call to traceTASK_SWITCHED_IN() in vTaskStartScheduler() so trace tools
  can see the first task to run.

* Correct definition of StaticTask_t in the case that portUSE_MPU_WRAPPERS is
  set to 1.

* prvTaskCheckFreeStackSpace() now returns configSTACK_DEPTH_TYPE to allow
  return values greater than max uint16_t value if required.

* xStreamBufferSend() and xStreamBufferReceive() no longer clear task
  notification bits - clearing was unnecessary as only the task notification
  state is used.

* Correct out of date comment in tasks.c.

* Fix typo in comment in queue.h.
2018-03-31 23:32:27 +11:00
Our Air Quality
e43329cbc7 Skip calling wrappers from a number of the ROM functions.
A number of the ROM functions were pointing to wrappers that saved and
restored the $a0 register, but the functions they called either did
not use $a0 or saved and restored $a0 as needed anyway.
2018-03-31 21:29:26 +11:00
Jean-Nicolas Graux
8cb769d55d uart: add ability to configure byte length
Signed-off-by: Jean-Nicolas Graux <nicogrx@gmail.com>
2018-03-29 13:24:06 +02:00
Zaltora
6dde352842 prevent multiple initialization memory allocation and inform user if allocation was fail 2018-03-27 10:56:46 +02:00
Ruslan V. Uss
a89417e26e
Merge pull request #582 from espway/i2c-timing-calculation
i2c: revise timing calculation
2018-03-13 18:35:41 +05:00
tkremeyer
5c18d42c8d UART: Add ability to configure stopbits and parity bit (#590) 2018-03-13 18:31:19 +05:00
Ruslan V. Uss
f296f4d91e
Merge pull request #591 from maximkulkin/fix-dhcpserver-memory-leak
extras/dhcpserver - Fix memory leak on stop
2018-03-13 18:30:27 +05:00
Maxim Kulkin
7707f4f905 extras/dhcpserver - Fix memory leak on stop 2018-03-11 22:56:10 -07:00
Our Air Quality
4bc6032fa6 newlib: skip locking when within the NMI Irq.
NMI Irq error paths call into printf which will use the newlib locks
but these can not be used within the NMI, a task switch can not occur
here. This case would be a terminal error path that is attempting to
write some debug message in the process, so just bail out of the
locking in this case. As a warning a ':' character is emitted and this
will typically prefix lines emitted in this context - it would be an
error for this path to be take in normal operation.
2018-03-03 09:52:47 +11:00
Andrea Greco
b77380bad1 Http client OTA (#553) 2018-03-01 05:03:44 +05:00
Jeff Kletsky
33082ba2c9 extras/timekeeping -- provide POSIX-like interface (#578) 2018-03-01 05:01:40 +05:00
Our Air Quality
f9ae521710 newlib: rebuild with the global stdio streams enabled.
This change means that there is only one set of global stdin, stdout, and stderr
FILE streams shared by all the threads. This reduces memory usage and avoids
having to close these streams before threads exit. These streams still have a
lock to synchronise access.
2018-02-28 23:44:27 +11:00
Sakari Kapanen
4a1b600be4 i2c: improve timing
Look-up tables were used for determining the delay loop counts before.
Based on these hand-tuned values, the loop overhead was estimated for
each option -- 80 and 160 MHz, fast and slow GPIO access. Instead of the
great number of tunable parameters one now only has to tune the overhead
values if the code is changed.

Functions were added to the API which allow setting an arbitrary
frequency. API backward compatibility is retained.

i2c: fix potential overflow situation
2018-02-27 23:47:16 +02:00
Ruslan V. Uss
ed1a6cc6f3
Merge pull request #580 from ourairquality/newlib-lock-fix
newlib lock support: use a separate mutex and recursive mutex.
2018-02-23 22:30:20 +05:00
Sashka
8d4b4aa7a3 Multi-Channel Soft PWM library (#579) 2018-02-23 22:29:42 +05:00
Our Air Quality
dccf3fc7b9 newlib lock support: uses a separate mutex and recursive mutex.
In trying to save memory had incorrectly shared a non-recursive mutex
with recursive mutex uses. Initialize one non-recursive mutex too.
2018-02-23 23:00:08 +11:00
Ruslan V. Uss
49343e9c68
Merge pull request #571 from ourairquality/newlib-300
Newlib: update to version 3.0.0
2018-02-19 10:16:58 +05:00
Ruslan V. Uss
33147ae77f
Merge pull request #574 from ourairquality/lwip-fix-timer-debug
lwip: update and fix compilation with timer debug enabled.
2018-02-18 20:25:57 +05:00
Our Air Quality
8fc06b9b57 lwip: update and fix compilation with timer debug enabled. 2018-02-18 23:38:15 +11:00
Our Air Quality
875aaabebe Newlib: update to version 3.0.0 2018-02-17 01:11:54 +11:00
Ruslan V. Uss
a3d94f168b
Merge pull request #567 from ourairquality/lwip-from-isr-stub
lwip add and stub for sys_mbox_trypost_fromisr()
2018-02-14 16:57:56 +05:00
Our Air Quality
4b6513f5a1 lwip add and stub for sys_mbox_trypost_fromisr()
This is not supported on esp-open-rtos, but add a stub to quieten
linker warnings.
2018-02-14 10:40:46 +11:00
Ruslan V. Uss
59c3ae3e5d
Merge pull request #554 from ourairquality/lwip-update-0118
lwip update
2018-02-13 16:39:34 +05:00
andrewclink
5750b9d91f Allow overriding bootloader flash arguments (#565) 2018-02-13 16:38:51 +05:00
Our Air Quality
3c81f7d587 lwip update
* The mdns responder has been reworked to lower stack and memory usage. This is
  a variation on the upstream code, it use malloc whereas the upstream code uses
  pools. The high stack usage of the mdns responder was problem for
  esp-open-rtos, so we might have to maintain the differences for now.

* Improved lwip core locking, and lock checking. Upstream improvements, that
  need some added support from esp-open-rtos specific code. More core lock is
  performed when calling from the esp-open-rtos code now, so a little safer. The
  checking is not enforced, but projects might see warning messages and might
  want to look into them.

* The esp-open-rtos lwip support has been sync'ed with the new freertos port
  included with lwip. There are still some minor differences.

* A few lwip timer bugs have been resolved. This might help resolve some issues.

* Plus it picks up all the other upstream fixes and improvements.

* The default lwip stack has been lowered from 768 words to 480 words,
  due to the reduced stack usage by the mdns responder.
2018-02-09 20:26:02 +11:00
Ruslan V. Uss
5f8b3d43c7
Merge pull request #556 from andrewclink/master
Add makefile flash hooks
2018-02-09 13:04:04 +05:00
Jeff Kletsky
6b43a1caa1 Improve extras/sntp -- Issue #562 (#563) 2018-02-09 13:02:01 +05:00
Ruslan V. Uss
c31d392f9a
Merge pull request #558 from wutje/patch-1
Update FreeRTOS license.
2018-02-03 01:21:30 +05:00
Wouter
c3eaaa7043
Update FreeRTOS license.
FreeRTOS is under MIT license and copyrighted by Amazon
2018-01-27 23:54:36 +01:00
Andrew Clink
63af6f4cc4 Add makefile flash hooks 2018-01-25 09:16:31 -07:00
Ruslan V. Uss
42e342e3dd
Merge pull request #544 from gschorcht/sht3x
Minor changes in SHT3x driver
2018-01-20 17:03:09 +05:00
Gunar Schorcht
13db675ac6 Minor changes in BME680 driver (#543) 2018-01-20 17:02:53 +05:00
Gunar Schorcht
8325bb87c5 Minor changes in CCS811 driver (#542) 2018-01-20 17:02:31 +05:00
Gunar Schorcht
37230b2de6 L3GD20H 3-axes gyroscope driver (#545) 2018-01-20 17:01:59 +05:00
Gunar Schorcht
a4de9dd4f1 LIS3DH 3-axes accelerometer driver added (#546) 2018-01-20 17:01:38 +05:00
Gunar Schorcht
812794f7d9 LIS3MDL 3-axes magnetometer driver added (#547) 2018-01-20 17:00:35 +05:00
Gunar Schorcht
f5bbff8b87 LSM303D e-Compass driver added (#548) 2018-01-20 16:59:54 +05:00
Ruslan V. Uss
39957e6203
Updated FreeRTOS version in reaadme 2018-01-18 12:30:34 +05:00
Gunar Schorcht
7fed013453 minor changes 2018-01-06 15:34:36 +01:00
Ruslan V. Uss
4715d5e8ff
Merge pull request #532 from ourairquality/netif-default-station
Change the netif default to the station in STATIONAP mode.
2017-12-30 18:53:09 +05:00
Ruslan V. Uss
9dee6f3fff
Merge pull request #531 from imihajlow/master
Allow html files customization for libesphttpd
2017-12-30 15:57:04 +05:00
Our Air Quality
c3dbac37ef Change the netif default to the station in STATIONAP mode.
It seems most common for the connection to the wider internet to be
via the station netif even if there is also an AP netif, so set the
default to the station netif. The lwip ipv4 route logic will still use
the AP netif if the destination is to that subnet.
2017-12-30 20:51:53 +11:00
Ivan Mikhailov
524f8b953f Allow html files customization for libesphttpd
Modified component.mk to let user customize
LIBESPHTTPD_HTML_DIR and LIBESPHTTPD_HTML_FILES
2017-12-30 09:48:17 +01:00
Ruslan V. Uss
4ec3659a04
Merge pull request #529 from ourairquality/newlib-locks-combine
newlib: add an option to combine some locks.
2017-12-28 06:48:28 +05:00
Ruslan V. Uss
e5e902589c
Merge pull request #523 from ourairquality/reclaim-wdev-bss
Reclaim a chunk of unused dram in the wdev bss area, 8000 bytes.
2017-12-28 06:48:16 +05:00
Ruslan V. Uss
2d22be9bac
Merge pull request #530 from ourairquality/sysparam-editor-flushing
sysparam editor: more stdout flushing.
2017-12-27 12:37:11 +05:00
Our Air Quality
3dd347ca55 sysparam editor: more stdout flushing. 2017-12-27 13:56:20 +11:00
Our Air Quality
3b2e0773ca newlib: add an option to combine some locks.
The locks are using a bit of the limited ram. It's probably fine to combine some
of these to use the same mutex, and this patch does so for the set initialized
early. The file locks will still be separate, and dynamically created, so a
thread blocking on them will not deadlock all uses of newlib that need a lock.
2017-12-27 13:55:07 +11:00
Ruslan V. Uss
132391752e
MAX7219 driver fix 2017-12-27 00:33:59 +05:00
Ruslan V. Uss
126fbc20a7
Merge pull request #528 from UncleRus/extras/f-ram
Driver for Cypress serial F-RAM
2017-12-27 00:24:42 +05:00
Ruslan V. Uss
a922ea0383
Merge pull request #519 from ourairquality/heap-end-use-startup-stack
Reuse the startup stack for the dynamic heap.
2017-12-25 22:00:35 +05:00
UncleRus
543b4198b2 Driver for Cypress serial F-RAM 2017-12-24 18:49:52 +05:00
Ruslan V. Uss
131da5b4f2
Merge pull request #505 from ourairquality/mdns-responder1
mDNS-responder: ipv6 support and fixes
2017-12-24 18:39:47 +05:00
Ruslan V. Uss
f671f31b96
Merge pull request #524 from gschorcht/bme680
BME680 driver updates
2017-12-24 04:57:37 +05:00
Ruslan V. Uss
ff18dead52
Merge pull request #525 from gschorcht/sht3x
SHT3x driver updates
2017-12-24 04:57:26 +05:00
Ruslan V. Uss
fa5fe85d3a
Merge pull request #526 from gschorcht/ccs811
CCS811 driver updates
2017-12-24 04:54:24 +05:00
Ruslan V. Uss
342ba29b63
Merge pull request #527 from ourairquality/freertos-v10-0-1
FreeRTOS v10.0.1
2017-12-24 00:34:17 +05:00
Our Air Quality
59a4d85663 FreeRTOS v10.0.1
Mainly some simplifications to the copyright terms.
2017-12-23 21:10:57 +11:00
Gunar Schorcht
ca0b5da905 - Delaying and repeating i2c operation automatically when i2c interface is busy removed. User has to deal with concurrency using semaphores.
- GPIO_ID_PIN macros removed
- Soft reset mechanism of SHT3x does not work when sensor is in any measurement mode. Therefore, it does not abort initialization procedure anymore
- typos
- changes to use the same source code with ESP8266 (esp-open-rtos) and ESP32 (ESP-IDF)
2017-12-21 19:02:02 +01:00
Gunar Schorcht
f0425e7abd - small corrections
- changes to use the same source code with ESP8266 (esp-open-rtos) and
  ESP32 (ESP-IDF)
2017-12-21 19:00:16 +01:00
Gunar Schorcht
07f3c08244 - minor changes
- changes to use the same source code with ESP8266 (esp-open-rtos) and
  ESP32 (ESP-IDF)
2017-12-21 18:58:52 +01:00
Our Air Quality
aa0b7f5005 Reclaim a chunk of unused dram in the wdev bss area, 8000 bytes. 2017-12-19 14:12:02 +11:00
Ruslan V. Uss
c3ae04c93f
Merge pull request #511 from ourairquality/newlib-locks
Newlib: implement locks
2017-12-14 08:30:20 +05:00
Ruslan V. Uss
642e98e0b3
Merge pull request #521 from ourairquality/print_meminfo-fixes
sdk_system_print_meminfo: fix and correct heap end.
2017-12-14 02:47:20 +05:00
Ruslan V. Uss
48a33e6c2e
Merge pull request #520 from ourairquality/wificfg-const-strings
wificfg: declare strings 'const' when appropriate.
2017-12-14 02:47:03 +05:00
Our Air Quality
f0d2c34399 sdk_system_print_meminfo: fix and correct heap end. 2017-12-14 08:15:04 +11:00
Our Air Quality
8ae8019045 wificfg: declare strings 'const' when appropriate. 2017-12-14 08:00:10 +11:00
Our Air Quality
724bf797b1 Reuse the startup stack for the dynamic heap.
Once scheduling has started, the startup stack is no longer usable, control can
never return to that stack. So bump up the heap end in the first task that runs
after scheduling has started. This gives back about 1k.
2017-12-14 07:48:25 +11:00
Our Air Quality
f27bc0f452 wificfg: remove the AP WEP mode option (#514)
* wificfg: remove the AP WEP mode option

The WEP mode does not appear to be implement in the sdk for the AP mode, and
defaults to open when WEP is requested which is probably not intended. Remove
the WEP option from the wifi config interface.

* lwip: enable mdns dns queries.

* wificfg: support mDNS on the softAP interface.
2017-12-13 21:29:49 +05:00
Ruslan V. Uss
c1937ea754
Merge pull request #518 from ourairquality/freertos-v10-1
FreeRTOS v10 fixes.
2017-12-13 16:08:24 +05:00
Our Air Quality
36322def89 FreeRTOS v10 fixes.
svn r2522:
FreeRTOS kernel: Fix extern "C" { in stream_buffer.h.
FreeRTOS kernel: Correct tskKERNEL_VERSION_NUMBER and tskKERNEL_VERSION_MAJOR constants for V10.
Ensure the currently executing task is printed correctly in vTaskList().
2017-12-13 21:16:40 +11:00
Ruslan V. Uss
95ff7ef378
Merge pull request #517 from UncleRus/fatfs_r13a
FatFs updated to R13a
2017-12-13 11:17:35 +05:00
Our Air Quality
e9d9201527 Newlib: implement locks
* Dynamically allocate arc4random data. Saves about 1k off the bss.
2017-12-13 11:29:43 +11:00
UncleRus
7f010ef1fe FatFs updated to R13a 2017-12-12 11:39:22 +05:00
Ruslan V. Uss
89c6c410ff
Merge pull request #516 from ourairquality/softap-multicast
softap: allow output of multicast frames.
2017-12-12 10:28:21 +05:00
Our Air Quality
0a07fe11e5 softap: allow output of multicast frames.
Multicast frames were being dropped by ieee80211_output_pbuf. It appears to look
up the destination address using cnx_node_search which only has an entry for the
broadcast address (all ones). This patch modifies cnx_node_search to return the
broadcast cnx_node for the multicast addresses too.

This is needed to support services such as mDNS on the softap interface.
2017-12-12 12:03:19 +11:00
Our Air Quality
85338ee672 mDNS-responder: ipv6 support and fixes
* Adds ipv6 support. Compiles with ipv6 enabled and then accepts ipv6
  connections and answers AAAA questions.

* Fixes a few overflows of the reply buffer. Reduce the default reply buffer
  size, name it MDNS_RESPONDER_REPLY_SIZE, and allow overriding.

* Fix mdns_add_TXT.

* Prefer malloc to large stack buffers, to control stack sizes, and try to
  malloc only the buffer size needed where known in advance.

* Determine the IP addresses when responding, eliminating the update function
  and the update task.

* Allow use in SoftAP and StationAP mode too.

* Fix to compile without the debug output.

* Slightly better integration with lwip.

* Accept a NULL TXT entry.

* Some code style changes, not comprehensive.
2017-12-12 11:34:21 +11:00
Gunar Schorcht
61f23d0cf4 CCS811 driver added (#479) 2017-12-11 08:00:53 +05:00
Ruslan V. Uss
2f62c6e9df
Merge pull request #509 from ourairquality/wificfg-ipv6-mdns
wificfg: IPv6 and mDNS support
2017-12-11 07:32:37 +05:00
Our Air Quality
d178d36e0e wificfg: add config option for mDNS 2017-12-10 10:32:21 +11:00
Our Air Quality
44d44a2cc5 wificfg: IPv6 and mDNS support
* When IPv6 is enabled the http server and the captive portal dns now also
  accept IPv6 connections. The interface and peer IPv6 address are now also
  reported.

* The http server no longer redirects <name>.local to an IP address for better
  integration with mDNS.

* Add mDNS support, for the extras/mdnsresponder or the LWIP mDNS responder,
  and enable the LWIP mDNS responder for examples/wificfg.
2017-12-10 10:32:21 +11:00
Our Air Quality
c4dcfb1cac lwip: update
* Update to current master branch

* Quietens unused variable warnings building mDNS.
2017-12-10 10:32:21 +11:00
Ruslan V. Uss
1d77f3ec1f
Merge pull request #500 from ourairquality/amazon-freertos-100
FreeRTOS v10.0.0
2017-12-09 22:29:06 +05:00
Sakari Kapanen
d41c0f1d72 I2C optimization (#503)
Fix of #480
2017-12-09 22:27:39 +05:00
Ruslan V. Uss
4ae2a6cdf0
Merge pull request #507 from imihajlow/master
Allow overrides of sntp.h
2017-12-09 22:26:53 +05:00
Ruslan V. Uss
776656d79b
Merge pull request #512 from ourairquality/esphttpd_wsbcast_stack
esphttpd: increase stack size for task wsbcast
2017-12-09 22:25:58 +05:00
Our Air Quality
c2eed89318 esphttpd: increase stack size for task wsbcast
Seeing stack overflows on this one.
2017-12-09 23:43:03 +11:00
Ivan Mikhailov
69220ee866 Allow overrides of sntp.h
Changed quote marks with triangle brackets
for sntp.h to allow user creating a custom sntp.h
2017-12-07 20:55:03 +01:00
Our Air Quality
a7f7f5c01c FreeRTOS v10.0.0
Based on svn r2519.

* Re-licensed with the MIT license, and by Amazon.

* New for this releases are Stream buffers and message buffers.
2017-12-07 11:13:07 +11:00
Sashka
d05d3020eb Bringing libesphttpd up-to-date (#504)
* libesphttpd: added extras and example

* Added "heatshrink" as a submodule

* Updated libesphttpd

* Updated libesphttpd

* Trying to fix the commit id

* Updated libesphttpd

* Added zlib1g-dev package

* Use native gcc to build mkespfsimage and mkupgimg

* Added NS and GW for DHCP server configuration

* Making libeshttpd up-to-date

* Making libeshttpd up-to-date (heatshrink updated)

* Making libesphttpd up-to-date
2017-12-06 20:13:29 +05:00
Maxim Kulkin
6faf7c569d Fix mdnsresponder compilation issues (#481) 2017-12-05 12:15:18 +05:00
Ruslan V. Uss
f67495f4f0
Merge pull request #486 from ekalyvio/master
Fixed Repeated-start in I2C
2017-12-02 14:45:46 +05:00
Ruslan V. Uss
3214c13fbc
Merge pull request #491 from funnydog/fixes
Fix the SPIFFS POSIX API (#489)
2017-12-02 14:41:41 +05:00
Zaltora
962196ef1d color and timing (ws2812_i2s) (#493) 2017-12-02 14:37:52 +05:00
Zaltora
a0f846013c pwm fix (#485)
* pwm fix special state + debug print + IRAM interupt
* Special state = don't set timer, safer
* fix timer crash, cant divide by 0
* pwm dont start when duty is set
* reverse option
* fix low duty crash + comments
2017-12-02 11:54:04 +05:00
funnydog
8354c03a12 Fix the SPIFFS POSIX API (#489)
The commit ebdd2f9 defined some offsets to differentiate between the
standard, socket and file descriptors.

SPIFFS_FILEHDL_OFFSET was updated accordingly but the code didn't use
that constant and this broke the SPIFFS POSIX API.

Fix it by initializing the fh_ix_offset field of the spiffs_config
structure to SPIFFS_FILEHDL_OFFSET.
2017-11-22 16:45:48 +01:00
Ruslan V. Uss
9b4a58c8e1
Merge pull request #484 from Zaltora/ina3221_option
Ina3221 crash with NULL fix
2017-11-22 16:43:39 +05:00
Efthymios Kalyviotis
0e6694144f Fixed Repeated-start in I2C 2017-11-19 23:27:55 +02:00
lilian
8a9c3fd9e8 ina3221 ptr NULL security 2017-11-17 20:44:02 +01:00
Gunar Schorcht
691cf4ed62 Driver for Bosch Sensortec BME680 added (#469)
* Driver for Bosch Sensortec BME680 added
2017-11-07 12:47:58 +05:00
Ruslan V. Uss
e0410b2c5d
Merge pull request #475 from UncleRus/i2c_fix2
Configurable I2C clock stretching
2017-10-29 19:13:48 +05:00
rus
1d3ca574f1 Fix #471 2017-10-28 22:57:22 +05:00
Ruslan V. Uss
f9d639f7f4 Merge pull request #478 from Petezah/fix.ssd1303.cpp
Fix a typo in ssd1306 driver that prevents compiling with c++ compiler
2017-10-27 19:52:17 +05:00
Peter Dunshee
f8c87c3d6c Fix a typo in ssd1306 driver that prevents compiling with c++ compiler 2017-10-27 09:04:57 -05:00
Ruslan V. Uss
7cd1afc52d Merge pull request #465 from UncleRus/pcf8591_update
PCF8591 driver update
2017-10-25 13:01:40 +05:00
Sashka
09b8b8087c Add libesphttpd to extras and supporting example (#458)
* libesphttpd: added extras and example

* Added "heatshrink" as a submodule

* Updated libesphttpd

* Updated libesphttpd

* Trying to fix the commit id

* Updated libesphttpd

* Added zlib1g-dev package

* Use native gcc to build mkespfsimage and mkupgimg

* Added NS and GW for DHCP server configuration
2017-10-23 23:59:13 +02:00
dora38
d36e9d65a0 Fix a printf issue. (#474)
Added missing return statements to stdio
2017-10-23 23:55:11 +02:00
Gunar Schorcht
ac6797e916 Driver for Sensirion SHT3x temperature and humidity sensor readded (#453)
* Driver for Sensirion SHT3x sensor added

This is a driver for Sensirion SHT3x temperature and humidity sensors
connected via I2C.

This commit is a rebasing and contains some interface changes based on
the review from @ourairquality.

* SHT3x driver changes

Additional include to satisfy the Travis CI test build

* SHT3x driver - small changes

README.md has been shortened

* SHT3x driver - small changes

* SHT3x driver - small changes

- crc8 lookup table is now static to be held in flash memory
- special handling for the timer overflow in sht3x_is_measuring removed
- initialization reduced to availability check

* SHT3x driver - some small changes

- crc8 lookup table is now static to be held in flash memory
- special handling for the timer overflow in sht3x_is_measuring removed
- some whitespace removed
- initialization reduced to availability check

* SHT3x driver - some minor changes

- lookup tables made const to be held in flash
- crc8 computation changed to a non table lookup version
- measurement duration is now given in ticks and can be used directly
  for vTaskDelay (documentation and examples changed accordingly)

* SHT3x driver - documentation changed

* SHT3x driver - minor correction

- number of ticks for measurement duration takes now into account
  portTICK_PERIOD_MS

* SHT3x driver - minor correction

- number of ticks for measurement duration takes now into account
  portTICK_PERIOD_MS

* SHT3x driver - minor correction

- number of ticks for measurement duration takes now into account
  portTICK_PERIOD_MS

* SHT3x driver - minor correction

- number of ticks for measurement duration takes now into account
  portTICK_PERIOD_MS

* SHT3x driver - minor corrections

* SHT3x driver - minor corrections

* Driver for Sensirion SHT3x sensor added

This is a driver for Sensirion SHT3x temperature and humidity sensors
connected via I2C.

This commit is a rebasing and contains some interface changes based on
the review from @ourairquality.

SHT3x driver changes

- additional include to satisfy the Travis CI test build
- README.md has been shortened
- special handling for the timer overflow in sht3x_is_measuring removed
- some whitespaces removed
- crc8 computation changed to a non table lookup version
- measurement duration is now given in ticks and can be used directly
  for vTaskDelay (documentation and examples changed accordingly)
- number of ticks for measurement duration takes now into account
  portTICK_PERIOD_MS
- clock stretching disabled on sensor to avoid blocking when data are
  not ready to read
- calculation of maesurement duration adds now one and a half ticks to
  be sure that measurement duration is not too short
- function sht3x_is_measuring is now private and only for internal use,
  user task has always to use function vTaskDelay to wait for
  measurement results
- function sht3x_is_measuring was simplified and returns now just a
  boolean value
- private function sht3x_reset added which is used to reset the sensor
  during initialization
- active flag in sensor data structure not needed anymore
- function sht3_get_raw_data simplified
- function sht3x_start_measurement returns now only a boolean
- function sht3x_start_measurement does not check anymore whether there is
  already a measurment running
- new function sht3x_get_measurement_duration which returns the measurement
  duration in ticks for configured repeatability

* SHT3x driver minor changes

- type sht3x_values_t replaced by separate float values
- additional repeatability parameter defined for function sht3x_start_measurement
- parameter of function sht3x_get_measurement_duration changed from
  sht3x_sensort_t to sht3_repeat_t
- sensor modes and repeatability levels extended by prefix sht3x_

* SHT3x driver minor changes

- new high level function sht3x_measure added, it comprises all three
  steps to perform one measurement in only one function
- example with two sensors removed

* SHT3x driver small correction
2017-10-23 23:39:48 +02:00
Ruslan V. Uss
5fa48d0298 Code formatted, minor fixes (#466) 2017-10-18 21:25:48 +02:00
Our Air Quality
8a474d749d wificfg: correct a few initialization issues (#464)
* Correct checking of the AP password and SSID lengths.

* Only enable AP mode if it is really configured enabled.

* Only start the http server if wifi is enabled.
2017-10-18 20:56:17 +02:00
Our Air Quality
ebdd2f983b lwip: define LWIP_POSIX_SOCKETS_IO_NAMES as zero (#457)
This patch gets the newlib standard stream descriptors playing well with the
lwip socket descriptors and the spiffs file descriptors. The LWIP_SOCKET_OFFSET
is now defined to be 3, rather than zero, to avoid clashing with the standard
stream descriptors, and the SPIFFS_FILEHDL_OFFSET is bumped up to start after
the lwip descriptors.
2017-10-18 19:33:32 +02:00
UncleRus
60b671ea44 Added DAC support to PCF8591 driver 2017-10-13 00:54:08 +05:00
Ruslan V. Uss
87a3503f93 I2C code formatting, README fix (#462) 2017-10-12 17:42:34 +05:00
Ruslan V. Uss
b520735d20 Merge pull request #463 from UncleRus/dhcp_if_revert
Revert #426
2017-10-11 16:40:06 +05:00
UncleRus
62d99e1554 Revert #426 2017-10-11 15:38:31 +05:00
Ruslan V. Uss
715bc8148c Fix example broken by DHCP update (#461) 2017-10-11 03:21:47 +05:00
Fernando
cb4ea206fa DHCP Allows selecting the DHCP server's network interface (#426) 2017-10-10 22:01:32 +05:00
Ruslan V. Uss
260dd1bde8 Merge pull request #460 from UncleRus/dhcp_fix
Minor fixes in dhcpserver.c
2017-10-10 21:22:19 +05:00
UncleRus
b58cd12f85 Minor fixes in dhcpserver.c 2017-10-10 20:01:07 +05:00
Johan Kanflo
e3403eb5db Added fflush for terminal echo (#455) 2017-10-10 15:37:43 +02:00
Erwin Boskma
e24b6579ff Added support for RGBW NeoPixels (#449) 2017-10-08 23:02:39 +05:00
Zaltora
68cc1451b2 example and dhcp debug (#447) 2017-10-08 11:47:23 +05:00
Ruslan V. Uss
546cc47121 Merge pull request #437 from ourairquality/oaq-merge-1
* bmp180: comment typo
* ds3231: minor code style fixes. Comment, on the week day start.
* Reverse engineered ets_timers.o Switch from FreeRTOS queue to task notification. Removed unknown/unused code. Rename sdk_ets_handler_isr to process_pending_timers. Add function for microseconds Simplify time to ticks conversion
* ets_timer: code for using the FreeRTOS timers, and remove from libs.
* libc: update to a recent newlib version.
* LwIP v2 support
* spi_write: use uint32_t for the page iteration counter. The page counter was using an uint8_t which seems unnecessary and might wrap.
* sysparam_get_bool: memcpy the binary values out.
* FreeRTOS 9.0.1
* Add an argument to ISRs. Disable interrupts while masking them.
* sysparam: reserve one more flash sector before placing the sysparams. This is to help work with recent SDKs that add a RF cal sector by default in the fifth last sector - just so the sysparam sectors do not jump around when using different SDK versions.
* upnp example: strip down the lwipopts.h file
* sysparam editor: accept newline to end a line of input.
* Add Wificfg. Uses the sysparam store to save the wifi configuration. Adds a basic http server for configuration.
* lwip: disable the tcpip_core_locking_input option. With this option enabled some lwip input processing occurs in the pp task which works well for some uses but some code uses a lot of stack (e.g. mdns) and will overflow the pp task stask, or might unnecessarily slow the critical pp task,
so disable this by default and if not already defined.
* sdk_cnx_add_rc: fix overflow of the table, when no match is found. Also adds source code for sdk_cnx_rc_search, adding a null pointer dereference. Check (that is not expected to be seen), and source code for sdk_cnx_remove_rc.
* http_get example: fix compilation with ipv6 disabled.
* lwip: update to master branch.
* wificfg: allow the AP channel to be 1.
* lwip: rework the tcp ooseq handling. It now accounts for the number of rx pool buffers used and the
available memory when deciding the number of ooseq buffers to retain. Enable the TCP Selective ACK support which appears to help a lot on lossy wifi when using the OOSEQ option.
* Update lwip, fixes losses of pcbs and associated problems.
* lwip: revise the tcp ooseq limit calulations. Was making a mess of the calculation sign. Also added a COPY_PP_RX_PBUFS define to include appropriate limits for this option.
* lwip: ooseq_max_bytes() - set a practical target memory size.
* lwip: revise ooseq handling. Modified for lwip backwards compatibility based on upstream feedback.
* lwip: update to the 2.0.3 release
* lwip: merge upstream master.
* libc: update to upstream master.
* lwip: fix building without TCP_QUEUE_OOSEQ
2017-10-02 04:50:35 +05:00
Our Air Quality
70aa7a90a5 lwip: fix building without TCP_QUEUE_OOSEQ 2017-10-01 21:26:15 +11:00
Our Air Quality
6080bb6ef2 libc: update to upstream master. 2017-09-21 23:44:24 +10:00
Our Air Quality
1e76ce25d5 lwip: merge upstream master. 2017-09-21 20:55:00 +10:00
Our Air Quality
5e92d55af5 lwip: update to the 2.0.3 release 2017-09-18 21:28:29 +10:00
Our Air Quality
0a1fd09459 lwip: revise ooseq handling.
Modified for lwip backwards compatibility based on upstream feedback.
2017-09-08 10:48:44 +10:00
Our Air Quality
893f715852 lwip: ooseq_max_bytes() - set a practical target memory size. 2017-09-04 18:13:27 +10:00
Our Air Quality
730a0f40c7 lwip: revise the tcp ooseq limit calulations.
Was making a mess of the calculation sign.

Also added a COPY_PP_RX_PBUFS define to include appropriate limits
for this option.
2017-09-04 17:22:30 +10:00
Our Air Quality
49f7951013 Update lwip, fixes losses of pcbs and associated problems. 2017-09-04 07:31:42 +10:00
Our Air Quality
f5817aef01 lwip: rework the tcp ooseq handling.
It now accounts for the number of rx pool buffers used and the
available memory when deciding the number of ooseq buffers to retain.

Enable the TCP Selective ACK support which appears to help a lot on
lossy wifi when using the OOSEQ option.
2017-09-03 20:13:54 +10:00
Zaltora
b83c2629b9 I2C bus upgrade (#432) 2017-09-01 14:29:32 +05:00
Ruslan V. Uss
d100f42b1f Merge pull request #440 from flannelhead/user-exception-handler
Add a hook for a user defined exception handler
2017-09-01 14:28:49 +05:00
Our Air Quality
1bfa6c4364 wificfg: allow the AP channel to be 1. 2017-08-30 13:53:01 +10:00
Our Air Quality
fea8a3f4e7 lwip: update to master branch. 2017-08-30 13:52:50 +10:00
Our Air Quality
29da4e9279 sdk_cnx_add_rc: fix overflow of the table, when no match is found.
Also adds source code for sdk_cnx_rc_search, adding a null pointer dereference
check (that is not expected to be seen), and source code for sdk_cnx_remove_rc.
2017-08-30 13:51:32 +10:00
Our Air Quality
87994d3bb4 http_get example: fix compilation with ipv6 disabled. 2017-08-30 13:51:32 +10:00
Our Air Quality
0d5e3bb663 lwip: disable the tcpip_core_locking_input option
With this option enabled some lwip input processing occurs in the pp task which
works well for some uses but some code uses a lot of stack (e.g. mdns) and will
overflow the pp task stask, or might unnecessarily slow the critical pp task,
so disable this by default and if not already defined.
2017-08-30 13:51:32 +10:00
Our Air Quality
b79da1f1f1 sysparam editor: accept newline to end a line of input. 2017-08-30 13:51:32 +10:00
Our Air Quality
5aabd643da ds3231: minor code style fixes.
Comment, on the week day start.
2017-08-30 13:51:32 +10:00
Our Air Quality
56a73454dd bmp180: comment typo 2017-08-30 13:51:32 +10:00
Our Air Quality
55958b8bc3 sysparam_get_bool: memcpy the binary values out. 2017-08-30 13:51:32 +10:00
Our Air Quality
b6fc58b743 spi_write: use uint32_t for the page iteration counter.
The page counter was using an uint8_t which seems unnecessary and might wrap.
2017-08-30 13:51:32 +10:00
Our Air Quality
3dbf129fa1 ets_timer: code for using the FreeRTOS timers, and remove from libs. 2017-08-30 13:51:32 +10:00
sheinz
326708c903 Reverse engineered ets_timers.o
Switch from FreeRTOS queue to task notification.
Removed unknown/unused code.

Rename sdk_ets_handler_isr to process_pending_timers
Add function for microseconds
Simplify time to ticks conversion
2017-08-30 13:51:32 +10:00
Our Air Quality
8b0a1ae362 Add Wificfg
Uses the sysparam store to save the wifi configuration.
Adds a basic http server for configuration.
2017-08-30 13:51:32 +10:00
Our Air Quality
af4ac44cb5 libc: update to a recent newlib version. 2017-08-30 13:51:32 +10:00
Our Air Quality
cd23acaa4a LwIP v2 support 2017-08-30 13:51:32 +10:00
Our Air Quality
1cfded6389 upnp example: strip down the lwipopts.h file 2017-08-30 13:51:32 +10:00
Our Air Quality
17eb160be7 FreeRTOS 9.0.1 2017-08-30 13:51:32 +10:00
Our Air Quality
5583543f14 Add an argument to ISRs. Disable interrupts while masking them. 2017-08-30 13:51:32 +10:00
Our Air Quality
ec5dabd237 sysparam: reserve one more flash sector before placing the sysparams
This is to help work with recent SDKs that add a RF cal sector by
default in the fifth last sector - just so the sysparam sectors do not
jump around when using different SDK versions.
2017-08-30 13:51:32 +10:00
Sakari Kapanen
4838072ecf Added an API for user exception handlers 2017-08-29 09:51:23 +03:00
Ruslan V. Uss
42ccb47eb3 Merge pull request #439 from Zaltora/ssd1306_fix
Fix SPI3 protocol with SSD1306
2017-08-24 18:41:02 +05:00
lilian
674c450416 Fix SPI3 protocol with SSD1306 2017-08-22 15:10:15 -03:00
Ruslan V. Uss
077fe622da Merge pull request #438 from sheinz/fix/travis
Fix pyserial import on travis CI
2017-08-20 01:32:21 +05:00
sheinz
8ce00cdf21 Fix pyserial import on travis CI 2017-08-18 17:38:38 +03:00
Ruslan V. Uss
f51becd0a7 Merge pull request #433 from flannelhead/httpd-typedef-fix
httpd: add missing typedef
2017-08-05 01:34:04 +05:00
Ruslan V. Uss
9347a6b165 Merge pull request #431 from ourairquality/i2c-default-speed
i2c: remove wip 400k define
2017-08-04 15:46:04 +05:00
Sakari Kapanen
30920ce4ec httpd: add missing typedef 2017-08-04 07:18:42 +03:00
Our Air Quality
afa834a805 i2c: remove wip 400k define
Looks like this was test wip code that should not have been included.
Want to be able to set the i2c per-project rather than having to patch
the driver.
2017-08-02 10:36:06 +10:00
Ruslan V. Uss
9523e872f8 Merge pull request #418 from apiel/master
Upnp example emulating a Wemo switch
2017-07-24 16:26:37 +05:00
Ruslan V. Uss
29b9054cb1 Merge pull request #415 from ourairquality/rm-libgcc-in-rom
Remove code from libgcc that is provided by the ROM.
2017-07-24 16:17:31 +05:00
Ruslan V. Uss
1544768025 Merge pull request #416 from ourairquality/lmac-use-hwrand
Use hwrand for the sdk uses of rand, in particular with the NMI.
2017-07-24 16:16:30 +05:00
alex
3c050bc4d1 Upnp example emulating a Wemo switch 2017-07-20 20:23:52 +02:00
Our Air Quality
6a0da03809 Use hwrand for the sdk uses of rand, in particular with the NMI.
The fiq NMI calls rand() from lmac:lmac.a:sdk_lmacTxFrame and the NMI
must not touch the newlib reent structure or enter critical regions
etc, so just use the simple and safe hwrand implementation as a
substitute.
2017-07-20 16:24:45 +10:00
Our Air Quality
9e302c59ed Remove code from libgcc and libc that is provided by the ROM.
This saves about 2.5k of iram.
2017-07-16 23:09:33 +10:00
Ruslan V. Uss
e17b1a5db6 Merge pull request #410 from UncleRus/extras/ad770x
Driver for AD7705/AD7706 SPI ADC
2017-07-10 03:42:42 +05:00
UncleRus
ee7bd87011 Driver for AD7705/AD7706 SPI ADC 2017-07-07 03:50:50 +05:00
Ruslan V. Uss
497b4e607b Merge pull request #404 from ourairquality/bearssl2
Update BearSSL
2017-07-06 11:17:04 +05:00
Ruslan V. Uss
11ea727efa Merge pull request #403 from ourairquality/mbedtls251
Update mbed TLS to 2.5.1
2017-07-06 11:16:32 +05:00
Our Air Quality
178d0e381c Update BearSSL 2017-07-04 23:16:22 +10:00
Our Air Quality
4737e3b438 Update mbed TLS to 2.5.1 2017-07-04 20:24:34 +10:00
Ruslan V. Uss
a0297eb3af Merge pull request #401 from Governa/mqtt_timer
Mqtt timer not sleeping
2017-07-04 02:26:59 +05:00
Fernando Governatore
c1747fb8da MQTT fix mqtt_timer_expired
If the user passes 0 as a timeout, we should not sleep(the timer has
already expired).
2017-07-03 15:50:54 -03:00
Fernando Governatore
67cd7bc031 MQTT fix mqtt_timer_left_ms
mqtt_timer_left_ms: timer->end_time is in ticks, now is in ticks, so left
is in ticks. left * portTICK_PERIOD_MS is the time left.

  With that change, the select in both mqtt_esp_read and mqtt_esp_write
seems to work as expected(with time, not ticks)
2017-07-03 15:50:54 -03:00
Ruslan V. Uss
49a0a74ae2 Merge pull request #397 from Governa/patch-1
MQTT ignores too many handlers registered
2017-06-22 01:09:45 +05:00
Fernando
ca110fa645 MQTT ignores too many handlers registered
On MQTTClient.c function mqtt_subscribe, if more than MQTT_MAX_MESSAGE_HANDLERS are registered, the variable rc receives the value of grantedQoS.

If grantedQoS = 0, and all handlers are already occupied, it goes on and returns 0 to the caller.
2017-06-19 21:31:09 -03:00
Ruslan V. Uss
abe3b8fd68 Merge pull request #390 from ourairquality/esp-open-sdk-update
travis: update the esp-open-sdk version used.
2017-06-07 14:19:24 +05:00
Our Air Quality
91e89001c3 travis: update the esp-open-sdk version used. 2017-06-07 18:36:06 +10:00
Ruslan V. Uss
ce298e1e23 Merge pull request #388 from luigifreitas/patch-1
Change xTaskCreate priority.
2017-06-06 07:39:00 +05:00
Luigi Freitas Cruz
5e3e69ba02 Change xTaskCreate priority.
Priority #1 appears not to be working. Priority #2 works just fine.
2017-06-05 19:29:04 -03:00
Ruslan V. Uss
857b8002e0 Merge pull request #382 from kanflo/httpd_fix
Fix for #381
2017-05-18 15:06:46 +05:00
Johan Kanflo
577d5e6895 Fix for #381 2017-05-16 16:12:55 +02:00
Ruslan V. Uss
c3482a8c01 Merge pull request #372 from panoti/feature/pcf8591
8-bit digital-to-analog conversion PCF8591 library
2017-05-10 03:31:55 +05:00
Ruslan V. Uss
5e04c890d1 Merge pull request #369 from UncleRus/spi_fix
Fixes unaligned writes to SPI data register
2017-04-26 17:24:35 +05:00
thanhpn
dbcb707c1c add pcf8591 lib + example 2017-04-25 23:57:40 +07:00
Michael Hamel
4b0acbe8bf Feature/mdnsresponder (#348)
Basic multicast-DNS service discovery responder
2017-04-25 19:00:09 +05:00
Ruslan V. Uss
c90362621a Merge pull request #370 from UncleRus/extras/timeout_fix
Fix for counter overflow in delays based on sdk_system_get_time()
2017-04-25 18:57:44 +05:00
thanhpn
b982a132ae add 2017-04-23 15:35:23 +07:00
UncleRus
55e08de21c Fix for counter overflow in delays based on sdk_system_get_time() 2017-04-22 00:55:41 +05:00
UncleRus
852ed2f1ad Fixes unaligned writes to SPI data register 2017-04-20 01:49:46 +05:00
andree182
b3f658bdbf bh1750 i2c light sensor driver + pwm cleanup (#330)
Add bh1750 (I2C light sensor) driver + usage example
2017-04-01 05:20:37 +05:00
UncleRus
31ef50c9a9 Revert SPI memcpy() 2017-03-22 10:50:54 +05:00
sheinz
a91ec6eb61 sysparam fixes, tests, spi flash refactoring (#299)
Original work by @ourairquality
* Sysparam threadsafe and SPI access
* Sysparam test cases
* Fix for negative int8
* Sysparam getting bool without memory allocation. Bool tests.
* SPI flash refactoring.
* Extract common spiflash.c into core.
* Use spiflash.c in sysparam.
* Use memcpy in spiflash.c insted of hand-written version.
* Tests for spiflash.c
2017-03-22 02:18:04 +05:00
UncleRus
07ca0d2e9e Update I2C README 2017-03-22 02:14:06 +05:00
Ruslan V. Uss
67a0cfbf8e Merge pull request #356 from bschwind/tsl4531
Add a TSL4531 driver and example
2017-03-22 00:09:18 +05:00
Brian Schwind
8b5ee93b55 Add a TSL4531 driver and example 2017-03-22 01:36:30 +09:00
Zaltora
813477aa8a I2c optimization and features (#321)
* custom delay
* Update comment
* add bus control status, add some missing include & fixed display output on sh1104 (#319)
* add some missing include
* Fixed display on SH1106
* Fix comment, add force sytem, rework flag, 16 bits data transfert
* Update all library with new I2C API
* custom delay
* Update comment, add bus control status
* fix i2c read + fix ds3231 temp + fix ssd1306 send
2017-03-21 11:41:47 +05:00
Ruslan V. Uss
1575bac0c7 Merge pull request #355 from andrewclink/export_rtos_hooks
Give FreeRTOS Hooks weak linkage
2017-03-21 01:50:58 +05:00
Andrew Clink
03597d9162 Make FreeRTOS hooks weak; Add example 2017-03-20 12:56:17 -07:00
Ruslan V. Uss
32328713f5 Merge pull request #353 from UncleRus/fatfs_r12c
Update FatFS to R0.12c
2017-03-16 01:26:02 +05:00
UncleRus
9300729533 FatFS update to R0.12c 2017-03-15 21:08:44 +05:00
Ruslan V. Uss
1457a3ed19 Fixed error of writing to SPI registers with memcpy (#352)
fixed memcpy() writing registers bug
2017-03-15 18:18:32 +05:00
Ruslan V. Uss
20674f8470 Merge pull request #350 from funnydog/sntp-fix
extras/sntp: fix an off-by-one bug in sntp_set_servers()
2017-03-15 10:58:28 +06:00
funnydog
65a0c95b13 extras/sntp: fix an off-by-one bug in sntp_set_servers()
The function sntp_set_servers() duplicates the strings supplied in the
server_url[] array into new strings but forgets to allocate the extra
byte needed for the \0 terminator for each string.

Fix the problem by using strdup(), which allocates the right amount of
memory and copies the string at once.
2017-03-14 20:32:51 +01:00
mr-nice
6b0547b963 Softuart (#307)
* extras/softuart: support for multiple UARTs, dynamic RX/TX pins
2017-03-06 23:28:20 +06:00
Zaltora
fda5d0b942 Crc fix and update (#347)
Update crc example API and config.
2017-02-27 22:35:56 +06:00
Zaltora
f51a2109b1 CRC library (#339)
* Crc initial example
* Update example and fix submodule
2017-02-22 01:44:03 +06:00
Ruslan V. Uss
eb5fa3d405 Merge pull request #343 from kanflo/sdk_system_get_netif
Added sdk_system_get_netif
2017-02-21 22:30:33 +06:00
Johan Kanflo
c415d49f1e Added sdk_system_get_netif 2017-02-20 20:27:24 +01:00
Milosch Meriac
398ed46776 Add BearSSL extra (#340)
Add BearSSL extra + http_get example, TLS server example
2017-02-15 17:44:11 +06:00
Ruslan V. Uss
54ce6bbe1c Merge pull request #337 from UncleRus/extras/max7219
MAX7219/MAX7221 dirver + example
2017-02-12 01:51:37 +06:00
UncleRus
87b4befd87 MAX7219/MAX7221 dirver + example 2017-02-09 03:31:51 +05:00
Ruslan V. Uss
c21f70366f Merge pull request #334 from lujji/master
httpd: support for large WebSocket frames
2017-02-03 11:31:13 +06:00
lujji
3b5397f2a4 added support for large WebSocket frames 2017-02-03 07:33:27 +00:00
lujji
bce2139f06 added WebSockets (#331) 2017-02-02 12:17:53 +06:00
lujji
f64935eb1d HTTP server (#324)
extras/httpd and http_server example
2017-01-27 14:38:01 +06:00
Tuan PM
ebfbc1144c Process recursive folder for spiffs images (#320)
* Process rercursive folder for spiffs images

* Flat file name from the directory structure

* change method to find '/' as the suggestion of @sheinz

* remove unused variable
2017-01-12 14:57:50 +02:00
Tuan PM
2b915c11c7 add some missing include & fixed display output on sh1104 (#319)
* add some missing include

* Fixed display on SH1106
2017-01-03 00:40:54 +02:00
Zaltora
5eae1664e5 Ina3221 (#318)
INA3221 driver + example
2016-12-29 19:45:25 +05:00
Zaltora
14c8ff57ca SPI3 support ssd1306 (#309)
SPI3 support, SH1106 port
2016-12-29 19:42:43 +05:00
Ruslan V. Uss
0b063730f3 Merge pull request #317 from UncleRus/fix_ms5611
Code style fixes for MS5611
2016-12-24 22:28:14 +05:00
UncleRus
b675ae6f29 Code style fixes for MS5611 2016-12-24 22:26:48 +05:00
mr-nice
34d783a289 Feature/ms561101ba03 (#308)
Driver for the ms561101ba03 barometric pressure sensor
2016-12-24 22:08:42 +05:00
Ruslan V. Uss
44124409e4 Merge pull request #315 from UncleRus/pca9685
Driver for PCA9685 + example
2016-12-21 10:38:00 +05:00
otopetrik
8f5d49de81 Allow changing write function of stdout (#304)
* Allow changing write function of stdout.

Required for stdout redirection.
Works on blocks, not chars - does _not_ use sdk_os_putc !
Should work even when linking with SPIFFS.
2016-12-19 20:55:26 +05:00
UncleRus
e96fb4242e Driver for PCA9685 + example 2016-12-19 05:53:07 +05:00
Ruslan V. Uss
97268eff29 Merge pull request #314 from UncleRus/rboot_cpp_fix
Fix #313
2016-12-17 21:10:06 +05:00
UncleRus
dc9b6a2988 Fix #313 2016-12-17 21:00:37 +05:00
Zaltora
7432c019f7 ssd1306 more functions (#310)
SSD1306 2D drawing/text functions, new example, builtin fonts support
2016-12-13 19:42:23 +06:00
Ruslan V. Uss
61c3d509e5 Merge pull request #302 from Zaltora/spi_fixes
Fixes SPI Bug(s)
2016-12-05 19:08:17 +06:00
lilian
8767a8a0a9 Readable option 2016-12-05 12:45:40 +01:00
lilian
47cd73ae02 Fix status with bus. 2016-12-05 12:05:18 +01:00
lilian
762f73515b Second bug. fix attempt. 2016-12-05 09:03:02 +01:00
Ruslan V. Uss
61caf8c9f4 Merge pull request #301 from UncleRus/gpio_intr
More convenient GPIO interrupt handlers
2016-12-04 09:52:20 +06:00
Ruslan V. Uss
1662892196 Merge pull request #303 from otopetrik/fix/sdk_system_rtc_mem
Fix ignored offset in rtc_mem access.
2016-12-02 02:10:48 +06:00
Oto Petřík
d50294b590 Fix ignored offset in rtc_mem access.
Fix sdk_system_rtc_mem_write and sdk_system_rtc_mem_read,
the functions did not use the user-provided offsets to rtc_mem.
Without using offset, rboot's rtcdata access, and its
temp_rom handling were broken.
2016-12-01 20:03:57 +01:00
lilian
199237ec6e Fixes Bug(s) 2016-11-30 08:19:25 +01:00
UncleRus
c3b6aff41d gpio_interrupt_handler() can now be overriden 2016-11-30 02:54:07 +05:00
UncleRus
a61af52d96 More convenient GPIO interrupt handlers 2016-11-30 01:07:46 +05:00
Ruslan V. Uss
53f85d0a2c Merge pull request #292 from UncleRus/extras/ads1115
ADS1113/ADS1114/ADS1115 I2C ADC driver + example
2016-11-29 11:37:50 +06:00
Ruslan V. Uss
b807eefeaf SSD1306 OLED Display driver refactored (#290)
* SSD1306 OLED Display driver SPI refactored:
- SPI connection support
- different display sizes support

* I2C address added to device descriptor

* Small fix
2016-11-29 00:57:22 +02:00
Ruslan V. Uss
2d933cf0e4 Merge pull request #296 from Zaltora/spi_features
Spi features
2016-11-27 20:32:55 +06:00
lilian
20ab2176fb fix tab 2016-11-26 15:14:40 +01:00
lilian
f19fdc37be adjustements 2016-11-26 12:26:42 +01:00
lilian
71bce674a0 Spi features 2016-11-26 12:19:53 +01:00
Ruslan V. Uss
4d00566421 Merge pull request #295 from sheinz/fix/ds18b20_negative_temp
ds18b20 fix for temperature below zero
2016-11-26 04:25:18 +06:00
sheinz
3ea18e74da ds18b20 fix for temperature below zero 2016-11-25 21:42:50 +02:00
Our Air Quality
5c885c7722 sysparam: export the 'compact' function, added it to the editor. (#213) 2016-11-24 00:41:39 +02:00
Ruslan V. Uss
e7e6df6358 HTTP parser intergation (#263)
* HTTP parser intergation

* include path fixed
2016-11-23 17:58:02 +02:00
Our Air Quality
df76e77598 open_esplibs libwpa: source code for os_xtensa.c (#283) 2016-11-23 17:56:34 +02:00
Our Air Quality
ca6c6e1d3e open_esplibs libnet80211: source code for sdk_cnx_node_search. (#280)
Also code for sdk_cnx_sta_leave, although disabled due to accessing static date, but it shows a reference to the netif->flags and the NETIF_FLAG_DHCP flag removed in lwip v2.
2016-11-23 17:56:05 +02:00
Our Air Quality
4f58059472 open_esplibs libwpa: source code for some struct netif paths. (#279)
Function sdk_eagle_auth_done accesses the netif-flags and the NETIF_FLAG_DHCP flag removed in lwip v2, and also the netif->ip_addr so is needed for lwip development.

Function sdk_wpa_config_bss accesses the netif->hwaddr.

Also code for a few other trivial functions that help debug the dhcpc paths.
2016-11-23 17:55:48 +02:00
Zaltora
0d9094e443 Bmp280 option (#220)
* bmp280 more options
add option to user for temp oversampling and possibility to skipp a specific measure

* Update bmp280.h

* quick fix oups

* less redundant terms
2016-11-23 17:16:03 +02:00
UncleRus
690a4793a6 ADS1113/ADS1114/ADS1115 I2C DAC driver + example 2016-11-22 20:10:03 +05:00
Ruslan V. Uss
6bd2d15d23 Merge pull request #288 from UncleRus/extras/mcp4725
Driver + example for MCP4725 12-bit I2C DAC
2016-11-22 02:46:48 +06:00
Our Air Quality
ec4368d9ae open_esplibs libnet80211: source code for sdk_wifi_station_start and stop. (#278)
The function sdk_wifi_station_start is one of two paths that allocates a lwip struct netif and also accesses the netif->hwaddr slot so this is required for lwip development.

Also code for sdk_wifi_station_stop and sdk_sta_status_set to better understand the status state.
2016-11-21 21:31:54 +02:00
UncleRus
16b38f94b0 Driver + example for MCP4725 12-bit I2C DAC 2016-11-21 21:28:08 +05:00
Our Air Quality
f10c6ed4ce open_esplibs libnet80211: source code for sdk_ieee80211_deliver_data. (#277) 2016-11-21 16:05:57 +02:00
Our Air Quality
b39df7f91e open_esplibs user_interface: source code for functions touching the struct netif. (#275)
Add source code for functions touching the struct netif to better support lwip development: sdk_wifi_get_ip_info, sdk_wifi_set_ip_info, sdk_wifi_get_macaddr, sdk_wifi_set_macaddr.

Also code for sdk_wifi_station_get_connect_status.

Also code for wifi_get_sleep_type and set_sleep_type, noting wifi_set_sleep_type returns a bool success flag, and implement wifi_get_sleep_type using sdk_pm_get_sleep_type.
2016-11-21 16:05:34 +02:00
sheinz
438a7582bf Revert "Travis running tests" (#291) 2016-11-21 11:39:13 +02:00
sheinz
6481f71ce0 Travis running tests on test servers (#272)
- README.md for adding test servers
 - Bash script for running tests on remote servers
 - Extend test_runner.py to flash using esptool.py
 - Python3.4 support. README.md update
2016-11-19 12:32:38 +02:00
Our Air Quality
1728ef3dfc Flush the uart tx fifo before a restart. (#274)
Also comment the point at which the bus clock that drives the uart changes on startup and comment out the change in the uart divisor. This at least allows a consistent uart baud rate during a restart if using the rate 115200.
2016-11-18 11:34:03 +02:00
Our Air Quality
0dadda86de wifi_get/set_sleep_type: add source code implementations plus fixes. (#218)
* wifi_set_sleep_type returns a bool success flag.

* wifi_get_sleep_type seemed useless, just returning an argument. Added an implementation using sdk_pm_get_sleep_type.
2016-11-14 12:13:38 +02:00
Our Air Quality
e48910ea3b Update and re-organise the sdk internal definitions. (#267) 2016-11-14 00:05:13 +02:00
637 changed files with 231932 additions and 50497 deletions

29
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "lwip/lwip"] [submodule "lwip/lwip"]
path = lwip/lwip path = lwip/lwip
url = https://github.com/SuperHouse/esp-lwip.git url = https://github.com/ourairquality/lwip.git
[submodule "extras/mbedtls/mbedtls"] [submodule "extras/mbedtls/mbedtls"]
path = extras/mbedtls/mbedtls path = extras/mbedtls/mbedtls
url = https://github.com/ARMmbed/mbedtls.git url = https://github.com/ARMmbed/mbedtls.git
@ -19,3 +19,30 @@
[submodule "tests/fs-test"] [submodule "tests/fs-test"]
path = tests/fs-test path = tests/fs-test
url = https://github.com/sheinz/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

View file

@ -2,7 +2,7 @@ language: c
sudo: false sudo: false
env: env:
# Target commit for https://github.com/pfalcon/esp-open-sdk/ # Target commit for https://github.com/pfalcon/esp-open-sdk/
OPENSDK_COMMIT=a48b12f OPENSDK_COMMIT=b069537
CROSS_ROOT="${HOME}/toolchain-${OPENSDK_COMMIT}" CROSS_ROOT="${HOME}/toolchain-${OPENSDK_COMMIT}"
CROSS_BINDIR="${CROSS_ROOT}/bin" CROSS_BINDIR="${CROSS_ROOT}/bin"
CROSS="ccache xtensa-lx106-elf-" CROSS="ccache xtensa-lx106-elf-"
@ -12,7 +12,6 @@ cache:
directories: directories:
- ${CROSS_ROOT} - ${CROSS_ROOT}
addons: addons:
ssh_known_hosts: 195.138.84.66
apt: apt:
packages: packages:
- make - make
@ -30,17 +29,15 @@ addons:
- libncurses5-dev - libncurses5-dev
- libexpat1-dev - libexpat1-dev
- python - python
- python-serial - python-pip
- sed - sed
- git - git
- help2man
- vim-common - vim-common
- zlib1g-dev
before_install: before_install:
- openssl aes-256-cbc -K $encrypted_709d8233e262_key -iv $encrypted_709d8233e262_iv - pip install --user pyserial
-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
- travis_wait 30 utils/travis_build/install_toolchain.sh - travis_wait 30 utils/travis_build/install_toolchain.sh
script: script:
@ -51,5 +48,3 @@ script:
- ( ${MAKE_CMD} ) || ( ${MAKE_CMD} V=1 ) - ( ${MAKE_CMD} ) || ( ${MAKE_CMD} V=1 )
# build bootloader # build bootloader
- make -C bootloader/ - make -C bootloader/
# run tests
- ./utils/travis_tests/run_tests.sh

View file

@ -1,440 +1,37 @@
The FreeRTOS.org source code is licensed by the *modified* GNU General Public The FreeRTOS kernel is released under the MIT open source license, the text of
License (GPL), text provided below. A special exception to the GPL is which is provided below.
included to allow you to distribute a combined work that includes FreeRTOS
without being obliged to provide the source code for any proprietary This license covers the FreeRTOS kernel source files, which are located in the
components. See the licensing section of http://www.FreeRTOS.org for full /FreeRTOS/Source directory of the official FreeRTOS kernel download. It also
details. The exception text is also included at the bottom of this file. 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).

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
@ -302,7 +260,7 @@ CRCB_t *pxCRCB;
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */ /* Is the co-routine waiting on an event also? */
if( pxCRCB->xEventListItem.pvContainer ) if( pxCRCB->xEventListItem.pxContainer )
{ {
( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
} }

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
/* Standard includes. */ /* Standard includes. */
#include <stdlib.h> #include <stdlib.h>
@ -81,11 +39,11 @@ task.h is included from an application file. */
#include "timers.h" #include "timers.h"
#include "event_groups.h" #include "event_groups.h"
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
header files above, but not in this file, in order to generate the correct for the header files above, but not in this file, in order to generate the
privileged Vs unprivileged linkage and placement. */ correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ #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 /* The following bit fields convey control information in a task's event list
item value. It is important they don't clash with the 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 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
#endif #endif
typedef struct xEventGroupDefinition typedef struct EventGroupDef_t
{ {
EventBits_t uxEventBits; EventBits_t uxEventBits;
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ 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. */ /* A StaticEventGroup_t object must be provided. */
configASSERT( pxEventGroupBuffer ); 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. */ /* 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 ) if( pxEventBits != NULL )
{ {
@ -160,10 +128,13 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
} }
else else
{ {
/* xEventGroupCreateStatic should only ever be called with
pxEventGroupBuffer pointing to a pre-allocated (compile time
allocated) StaticEventGroup_t variable. */
traceEVENT_GROUP_CREATE_FAILED(); traceEVENT_GROUP_CREATE_FAILED();
} }
return ( EventGroupHandle_t ) pxEventBits; return pxEventBits;
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
@ -175,8 +146,20 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
{ {
EventGroup_t *pxEventBits; EventGroup_t *pxEventBits;
/* Allocate the event group. */ /* Allocate the event group. Justification for MISRA deviation as
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); 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 ) if( pxEventBits != NULL )
{ {
@ -196,10 +179,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
} }
else 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 */ #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 xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
{ {
EventBits_t uxOriginalBitValue, uxReturn; EventBits_t uxOriginalBitValue, uxReturn;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventGroup_t *pxEventBits = xEventGroup;
BaseType_t xAlreadyYielded; BaseType_t xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
@ -259,6 +242,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
/* The rendezvous bits were not set, but no block time was /* The rendezvous bits were not set, but no block time was
specified - just return the current event bit value. */ specified - just return the current event bit value. */
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
xTimeoutOccurred = pdTRUE;
} }
} }
} }
@ -317,13 +301,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
/* Prevent compiler warnings when trace macros are not used. */
( void ) xTimeoutOccurred;
return uxReturn; return uxReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) 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; EventBits_t uxReturn, uxControlBits = 0;
BaseType_t xWaitConditionMet, xAlreadyYielded; BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
@ -368,6 +355,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
/* The wait condition has not been met, but no block time was /* The wait condition has not been met, but no block time was
specified, so just return the current value. */ specified, so just return the current value. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
xTimeoutOccurred = pdTRUE;
} }
else else
{ {
@ -449,11 +437,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
xTimeoutOccurred = pdTRUE;
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
/* Prevent compiler warnings when trace macros are not used. */
xTimeoutOccurred = pdFALSE;
} }
else else
{ {
@ -465,13 +451,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
/* Prevent compiler warnings when trace macros are not used. */
( void ) xTimeoutOccurred;
return uxReturn; return uxReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
{ {
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventGroup_t *pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
/* Check the user is not attempting to clear the bits used by the kernel /* Check the user is not attempting to clear the bits used by the kernel
@ -503,7 +492,7 @@ EventBits_t uxReturn;
BaseType_t xReturn; BaseType_t xReturn;
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); 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; return xReturn;
} }
@ -514,7 +503,7 @@ EventBits_t uxReturn;
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
{ {
UBaseType_t uxSavedInterruptStatus; UBaseType_t uxSavedInterruptStatus;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventGroup_t const * const pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
@ -524,16 +513,16 @@ EventBits_t uxReturn;
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return uxReturn; 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 ) EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
{ {
ListItem_t *pxListItem, *pxNext; ListItem_t *pxListItem, *pxNext;
ListItem_t const *pxListEnd; ListItem_t const *pxListEnd;
List_t *pxList; List_t const * pxList;
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventGroup_t *pxEventBits = xEventGroup;
BaseType_t xMatchFound = pdFALSE; BaseType_t xMatchFound = pdFALSE;
/* Check the user is not attempting to set the bits used by the kernel /* 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 ); configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
pxList = &( pxEventBits->xTasksWaitingForBits ); 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(); vTaskSuspendAll();
{ {
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); 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 eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
that is was unblocked due to its required bits matching, rather that is was unblocked due to its required bits matching, rather
than because it timed out. */ 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 /* Move onto the next list item. Note pxListItem->pxNext is not
@ -623,7 +612,7 @@ BaseType_t xMatchFound = pdFALSE;
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) void vEventGroupDelete( EventGroupHandle_t xEventGroup )
{ {
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventGroup_t *pxEventBits = xEventGroup;
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
vTaskSuspendAll(); vTaskSuspendAll();
@ -634,8 +623,8 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
{ {
/* Unblock the task, returning 0 as the event list is being deleted /* Unblock the task, returning 0 as the event list is being deleted
and cannot therefore have any bits set. */ and cannot therefore have any bits set. */
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
} }
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
@ -667,7 +656,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
an interrupt. */ an interrupt. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) 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. */ an interrupt. */
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) 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; BaseType_t xReturn;
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); 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; return xReturn;
} }
@ -734,7 +723,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
{ {
UBaseType_t xReturn; 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 ) if( xEventGroup == NULL )
{ {
@ -748,5 +737,17 @@ BaseType_t xWaitConditionMet = pdFALSE;
return xReturn; 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 */
/*-----------------------------------------------------------*/

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#define 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. #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#if configMAX_PRIORITIES < 1
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
#endif
#ifndef configUSE_PREEMPTION #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. #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 #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. #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 #endif
#ifndef configMAX_PRIORITIES
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
#endif
#ifndef configUSE_CO_ROUTINES #ifndef configUSE_CO_ROUTINES
#define configUSE_CO_ROUTINES 0 #define configUSE_CO_ROUTINES 0
#endif #endif
@ -198,6 +156,10 @@ extern "C" {
#define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_uxTaskGetStackHighWaterMark 0
#endif #endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark2
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
#endif
#ifndef INCLUDE_eTaskGetState #ifndef INCLUDE_eTaskGetState
#define INCLUDE_eTaskGetState 0 #define INCLUDE_eTaskGetState 0
#endif #endif
@ -396,6 +358,14 @@ extern "C" {
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif #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 #ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a /* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
@ -408,6 +378,14 @@ extern "C" {
#define configCHECK_FOR_STACK_OVERFLOW 0 #define configCHECK_FOR_STACK_OVERFLOW 0
#endif #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. */ /* The following event macros are embedded in the kernel API calls. */
#ifndef traceMOVED_TASK_TO_READY_STATE #ifndef traceMOVED_TASK_TO_READY_STATE
@ -474,6 +452,10 @@ extern "C" {
#define traceQUEUE_PEEK( pxQueue ) #define traceQUEUE_PEEK( pxQueue )
#endif #endif
#ifndef traceQUEUE_PEEK_FAILED
#define traceQUEUE_PEEK_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_PEEK_FROM_ISR #ifndef traceQUEUE_PEEK_FROM_ISR
#define traceQUEUE_PEEK_FROM_ISR( pxQueue ) #define traceQUEUE_PEEK_FROM_ISR( pxQueue )
#endif #endif
@ -658,6 +640,58 @@ extern "C" {
#define traceTASK_NOTIFY_GIVE_FROM_ISR() #define traceTASK_NOTIFY_GIVE_FROM_ISR()
#endif #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 #ifndef configGENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 0 #define configGENERATE_RUN_TIME_STATS 0
#endif #endif
@ -708,6 +742,10 @@ extern "C" {
#define configUSE_TICKLESS_IDLE 0 #define configUSE_TICKLESS_IDLE 0
#endif #endif
#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING
#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x )
#endif
#ifndef configPRE_SLEEP_PROCESSING #ifndef configPRE_SLEEP_PROCESSING
#define configPRE_SLEEP_PROCESSING( x ) #define configPRE_SLEEP_PROCESSING( x )
#endif #endif
@ -724,6 +762,10 @@ extern "C" {
#define portTASK_USES_FLOATING_POINT() #define portTASK_USES_FLOATING_POINT()
#endif #endif
#ifndef portALLOCATE_SECURE_CONTEXT
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#endif
#ifndef configUSE_TIME_SLICING #ifndef configUSE_TIME_SLICING
#define configUSE_TIME_SLICING 1 #define configUSE_TIME_SLICING 1
#endif #endif
@ -768,6 +810,10 @@ extern "C" {
#define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TASK_NOTIFICATIONS 1
#endif #endif
#ifndef configUSE_POSIX_ERRNO
#define configUSE_POSIX_ERRNO 0
#endif
#ifndef portTICK_TYPE_IS_ATOMIC #ifndef portTICK_TYPE_IS_ATOMIC
#define portTICK_TYPE_IS_ATOMIC 0 #define portTICK_TYPE_IS_ATOMIC 0
#endif #endif
@ -782,6 +828,19 @@ extern "C" {
#define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1
#endif #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. */ /* Sanity check the configuration. */
#if( configUSE_TICKLESS_IDLE != 0 ) #if( configUSE_TICKLESS_IDLE != 0 )
#if( INCLUDE_vTaskSuspend != 1 ) #if( INCLUDE_vTaskSuspend != 1 )
@ -797,6 +856,10 @@ extern "C" {
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes #error configUSE_MUTEXES must be set to 1 to use recursive mutexes
#endif #endif
#ifndef configINITIAL_TICK_COUNT
#define configINITIAL_TICK_COUNT 0
#endif
#if( portTICK_TYPE_IS_ATOMIC == 0 ) #if( portTICK_TYPE_IS_ATOMIC == 0 )
/* Either variables of tick type cannot be read atomically, or /* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when 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 #define configENABLE_BACKWARD_COMPATIBILITY 1
#endif #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 #if configENABLE_BACKWARD_COMPATIBILITY == 1
#define eTaskStateGet eTaskGetState #define eTaskStateGet eTaskGetState
#define portTickType TickType_t #define portTickType TickType_t
@ -847,6 +936,10 @@ V8 if desired. */
#define pdTASK_CODE TaskFunction_t #define pdTASK_CODE TaskFunction_t
#define xListItem ListItem_t #define xListItem ListItem_t
#define xList List_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 */ #endif /* configENABLE_BACKWARD_COMPATIBILITY */
#if( configUSE_ALTERNATIVE_API != 0 ) #if( configUSE_ALTERNATIVE_API != 0 )
@ -861,6 +954,75 @@ point support. */
#define configUSE_TASK_FPU_SUPPORT 1 #define configUSE_TASK_FPU_SUPPORT 1
#endif #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 * In line with software engineering best practice, FreeRTOS implements a strict
* data hiding policy, so the real structures used by FreeRTOS to maintain the * data hiding policy, so the real structures used by FreeRTOS to maintain the
@ -873,25 +1035,40 @@ point support. */
*/ */
struct xSTATIC_LIST_ITEM struct xSTATIC_LIST_ITEM
{ {
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
TickType_t xDummy1; 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; typedef struct xSTATIC_LIST_ITEM StaticListItem_t;
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
struct xSTATIC_MINI_LIST_ITEM struct xSTATIC_MINI_LIST_ITEM
{ {
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
TickType_t xDummy1; TickType_t xDummy1;
void *pvDummy2[ 2 ]; #endif
TickType_t xDummy2;
void *pvDummy3[ 2 ];
}; };
typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t;
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
typedef struct xSTATIC_LIST typedef struct xSTATIC_LIST
{ {
UBaseType_t uxDummy1; #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
void *pvDummy2; TickType_t xDummy1;
StaticMiniListItem_t xDummy3; #endif
UBaseType_t uxDummy2;
void *pvDummy3;
StaticMiniListItem_t xDummy4;
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 )
TickType_t xDummy5;
#endif
} StaticList_t; } StaticList_t;
/* /*
@ -917,7 +1094,7 @@ typedef struct xSTATIC_TCB
UBaseType_t uxDummy5; UBaseType_t uxDummy5;
void *pxDummy6; void *pxDummy6;
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
#if ( portSTACK_GROWTH > 0 ) #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
void *pxDummy8; void *pxDummy8;
#endif #endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 ) #if ( portCRITICAL_NESTING_IN_TCB == 1 )
@ -945,10 +1122,16 @@ typedef struct xSTATIC_TCB
uint32_t ulDummy18; uint32_t ulDummy18;
uint8_t ucDummy19; uint8_t ucDummy19;
#endif #endif
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
uint8_t uxDummy20; uint8_t uxDummy20;
#endif #endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDummy21;
#endif
#if ( configUSE_POSIX_ERRNO == 1 )
int iDummy22;
#endif
} StaticTask_t; } StaticTask_t;
/* /*
@ -1043,18 +1226,42 @@ typedef struct xSTATIC_TIMER
void *pvDummy1; void *pvDummy1;
StaticListItem_t xDummy2; StaticListItem_t xDummy2;
TickType_t xDummy3; TickType_t xDummy3;
UBaseType_t uxDummy4; void *pvDummy5;
void *pvDummy5[ 2 ]; TaskFunction_t pvDummy6;
#if( configUSE_TRACE_FACILITY == 1 ) #if( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxDummy6; UBaseType_t uxDummy7;
#endif
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
uint8_t ucDummy7;
#endif #endif
uint8_t ucDummy8;
} StaticTimer_t; } 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -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 #ifndef __DEFAULT_FREERTOS_CONFIG_H
#define __DEFAULT_FREERTOS_CONFIG_H #define __DEFAULT_FREERTOS_CONFIG_H
@ -47,7 +63,7 @@
#define configTICK_RATE_HZ ( ( TickType_t ) 100 ) #define configTICK_RATE_HZ ( ( TickType_t ) 100 )
#endif #endif
#ifndef configMAX_PRIORITIES #ifndef configMAX_PRIORITIES
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) #define configMAX_PRIORITIES ( 15 )
#endif #endif
#ifndef configMINIMAL_STACK_SIZE #ifndef configMINIMAL_STACK_SIZE
#define configMINIMAL_STACK_SIZE ( ( unsigned short )256 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short )256 )
@ -81,6 +97,9 @@
#ifndef configCHECK_FOR_STACK_OVERFLOW #ifndef configCHECK_FOR_STACK_OVERFLOW
#define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_FOR_STACK_OVERFLOW 2
#endif #endif
#ifndef configUSE_RECURSIVE_MUTEXES
#define configUSE_RECURSIVE_MUTEXES 1
#endif
#ifndef configUSE_MUTEXES #ifndef configUSE_MUTEXES
#define configUSE_MUTEXES 1 #define configUSE_MUTEXES 1
#endif #endif
@ -108,6 +127,10 @@
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#endif #endif
#ifndef configUSE_NEWLIB_REENTRANT
#define configUSE_NEWLIB_REENTRANT 1
#endif
/* Set the following definitions to 1 to include the API function, or zero /* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */ to exclude the API function. */
#ifndef INCLUDE_vTaskPrioritySet #ifndef INCLUDE_vTaskPrioritySet
@ -144,5 +167,10 @@ to exclude the API function. */
#define configENABLE_BACKWARD_COMPATIBILITY 0 #define configENABLE_BACKWARD_COMPATIBILITY 0
#endif #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 */ #endif /* __DEFAULT_FREERTOS_CONFIG_H */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef CO_ROUTINE_H #ifndef CO_ROUTINE_H
#define CO_ROUTINE_H #define CO_ROUTINE_H

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef DEPRECATED_DEFINITIONS_H #ifndef DEPRECATED_DEFINITIONS_H
#define DEPRECATED_DEFINITIONS_H #define DEPRECATED_DEFINITIONS_H

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef EVENT_GROUPS_H #ifndef EVENT_GROUPS_H
#define EVENT_GROUPS_H #define EVENT_GROUPS_H
@ -120,7 +78,8 @@ extern "C" {
* \defgroup EventGroupHandle_t EventGroupHandle_t * \defgroup EventGroupHandle_t EventGroupHandle_t
* \ingroup EventGroup * \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 * 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 * \ingroup EventGroup
*/ */
#if( configUSE_TRACE_FACILITY == 1 ) #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 #else
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
#endif #endif
@ -786,6 +745,7 @@ void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToCl
#if (configUSE_TRACE_FACILITY == 1) #if (configUSE_TRACE_FACILITY == 1)
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
/* /*
* This is the list implementation used by the scheduler. While it is tailored * 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. * Definition of the only type of object that a list can contain.
*/ */
struct xLIST;
struct xLIST_ITEM 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. */ 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 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. */ 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 * 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. */ 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. */ 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 typedef struct xLIST
{ {
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 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 (). */ 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. */ 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. */ 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 * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
* \ingroup LinkedList * \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. * 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. * @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. * @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). * 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. * @param pxListItem The list item being queried.
* @return A pointer to the List_t object that references the pxListItem * @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 * This provides a crude means of knowing if a list has been initialised, as

View 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 ) */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
/* /*
* When the MPU is used the standard (non MPU) API functions are mapped to * When the MPU is used the standard (non MPU) API functions are mapped to
@ -79,99 +37,121 @@
#ifndef MPU_PROTOTYPES_H #ifndef MPU_PROTOTYPES_H
#define MPU_PROTOTYPES_H #define MPU_PROTOTYPES_H
/* MPU versions of tasks.h API function. */ /* 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 ); 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 ); 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 ); BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ); void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelay( const TickType_t xTicksToDelay ); void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ); void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ); void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t xTask ); BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ); UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ); void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskResume( TaskHandle_t xTaskToResume ); void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskStartScheduler( void ); void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspendAll( void ); void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskResumeAll( void ); void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTaskGetTickCount( void ); BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ); TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ); void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ); BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskList( char * pcWriteBuffer ); TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ); UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ); TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ); BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskIncrementTick( void ); BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ); uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskMissedYield( void ); TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGetSchedulerState( void ); 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. */ /* 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 ); BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ); BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ); BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ); BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueDelete( QueueHandle_t xQueue ); UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ); UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ); void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ); QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ); QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ); QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ); TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ); BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ); BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ); void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ); void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) 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 ); const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ); QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); 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;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ); BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ); BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ); QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ); BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ); 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 */ #endif /* MPU_PROTOTYPES_H */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef MPU_WRAPPERS_H #ifndef MPU_WRAPPERS_H
#define MPU_WRAPPERS_H #define MPU_WRAPPERS_H
@ -109,6 +67,7 @@ only for ports that are using the MPU. */
#define pcTaskGetName MPU_pcTaskGetName #define pcTaskGetName MPU_pcTaskGetName
#define xTaskGetHandle MPU_xTaskGetHandle #define xTaskGetHandle MPU_xTaskGetHandle
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
@ -118,6 +77,7 @@ only for ports that are using the MPU. */
#define uxTaskGetSystemState MPU_uxTaskGetSystemState #define uxTaskGetSystemState MPU_uxTaskGetSystemState
#define vTaskList MPU_vTaskList #define vTaskList MPU_vTaskList
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter
#define xTaskGenericNotify MPU_xTaskGenericNotify #define xTaskGenericNotify MPU_xTaskGenericNotify
#define xTaskNotifyWait MPU_xTaskNotifyWait #define xTaskNotifyWait MPU_xTaskNotifyWait
#define ulTaskNotifyTake MPU_ulTaskNotifyTake #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. */ /* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueGenericSend MPU_xQueueGenericSend #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 uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define vQueueDelete MPU_vQueueDelete #define vQueueDelete MPU_vQueueDelete
@ -164,6 +126,7 @@ only for ports that are using the MPU. */
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
#define pcTimerGetName MPU_pcTimerGetName #define pcTimerGetName MPU_pcTimerGetName
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
#define xTimerGetPeriod MPU_xTimerGetPeriod #define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
#define xTimerGenericCommand MPU_xTimerGenericCommand #define xTimerGenericCommand MPU_xTimerGenericCommand
@ -177,14 +140,35 @@ only for ports that are using the MPU. */
#define xEventGroupSync MPU_xEventGroupSync #define xEventGroupSync MPU_xEventGroupSync
#define vEventGroupDelete MPU_vEventGroupDelete #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_FUNCTION
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#define FREERTOS_SYSTEM_CALL
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */ /* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) #define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
@ -192,6 +176,7 @@ only for ports that are using the MPU. */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA #define PRIVILEGED_DATA
#define FREERTOS_SYSTEM_CALL
#define portUSING_MPU_WRAPPERS 0 #define portUSING_MPU_WRAPPERS 0
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Portable layer API. Each function must be defined for each port. * 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 #define portNUM_CONFIGURABLE_REGIONS 1
#endif #endif
#ifndef portHAS_STACK_OVERFLOW_CHECKING
#define portHAS_STACK_OVERFLOW_CHECKING 0
#endif
#ifndef portARCH_NAME
#define portARCH_NAME NULL
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -139,9 +105,17 @@ extern "C" {
* *
*/ */
#if( portUSING_MPU_WRAPPERS == 1 ) #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; StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
#endif
#else #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; StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
#endif
#endif #endif
/* Used by heap_5.c. */ /* Used by heap_5.c. */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef PROJDEFS_H #ifndef PROJDEFS_H
#define PROJDEFS_H #define PROJDEFS_H
@ -155,6 +113,11 @@ itself. */
#define pdFREERTOS_LITTLE_ENDIAN 0 #define pdFREERTOS_LITTLE_ENDIAN 0
#define pdFREERTOS_BIG_ENDIAN 1 #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 */ #endif /* PROJDEFS_H */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef QUEUE_H #ifndef QUEUE_H
@ -79,27 +37,29 @@
extern "C" { extern "C" {
#endif #endif
#include "task.h"
/** /**
* Type by which queues are referenced. For example, a call to xQueueCreate() * 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 * returns an QueueHandle_t variable that can then be used as a parameter to
* xQueueSend(), xQueueReceive(), etc. * 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 * Type by which queue sets are referenced. For example, a call to
* xQueueCreateSet() returns an xQueueSet variable that can then be used as a * xQueueCreateSet() returns an xQueueSet variable that can then be used as a
* parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
*/ */
typedef void * QueueSetHandle_t; typedef struct QueueDefinition * QueueSetHandle_t;
/** /**
* Queue sets can contain both queues and semaphores, so the * Queue sets can contain both queues and semaphores, so the
* QueueSetMemberHandle_t is defined as a type to be used where a parameter or * 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. * 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. */ /* For internal use only. */
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) #define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
@ -282,8 +242,6 @@ typedef void * QueueSetMemberHandle_t;
); );
* </pre> * </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 * 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 * reference. This function must not be called from an interrupt service
* routine. See xQueueSendFromISR () for an alternative which may be used * 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> * <pre>
BaseType_t xQueuePeek( BaseType_t xQueuePeek(
QueueHandle_t xQueue, QueueHandle_t xQueue,
void *pvBuffer, void * const pvBuffer,
TickType_t xTicksToWait TickType_t xTicksToWait
);</pre> );</pre>
* *
* This is a macro that calls the xQueueGenericReceive() function.
*
* Receive an item from a queue without removing the item from the queue. * 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 * 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 * 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. // ... Rest of task code.
} }
</pre> </pre>
* \defgroup xQueueReceive xQueueReceive * \defgroup xQueuePeek xQueuePeek
* \ingroup QueueManagement * \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 * queue. h
@ -829,8 +785,6 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
TickType_t xTicksToWait TickType_t xTicksToWait
);</pre> );</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 * 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 * adequate size must be provided. The number of bytes copied into the buffer
* was defined when the queue was created. * was defined when the queue was created.
@ -911,106 +865,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIV
* \defgroup xQueueReceive xQueueReceive * \defgroup xQueueReceive xQueueReceive
* \ingroup QueueManagement * \ingroup QueueManagement
*/ */
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/**
* 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;
/** /**
* queue. h * 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 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 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; 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 * For internal use only. Use xSemaphoreTakeMutexRecursive() or
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly. * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
*/ */
BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; 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 * 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. * preferably in ROM/Flash), not on the stack.
*/ */
#if( configQUEUE_REGISTRY_SIZE > 0 ) #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 #endif
/* /*

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef SEMAPHORE_H #ifndef SEMAPHORE_H
#define SEMAPHORE_H #define SEMAPHORE_H
@ -328,7 +286,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup xSemaphoreTake xSemaphoreTake * \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores * \ingroup Semaphores
*/ */
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
/** /**
* semphr. h * semphr. h
@ -1154,6 +1112,17 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/ */
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) #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 * semphr.h
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre> * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef STACK_MACROS_H #ifndef STACK_MACROS_H
#define STACK_MACROS_H #define STACK_MACROS_H

View 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 ) */

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef INC_TASK_H #ifndef INC_TASK_H
@ -85,11 +43,19 @@ extern "C" {
* MACROS AND DEFINITIONS * MACROS AND DEFINITIONS
*----------------------------------------------------------*/ *----------------------------------------------------------*/
#define tskKERNEL_VERSION_NUMBER "V9.0.0" #define tskKERNEL_VERSION_NUMBER "V10.2.0"
#define tskKERNEL_VERSION_MAJOR 9 #define tskKERNEL_VERSION_MAJOR 10
#define tskKERNEL_VERSION_MINOR 0 #define tskKERNEL_VERSION_MINOR 2
#define tskKERNEL_VERSION_BUILD 0 #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 * task. h
* *
@ -100,7 +66,8 @@ extern "C" {
* \defgroup TaskHandle_t TaskHandle_t * \defgroup TaskHandle_t TaskHandle_t
* \ingroup Tasks * \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 * Defines the prototype to which the application task hook function must
@ -155,11 +122,14 @@ typedef struct xTASK_PARAMETERS
{ {
TaskFunction_t pvTaskCode; TaskFunction_t pvTaskCode;
const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 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; void *pvParameters;
UBaseType_t uxPriority; UBaseType_t uxPriority;
StackType_t *puxStackBuffer; StackType_t *puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
StaticTask_t * const pxTaskBuffer;
#endif
} TaskParameters_t; } TaskParameters_t;
/* Used with the uxTaskGetSystemState() function to return the state of each task /* 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. */ 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. */ 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. */ 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; } TaskStatus_t;
/* Possible return values for eTaskConfirmSleepModeStatus(). */ /* Possible return values for eTaskConfirmSleepModeStatus(). */
@ -269,7 +239,7 @@ is used in assert() statements. */
BaseType_t xTaskCreate( BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode, TaskFunction_t pvTaskCode,
const char * const pcName, const char * const pcName,
uint16_t usStackDepth, configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters, void *pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask TaskHandle_t *pvCreatedTask
@ -358,11 +328,11 @@ is used in assert() statements. */
*/ */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, BaseType_t xTaskCreate( 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 uint16_t usStackDepth, const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, 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 #endif
/** /**
@ -414,9 +384,9 @@ is used in assert() statements. */
* memory to be allocated dynamically. * memory to be allocated dynamically.
* *
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will
* be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer * be created and a handle to the created task is returned. If either
* are NULL then the task will not be created and * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and
* errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned. * NULL is returned.
* *
* Example usage: * Example usage:
<pre> <pre>
@ -474,12 +444,12 @@ is used in assert() statements. */
*/ */
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, 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, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
StackType_t * const puxStackBuffer, 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 */ #endif /* configSUPPORT_STATIC_ALLOCATION */
/** /**
@ -487,6 +457,8 @@ is used in assert() statements. */
*<pre> *<pre>
BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</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 * xTaskCreateRestricted() should only be used in systems that include an MPU
* implementation. * implementation.
* *
@ -494,6 +466,9 @@ is used in assert() statements. */
* The function parameters define the memory regions and associated access * The function parameters define the memory regions and associated access
* permissions allocated to the task. * 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 * @param pxTaskDefinition Pointer to a structure that contains a member
* for each of the normal xTaskCreate() parameters (see the xTaskCreate() API * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
* documentation) plus an optional stack buffer and the memory region * 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; BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif #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 * task. h
*<pre> *<pre>
@ -780,7 +843,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
/** /**
* task. h * 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. * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.
* See the configuration section for more information. * See the configuration section for more information.
@ -823,15 +886,15 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
* \defgroup uxTaskPriorityGet uxTaskPriorityGet * \defgroup uxTaskPriorityGet uxTaskPriorityGet
* \ingroup TaskCtrl * \ingroup TaskCtrl
*/ */
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
/** /**
* task. h * 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. * 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 * 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 * 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. * 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. * @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. * 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; 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 /* 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, 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 so the following two prototypes will cause a compilation error. This can be
@ -1389,9 +1485,20 @@ constant. */
* task.h * task.h
* <pre>void xTaskGetApplicationTaskTag( TaskHandle_t xTask );</pre> * <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; 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 /* configUSE_APPLICATION_TASK_TAG ==1 */
#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ #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. */ 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 * task. h
* <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE> * <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 * Removes a task from both the specified event list and the list of blocked
* tasks, and places it on a ready queue. * 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 * if either an event occurs to unblock a task, or the block timeout period
* expires. * expires.
* *
* xTaskRemoveFromEventList() is used when the event list is in task priority * 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 * 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. * 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 * 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 * priority. In this case the event list item value is updated to the value
* passed in the xItemValue parameter. * passed in the xItemValue parameter.
@ -2157,7 +2294,7 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi
* making the call, otherwise pdFALSE. * making the call, otherwise pdFALSE.
*/ */
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; 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 * 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 * 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. * 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 * 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; 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. * 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; 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 * 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, * 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. * 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 * 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. * 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 #ifdef __cplusplus
} }

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#ifndef TIMERS_H #ifndef TIMERS_H
@ -75,10 +33,10 @@
#error "include FreeRTOS.h must appear in source files before include timers.h" #error "include FreeRTOS.h must appear in source files before include timers.h"
#endif #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. */ happens to also be including task.h. */
#include "task.h" #include "task.h"
/*lint +e537 */ /*lint -restore */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { 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 * reference the subject timer in calls to other software timer API functions
* (for example, xTimerStart(), xTimerReset(), etc.). * (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. * Defines the prototype to which timer callback functions must conform.
@ -266,11 +225,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, 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 #endif
/** /**
@ -396,12 +355,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, 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 */ #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. */ 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 ); * 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 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; 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
#include <stdlib.h> #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 /* 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 end of the list. To initialise the list the list end is inserted
as the only list entry. */ 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 /* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */ 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 /* The list end next and previous pointers point to itself so we know
when the list is empty. */ 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.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 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; pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
@ -104,7 +62,7 @@ void vListInitialise( List_t * const pxList )
void vListInitialiseItem( ListItem_t * const pxItem ) void vListInitialiseItem( ListItem_t * const pxItem )
{ {
/* Make sure the list item is not recorded as being on a list. */ /* 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 /* Write known values into the list item if
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
@ -136,7 +94,7 @@ ListItem_t * const pxIndex = pxList->pxIndex;
pxIndex->pxPrevious = pxNewListItem; pxIndex->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */ /* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
} }
@ -156,7 +114,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
/* Insert the new list item into the list, sorted in xItemValue order. /* 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 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 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 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 the iteration loop below will not end. Therefore the value is checked
@ -169,18 +127,18 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
{ {
/* *** NOTE *********************************************************** /* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are 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! more tips, and ensure configASSERT() is defined!
http://www.freertos.org/a00110.html#configASSERT https://www.freertos.org/a00110.html#configASSERT
1) Stack overflow - 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 2) Incorrect interrupt priority assignment, especially on Cortex-M
parts where numerically high priority values denote low actual parts where numerically high priority values denote low actual
interrupt priorities, which can seem counter intuitive. See 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 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 3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt. not end in "FromISR" from an interrupt.
@ -189,7 +147,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
before vTaskStartScheduler() has been called?). 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 /* There is nothing to do here, just iterating to the wanted
insertion position. */ 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 /* Remember which list the item is in. This allows fast removal of the
item later. */ item later. */
pxNewListItem->pvContainer = ( void * ) pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( 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 /* The list item knows which list it is in. Obtain the list from the list
item. */ item. */
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; List_t * const pxList = pxItemToRemove->pxContainer;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
@ -231,7 +189,7 @@ List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
pxItemToRemove->pvContainer = NULL; pxItemToRemove->pxContainer = NULL;
( pxList->uxNumberOfItems )--; ( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;

View file

@ -1,66 +1,30 @@
/* /*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. *
* 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
* FreeRTOS provides completely free yet professionally developed, * * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* robust, strictly quality controlled, supported, and cross * * the Software, and to permit persons to whom the Software is furnished to do so,
* platform software that has become a de facto standard. * * subject to the following conditions:
* * *
* Help yourself get started quickly and support the FreeRTOS * * The above copyright notice and this permission notice shall be included in all
* project by purchasing a FreeRTOS tutorial book, reference * * copies or substantial portions of the Software. If you wish to use our Amazon
* manual, or both from: http://www.FreeRTOS.org/Documentation * * FreeRTOS name, please do so in a fair use way that does not cause confusion.
* * *
* Thank you! * * 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
This file is part of the FreeRTOS distribution. * 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.
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 * http://www.FreeRTOS.org
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. * http://aws.amazon.com/freertos
*
>>! NOTE: The modification to the GPL is included to allow you to distribute * 1 tab == 4 spaces!
>>! 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!
*/
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Implementation of functions defined in portable.h for ESP8266 * Implementation of functions defined in portable.h for ESP8266
@ -73,10 +37,12 @@
#include <malloc.h> #include <malloc.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <xtensa_ops.h> #include <xtensa_ops.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "queue.h"
#include "xtensa_rtos.h" #include "xtensa_rtos.h"
unsigned cpu_sr; unsigned cpu_sr;
@ -91,6 +57,13 @@ char level1_int_disabled;
*/ */
void *xPortSupervisorStackPointer; void *xPortSupervisorStackPointer;
void vAssertCalled(const char * pcFile, unsigned long ulLine)
{
printf("rtos assert %s %lu\n", pcFile, ulLine);
abort();
//for (;;);
}
/* /*
* Stack initialization * Stack initialization
*/ */
@ -100,7 +73,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunctio
portSTACK_TYPE *sp, *tp; portSTACK_TYPE *sp, *tp;
/* Create interrupt stack frame aligned to 16 byte boundary */ /* 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) */ /* Clear the entire frame (do not use memset() because we don't depend on C library) */
for (tp = sp; tp <= pxTopOfStack; ++tp) 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_soft_sv;
static int pending_maclayer_sv; static int pending_maclayer_sv;
/* PendSV is called in place of vPortYield() to request a supervisor /*
call. * 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
The portYIELD macro calls pendSV if it's a software request. * are enabled which might be after exiting the critical region below.
*
The libpp and libudhcp libraries also call this function, assuming * The wdev NMI calls this function from pp_post() with SVC_MACLayer to set a
always with arg==2 (but maybe sometimes with arg==1?) * pending interrupt service callback which flushs the queue of messages that
* the NMI stashes away. This interrupt will be triggered after the return from
In the original esp_iot_rtos_sdk implementation, arg was a char. Using an * the NMI and when interrupts are enabled. The NMI can not touch the FreeRTOS
enum is ABI-compatible, though. * 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) void IRAM PendSV(enum SVC_ReqType req)
{ {
if (req == SVC_Software) {
vPortEnterCritical(); vPortEnterCritical();
if(req == SVC_Software)
{
pending_soft_sv = 1; pending_soft_sv = 1;
}
else if(req == SVC_MACLayer)
pending_maclayer_sv= 1;
WSR(BIT(INUM_SOFT), interrupt); WSR(BIT(INUM_SOFT), interrupt);
vPortExitCritical(); 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 /* 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); extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void);
void IRAM SV_ISR(void) void IRAM SV_ISR(void *arg)
{ {
portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE ;
if(pending_maclayer_sv) if (pending_maclayer_sv) {
{
xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl(); xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
pending_maclayer_sv = 0; pending_maclayer_sv = 0;
} }
if( xHigherPriorityTaskWoken || pending_soft_sv) if (xHigherPriorityTaskWoken || pending_soft_sv) {
{
sdk__xt_timer_int1(); sdk__xt_timer_int1();
pending_soft_sv = 0; pending_soft_sv = 0;
} }
@ -170,14 +140,9 @@ void IRAM SV_ISR(void)
void xPortSysTickHandle (void) void xPortSysTickHandle (void)
{ {
//CloseNMI(); if (xTaskIncrementTick() != pdFALSE) {
{
if(xTaskIncrementTick() !=pdFALSE )
{
vTaskSwitchContext(); vTaskSwitchContext();
} }
}
//OpenNMI();
} }
/* /*
@ -185,11 +150,11 @@ void xPortSysTickHandle (void)
*/ */
portBASE_TYPE xPortStartScheduler( 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)); _xt_isr_unmask(BIT(INUM_SOFT));
/* Initialize system tick timer interrupt and schedule the first tick. */ /* 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)); _xt_isr_unmask(BIT(INUM_TICK));
sdk__xt_tick_timer_init(); sdk__xt_tick_timer_init();
@ -221,8 +186,10 @@ size_t xPortGetFreeHeapSize( void )
uint32_t brk_val = (uint32_t) sbrk(0); uint32_t brk_val = (uint32_t) sbrk(0);
intptr_t sp = (intptr_t)xPortSupervisorStackPointer; intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
if(sp == 0) /* scheduler not started */ if (sp == 0) {
/* scheduler not started */
SP(sp); SP(sp);
}
return sp - brk_val + mi.fordblks; 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; static unsigned portBASE_TYPE uxCriticalNesting = 0;
/* These nested vPortEnter/ExitCritical macros are called by SDK /* 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 * It may be possible to replace the global nesting count variable
* with a save/restore of interrupt level, although it's difficult as * with a save/restore of interrupt level, although it's difficult as
* the functions have no return value. * 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(); portDISABLE_INTERRUPTS();
uxCriticalNesting++; uxCriticalNesting++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void IRAM vPortExitCritical( void ) void IRAM vPortExitCritical(void) {
{
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if (uxCriticalNesting == 0)
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
/* Backward compatibility with libmain.a and libpp.a and can remove when these are open. */ /* 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 )
{ signed portBASE_TYPE xTaskGenericCreate(TaskFunction_t pxTaskCode,
(void)puxStackBuffer; (void)xRegions; const signed char * const pcName,
return xTaskCreate( pxTaskCode, (const char * const)pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask); 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);
}

View file

@ -1,67 +1,30 @@
/* /*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. *
* 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
* FreeRTOS provides completely free yet professionally developed, * * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* robust, strictly quality controlled, supported, and cross * * the Software, and to permit persons to whom the Software is furnished to do so,
* platform software that has become a de facto standard. * * subject to the following conditions:
* * *
* Help yourself get started quickly and support the FreeRTOS * * The above copyright notice and this permission notice shall be included in all
* project by purchasing a FreeRTOS tutorial book, reference * * copies or substantial portions of the Software. If you wish to use our Amazon
* manual, or both from: http://www.FreeRTOS.org/Documentation * * FreeRTOS name, please do so in a fair use way that does not cause confusion.
* * *
* Thank you! * * 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
This file is part of the FreeRTOS distribution. * 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.
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 * http://www.FreeRTOS.org
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. * http://aws.amazon.com/freertos
*
>>! NOTE: The modification to the GPL is included to allow you to distribute * 1 tab == 4 spaces!
>>! 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!
*/
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
@ -92,18 +55,18 @@ extern "C" {
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE unsigned portLONG #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
#define portPOINTER_SIZE_TYPE unsigned portLONG
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t; typedef portBASE_TYPE BaseType_t;
typedef unsigned portBASE_TYPE UBaseType_t; typedef unsigned portBASE_TYPE UBaseType_t;
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffff #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* Architecture specifics. */ /* Architecture specifics. */
#define portARCH_NAME "ESP8266"
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8 #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 ESPTODO: It may be possible to just read the 'ps' register instead
of accessing thisvariable. of accessing thisvariable.
*/ */
extern char sdk_NMIIrqIsOn; extern uint8_t sdk_NMIIrqIsOn;
extern char level1_int_disabled; extern char level1_int_disabled;
extern unsigned cpu_sr; extern unsigned cpu_sr;
@ -156,6 +119,9 @@ extern unsigned cpu_sr;
prefer to _xt_disable_interrupts & _xt_enable_interrupts and store prefer to _xt_disable_interrupts & _xt_enable_interrupts and store
the ps value in a local variable - that approach is recursive-safe the ps value in a local variable - that approach is recursive-safe
and generally better. 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) 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. */ (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( 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 #ifdef __cplusplus

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,71 +1,29 @@
/* /*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.0
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
This file is part of the FreeRTOS distribution. * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
FreeRTOS is free software; you can redistribute it and/or modify it under * the Software, and to permit persons to whom the Software is furnished to do so,
the terms of the GNU General Public License (version 2) as published by the * subject to the following conditions:
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *
* The above copyright notice and this permission notice shall be included in all
*************************************************************************** * copies or substantial portions of the Software.
>>! NOTE: The modification to the GPL is included to allow you to !<< *
>>! distribute a combined work that includes FreeRTOS without being !<< * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>>! obliged to provide the source code for proprietary components !<< * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
>>! outside of the FreeRTOS kernel. !<< * 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
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
FOR A PARTICULAR PURPOSE. Full license text is available on the following * http://www.FreeRTOS.org
link: http://www.freertos.org/a00114.html * http://aws.amazon.com/freertos
*
*************************************************************************** * 1 tab == 4 spaces!
* * */
* 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!
*/
/* Standard includes. */ /* Standard includes. */
#include <stdlib.h> #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. #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
#endif #endif
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
header files above, but not in this file, in order to generate the correct for the header files above, but not in this file, in order to generate the
privileged Vs unprivileged linkage and placement. */ correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */
/* This entire source file will be skipped if the application is not configured /* 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. */ /* Misc definitions. */
#define tmrNO_DELAY ( TickType_t ) 0U #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. */ /* 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. */ 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. */ 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. */ 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. */ 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. */ TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
#if( configUSE_TRACE_FACILITY == 1 ) #if( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
#endif #endif
uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */
#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
} xTIMER; } xTIMER;
/* The old xTIMER name is maintained above then typedefed to the new Timer_t /* The old xTIMER name is maintained above then typedefed to the new Timer_t
@ -158,12 +123,15 @@ typedef struct tmrTimerQueueMessage
} u; } u;
} DaemonTaskMessage_t; } DaemonTaskMessage_t;
/*lint -e956 A manual analysis and inspection has been used to determine which /*lint -save -e956 A manual analysis and inspection has been used to determine
static variables must be declared volatile. */ which static variables must be declared volatile. */
/* The list in which active timers are stored. Timers are referenced in expire /* 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 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 xActiveTimerList1;
PRIVILEGED_DATA static List_t xActiveTimerList2; PRIVILEGED_DATA static List_t xActiveTimerList2;
PRIVILEGED_DATA static List_t *pxCurrentTimerList; 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 QueueHandle_t xTimerQueue = NULL;
PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = 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 * task. Other tasks communicate with the timer service task using the
* xTimerQueue queue. * 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 * 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 * Called after a Timer_t structure has been allocated either statically or
* dynamically to fill in the structure's members. * 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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, 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 ) BaseType_t xTimerCreateTimerTask( void )
@ -276,7 +244,7 @@ BaseType_t xReturn = pdFAIL;
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
"Tmr Svc", configTIMER_SERVICE_TASK_NAME,
ulTimerTaskStackSize, ulTimerTaskStackSize,
NULL, NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
@ -291,7 +259,7 @@ BaseType_t xReturn = pdFAIL;
#else #else
{ {
xReturn = xTaskCreate( prvTimerTask, xReturn = xTaskCreate( prvTimerTask,
"Tmr Svc", configTIMER_SERVICE_TASK_NAME,
configTIMER_TASK_STACK_DEPTH, configTIMER_TASK_STACK_DEPTH,
NULL, NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
@ -311,44 +279,39 @@ BaseType_t xReturn = pdFAIL;
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, 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; 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 ) 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 ); 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; return pxNewTimer;
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, 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; Timer_t *pxNewTimer;
@ -356,27 +319,25 @@ BaseType_t xReturn = pdFAIL;
{ {
/* Sanity check that the size of the structure used to declare a /* Sanity check that the size of the structure used to declare a
variable of type StaticTimer_t equals the size of the real timer variable of type StaticTimer_t equals the size of the real timer
structures. */ structure. */
volatile size_t xSize = sizeof( StaticTimer_t ); volatile size_t xSize = sizeof( StaticTimer_t );
configASSERT( xSize == sizeof( Timer_t ) ); configASSERT( xSize == sizeof( Timer_t ) );
( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/* A pointer to a StaticTimer_t structure MUST be provided, use it. */ /* A pointer to a StaticTimer_t structure MUST be provided, use it. */
configASSERT( pxTimerBuffer ); 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 ) 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 /* Timers can be created statically or dynamically so note this
timer was created statically in case it is later deleted. */ timer was created statically in case it is later deleted. The
pxNewTimer->ucStaticallyAllocated = pdTRUE; autoreload bit may get set in prvInitialiseNewTimer(). */
} pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
} }
return pxNewTimer; return pxNewTimer;
@ -385,12 +346,12 @@ BaseType_t xReturn = pdFAIL;
#endif /* configSUPPORT_STATIC_ALLOCATION */ #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 TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, 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. */ /* 0 is not a valid value for xTimerPeriodInTicks. */
configASSERT( ( xTimerPeriodInTicks > 0 ) ); configASSERT( ( xTimerPeriodInTicks > 0 ) );
@ -405,10 +366,13 @@ static void prvInitialiseNewTimer( const char * const pcTimerName,
parameters. */ parameters. */
pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->pcTimerName = pcTimerName;
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
pxNewTimer->uxAutoReload = uxAutoReload;
pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pvTimerID = pvTimerID;
pxNewTimer->pxCallbackFunction = pxCallbackFunction; pxNewTimer->pxCallbackFunction = pxCallbackFunction;
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
if( uxAutoReload != pdFALSE )
{
pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
}
traceTIMER_CREATE( pxNewTimer ); traceTIMER_CREATE( pxNewTimer );
} }
} }
@ -428,7 +392,7 @@ DaemonTaskMessage_t xMessage;
/* Send a command to the timer service task to start the xTimer timer. */ /* Send a command to the timer service task to start the xTimer timer. */
xMessage.xMessageID = xCommandID; xMessage.xMessageID = xCommandID;
xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer; xMessage.u.xTimerParameters.pxTimer = xTimer;
if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
{ {
@ -468,16 +432,36 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) TickType_t xTimerGetPeriod( TimerHandle_t xTimer )
{ {
Timer_t *pxTimer = ( Timer_t * ) xTimer; Timer_t *pxTimer = xTimer;
configASSERT( xTimer ); configASSERT( xTimer );
return pxTimer->xTimerPeriodInTicks; 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 ) TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )
{ {
Timer_t * pxTimer = ( Timer_t * ) xTimer; Timer_t * pxTimer = xTimer;
TickType_t xReturn; TickType_t xReturn;
configASSERT( xTimer ); 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. */ 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 ); configASSERT( xTimer );
return pxTimer->pcTimerName; return pxTimer->pcTimerName;
@ -498,7 +482,7 @@ Timer_t *pxTimer = ( Timer_t * ) xTimer;
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
{ {
BaseType_t xResult; 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 /* Remove the timer from the list of active timers. A check has already
been performed to ensure the list is not empty. */ 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 /* 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. */ 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 /* 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 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 else
{ {
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
mtCOVERAGE_TEST_MARKER(); 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; TickType_t xNextExpireTime;
BaseType_t xListWasEmpty; BaseType_t xListWasEmpty;
@ -760,7 +745,7 @@ TickType_t xTimeNow;
software timer. */ software timer. */
pxTimer = xMessage.u.xTimerParameters.pxTimer; 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. */ /* The timer is in a list, remove it. */
( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
@ -788,6 +773,7 @@ TickType_t xTimeNow;
case tmrCOMMAND_RESET_FROM_ISR : case tmrCOMMAND_RESET_FROM_ISR :
case tmrCOMMAND_START_DONT_TRACE : case tmrCOMMAND_START_DONT_TRACE :
/* Start or restart a timer. */ /* 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 ) 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 /* The timer expired before it was added to the active
@ -795,7 +781,7 @@ TickType_t xTimeNow;
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
traceTIMER_EXPIRED( 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 ); xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
configASSERT( xResult ); configASSERT( xResult );
@ -814,12 +800,13 @@ TickType_t xTimeNow;
case tmrCOMMAND_STOP : case tmrCOMMAND_STOP :
case tmrCOMMAND_STOP_FROM_ISR : case tmrCOMMAND_STOP_FROM_ISR :
/* The timer has already been removed from the active list. /* The timer has already been removed from the active list. */
There is nothing to do here. */ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
break; break;
case tmrCOMMAND_CHANGE_PERIOD : case tmrCOMMAND_CHANGE_PERIOD :
case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
@ -833,29 +820,28 @@ TickType_t xTimeNow;
break; break;
case tmrCOMMAND_DELETE : case tmrCOMMAND_DELETE :
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
/* The timer has already been removed from the active list, /* The timer has already been removed from the active list,
just free up the memory if the memory was dynamically just free up the memory if the memory was dynamically
allocated. */ allocated. */
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 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 )
{ {
vPortFree( pxTimer ); vPortFree( pxTimer );
} }
else 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 */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
break; break;
@ -884,7 +870,7 @@ BaseType_t xResult;
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
/* Remove the timer from the list. */ /* 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 ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
traceTIMER_EXPIRED( pxTimer ); traceTIMER_EXPIRED( pxTimer );
@ -893,7 +879,7 @@ BaseType_t xResult;
have not yet been switched. */ have not yet been switched. */
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); 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 /* Calculate the reload value, and if the reload value results in
the timer going into the same timer list then it has already expired 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 /* The timer queue is allocated statically in case
configSUPPORT_DYNAMIC_ALLOCATION is 0. */ configSUPPORT_DYNAMIC_ALLOCATION is 0. */
static StaticQueue_t xStaticTimerQueue; 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[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; 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 #else
{ {
@ -980,28 +966,32 @@ static void prvCheckForValidListAndQueue( void )
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
{ {
BaseType_t xTimerIsInActiveList; BaseType_t xReturn;
Timer_t *pxTimer = ( Timer_t * ) xTimer; Timer_t *pxTimer = xTimer;
configASSERT( xTimer ); configASSERT( xTimer );
/* Is the timer in the list of active timers? */ /* Is the timer in the list of active timers? */
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Checking to see if it is in the NULL list in effect checks to see if if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )
it is referenced from either the current or the overflow timer lists in {
one go, but the logic has to be reversed, hence the '!'. */ xReturn = pdFALSE;
xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); }
else
{
xReturn = pdTRUE;
}
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
return xTimerIsInActiveList; return xReturn;
} /*lint !e818 Can't be pointer to const due to the typedef. */ } /*lint !e818 Can't be pointer to const due to the typedef. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *pvTimerGetTimerID( const TimerHandle_t xTimer ) void *pvTimerGetTimerID( const TimerHandle_t xTimer )
{ {
Timer_t * const pxTimer = ( Timer_t * ) xTimer; Timer_t * const pxTimer = xTimer;
void *pvReturn; void *pvReturn;
configASSERT( xTimer ); configASSERT( xTimer );
@ -1018,7 +1008,7 @@ void *pvReturn;
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )
{ {
Timer_t * const pxTimer = ( Timer_t * ) xTimer; Timer_t * const pxTimer = xTimer;
configASSERT( xTimer ); configASSERT( xTimer );
@ -1083,6 +1073,26 @@ Timer_t * const pxTimer = ( Timer_t * ) xTimer;
#endif /* INCLUDE_xTimerPendFunctionCall */ #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 /* 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 to include software timer functionality. If you want to include software timer
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */

View file

@ -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

View file

@ -77,9 +77,9 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl
## Open Source Components ## Open Source Components
* [FreeRTOS](http://www.freertos.org/) V9.0.0 * [FreeRTOS](http://www.freertos.org/) V10.2.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. * [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v2.0.3, with [some modifications](https://github.com/ourairquality/lwip/).
* [newlib](https://github.com/projectgus/newlib-xtensa) v2.2.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS. * [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). 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. * 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. * 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
View 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

View file

@ -146,7 +146,7 @@ ifndef $(1)_WHOLE_ARCHIVE
$(1)_AR_IN_FILES += $$($(1)_SRC_FILES) $(1)_AR_IN_FILES += $$($(1)_SRC_FILES)
endif endif
$$($(1)_AR): $$($(1)_OBJ_FILES) $$($(1)_SRC_IN_AR_FILES) $$($(1)_AR): $$($(1)_AR_IN_FILES)
$(vecho) "AR $$@" $(vecho) "AR $$@"
$(Q) mkdir -p $$(dir $$@) $(Q) mkdir -p $$(dir $$@)
$(Q) $(AR) cru $$@ $$^ $(Q) $(AR) cru $$@ $$^
@ -160,6 +160,26 @@ endif
-include $$($(1)_OBJ_FILES:.o=.d) -include $$($(1)_OBJ_FILES:.o=.d)
endef 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 ## Linking rules for SDK libraries
## SDK libraries are preprocessed to: ## SDK libraries are preprocessed to:
# - remove object files named in <libname>.remove # - remove object files named in <libname>.remove
@ -208,9 +228,9 @@ $(foreach component,$(COMPONENTS), \
) )
# final linking step to produce .elf # 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 $@" $(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: $(BUILD_DIR) $(FIRMWARE_DIR) $(BUILD_DIR)sdklib:
$(Q) mkdir -p $@ $(Q) mkdir -p $@
@ -223,17 +243,16 @@ $(FW_FILE): $(PROGRAM_OUT) $(FIRMWARE_DIR)
$(vecho) "FW $@" $(vecho) "FW $@"
$(Q) $(ESPTOOL) elf2image --version=2 $(ESPTOOL_ARGS) $< -o $(FW_FILE) $(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 flash: all
$(Q) $(ESPTOOL) $(ESPTOOL_FLASH_CMD) $(if will_flash, $(call will_flash, "flash"))
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPTOOL_ARGS) \
print_flash_cmd: $(RBOOT_ARGS) 0x2000 $(FW_FILE) $(SPIFFS_ESPTOOL_ARGS)
$(Q) echo "$(ESPTOOL_FLASH_CMD)" $(if did_flash, $(call did_flash, "flash"))
erase_flash: erase_flash:
$(if will_flash, $(call will_flash, "erase"))
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) erase_flash $(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) erase_flash
$(if did_flash, $(call did_flash, "erase"))
size: $(PROGRAM_OUT) size: $(PROGRAM_OUT)
$(Q) $(CROSS)size --format=sysv $(PROGRAM_OUT) $(Q) $(CROSS)size --format=sysv $(PROGRAM_OUT)
@ -275,9 +294,6 @@ help:
@echo "test" @echo "test"
@echo "'flash', then start a GNU Screen session on the same serial port to see serial output." @echo "'flash', then start a GNU Screen session on the same serial port to see serial output."
@echo "" @echo ""
@echo "print_flash_cmd"
@echo "Just print command line arguments for flashing with esptool.py"
@echo ""
@echo "size" @echo "size"
@echo "Build, then print a summary of built firmware size." @echo "Build, then print a summary of built firmware size."
@echo "" @echo ""

View file

@ -21,13 +21,17 @@
#include "esp/spi_regs.h" #include "esp/spi_regs.h"
#include "esp/dport_regs.h" #include "esp/dport_regs.h"
#include "esp/wdev_regs.h" #include "esp/wdev_regs.h"
#include "esp/wdt_regs.h"
#include "esp/rtcmem_regs.h"
#include "esp/hwrand.h" #include "esp/hwrand.h"
#include "os_version.h" #include "os_version.h"
#include "espressif/esp_common.h" #include "espressif/esp_common.h"
#include "espressif/phy_info.h" #include "espressif/phy_info.h"
#include "sdk_internal.h"
#include "esplibs/libmain.h" #include "esplibs/libmain.h"
#include "esplibs/libnet80211.h"
#include "esplibs/libphy.h"
#include "esplibs/libpp.h"
#include "sysparam.h" #include "sysparam.h"
/* This is not declared in any header file (but arguably should be) */ /* 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); 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 // .text+0x258
void IRAM sdk_user_start(void) { void IRAM sdk_user_start(void) {
uint32_t buf32[sizeof(struct sdk_g_ic_saved_st) / 4]; 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) { switch (buf8[3] >> 4) {
case 0x0: // 4 Mbit (512 KByte) case 0x0: // 4 Mbit (512 KByte)
flash_sectors = 128; flash_size = 524288;
break; break;
case 0x1: // 2 Mbit (256 Kbyte) case 0x1: // 2 Mbit (256 Kbyte)
flash_sectors = 64; flash_size = 262144;
break; break;
case 0x2: // 8 Mbit (1 Mbyte) case 0x2: // 8 Mbit (1 Mbyte)
flash_sectors = 256; flash_size = 1048576;
break; break;
case 0x3: // 16 Mbit (2 Mbyte) case 0x3: // 16 Mbit (2 Mbyte)
flash_sectors = 512; case 0x5: // 16 Mbit (2 Mbyte)
flash_size = 2097152;
break; break;
case 0x4: // 32 Mbit (4 Mbyte) 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; break;
default: // Invalid -- Assume 4 Mbit (512 KByte) 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_sectors = flash_size / sdk_flashchip.sector_size;
flash_size = flash_sectors * 4096;
sdk_flashchip.chip_size = flash_size; sdk_flashchip.chip_size = flash_size;
set_spi0_divisor(flash_speed_divisor); set_spi0_divisor(flash_speed_divisor);
sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE); 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); Cache_Read_Enable(0, 0, 1);
zero_bss(); zero_bss();
sdk_os_install_putc1(default_putc); 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) { if (cksum_magic == 0xffffffff) {
// No checksum required // No checksum required
} else if ((cksum_magic == 0x55aa55aa) && } 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)); 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 // By default, put the sysparam region just below the config sectors at the
// top of the flash space // top of the flash space, and allowing one extra sector spare.
sysparam_addr = flash_size - (4 + DEFAULT_SYSPARAM_SECTORS) * sdk_flashchip.sector_size; sysparam_addr = flash_size - (5 + DEFAULT_SYSPARAM_SECTORS) * sdk_flashchip.sector_size;
status = sysparam_init(sysparam_addr, flash_size); status = sysparam_init(sysparam_addr, flash_size);
if (status == SYSPARAM_NOTFOUND) { if (status == SYSPARAM_NOTFOUND) {
status = sysparam_create_area(sysparam_addr, DEFAULT_SYSPARAM_SECTORS, false); 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 // .text+0x3d8
void IRAM vApplicationIdleHook(void) { void __attribute__((weak)) IRAM vApplicationIdleHook(void) {
printf("idle %u\n", WDEV.SYS_TIME); printf("idle %u\n", WDEV.SYS_TIME);
} }
// .text+0x404 // .text+0x404
void IRAM vApplicationTickHook(void) { void __attribute__((weak)) IRAM vApplicationTickHook(void) {
printf("tick %u\n", WDEV.SYS_TIME); printf("tick %u\n", WDEV.SYS_TIME);
} }
@ -252,12 +276,25 @@ static void zero_bss(void) {
// .Lfunc006 -- .irom0.text+0x70 // .Lfunc006 -- .irom0.text+0x70
static void init_networking(sdk_phy_info_t *phy_info, uint8_t *mac_addr) { 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)) { if (sdk_register_chipv6_phy(phy_info)) {
printf("FATAL: sdk_register_chipv6_phy failed"); printf("FATAL: sdk_register_chipv6_phy failed");
abort(); 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_phy_disable_agc();
sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode); sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode);
sdk_lmacInit(); sdk_lmacInit();
@ -294,13 +331,13 @@ static void init_g_ic(void) {
if (sdk_g_ic.s._unknown310 > 4) { if (sdk_g_ic.s._unknown310 > 4) {
sdk_g_ic.s._unknown310 = 4; sdk_g_ic.s._unknown310 = 4;
} }
if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) { if (sdk_g_ic.s.sta_ssid.ssid_length == 0xffffffff) {
bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4)); bzero(&sdk_g_ic.s.sta_ssid, sizeof(sdk_g_ic.s.sta_ssid));
bzero(&sdk_g_ic.s._unknown20f, sizeof(sdk_g_ic.s._unknown20f)); bzero(&sdk_g_ic.s.sta_password, sizeof(sdk_g_ic.s.sta_password));
} }
sdk_g_ic.s.wifi_led_enable = 0; sdk_g_ic.s.wifi_led_enable = 0;
if (sdk_g_ic.s._unknown281 > 1) { if (sdk_g_ic.s.sta_bssid_set > 1) {
sdk_g_ic.s._unknown281 = 0; sdk_g_ic.s.sta_bssid_set = 0;
} }
if (sdk_g_ic.s.ap_number > 5) { if (sdk_g_ic.s.ap_number > 5) {
sdk_g_ic.s.ap_number = 1; sdk_g_ic.s.ap_number = 1;
@ -322,10 +359,16 @@ void sdk_wdt_init(void) {
sdk_pp_soft_wdt_init(); sdk_pp_soft_wdt_init();
} }
extern void *xPortSupervisorStackPointer;
// .irom0.text+0x474 // .irom0.text+0x474
void sdk_user_init_task(void *params) { void sdk_user_init_task(void *params) {
int phy_ver, pp_ver; 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(); sdk_ets_timer_init();
printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__); printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__);
phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16; phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16;
@ -335,18 +378,24 @@ void sdk_user_init_task(void *params) {
user_init(); user_init();
sdk_user_init_flag = 1; sdk_user_init_flag = 1;
sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode); 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(); sdk_wifi_station_start();
LOCK_TCPIP_CORE();
netif_set_default(sdk_g_ic.v.station_netif_info->netif); 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(); sdk_wifi_softap_start();
LOCK_TCPIP_CORE();
netif_set_default(sdk_g_ic.v.softap_netif_info->netif); 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_station_start();
sdk_wifi_softap_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()) { if (sdk_wifi_station_get_auto_connect()) {
sdk_wifi_station_connect(); sdk_wifi_station_connect();
@ -374,9 +423,9 @@ static __attribute__((noinline)) void user_start_phase2(void) {
sdk_sleep_reset_analog_rtcreg_8266(); sdk_sleep_reset_analog_rtcreg_8266();
get_otp_mac_address(sdk_info.sta_mac_addr); 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_wifi_softap_cacl_mac(sdk_info.softap_mac_addr, sdk_info.sta_mac_addr);
sdk_info._unknown0 = 0x0104a8c0; sdk_info.softap_ipaddr.addr = 0x0104a8c0; // 192.168.4.1
sdk_info._unknown4 = 0x00ffffff; sdk_info.softap_netmask.addr = 0x00ffffff; // 255.255.255.0
sdk_info._unknown8 = 0x0104a8c0; sdk_info.softap_gw.addr = 0x0104a8c0; // 192.168.4.1
init_g_ic(); init_g_ic();
read_saved_phy_info(&phy_info); 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)); 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. // Wait for UARTs to finish sending anything in their queues.
uart_flush_txfifo(0); uart_flush_txfifo(0);
uart_flush_txfifo(1); uart_flush_txfifo(1);

View file

@ -4,22 +4,22 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void *operator new(size_t size) void * __attribute__((weak)) operator new(size_t size)
{ {
return malloc(size); return malloc(size);
} }
void *operator new[](size_t size) void * __attribute__((weak)) operator new[](size_t size)
{ {
return malloc(size); return malloc(size);
} }
void operator delete(void * ptr) void __attribute__((weak)) operator delete(void * ptr)
{ {
free(ptr); free(ptr);
} }
void operator delete[](void * ptr) void __attribute__((weak)) operator delete[](void * ptr)
{ {
free(ptr); free(ptr);
} }

View file

@ -19,8 +19,10 @@
#include "xtensa_ops.h" #include "xtensa_ops.h"
#include "esp/rom.h" #include "esp/rom.h"
#include "esp/uart.h" #include "esp/uart.h"
#include "esp/dport_regs.h"
#include "espressif/esp_common.h" #include "espressif/esp_common.h"
#include "esplibs/libmain.h" #include "esplibs/libmain.h"
#include "user_exception.h"
/* Forward declarations */ /* Forward declarations */
static void IRAM fatal_handler_prelude(void); 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 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 /* fatal_exception_handler called from any unhandled user exception
* *
* (similar to a hard fault on other processor architectures) * (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_Disable();
Cache_Read_Enable(0, 0, 1); 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 /* 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(); dump_heapinfo();
post_crash_reset(); post_crash_reset();
} }
void set_user_exception_handler(void (*fn)(void))
{
user_exception_handler = fn;
}

View file

@ -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); 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);
}
}

View file

@ -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]();
}
}

View file

@ -10,8 +10,13 @@
#include <esp/wdev_regs.h> #include <esp/wdev_regs.h>
#include <string.h> #include <string.h>
/* Return a random 32-bit number */ /* Return a random 32-bit number.
uint32_t hwrand(void) *
* 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; return WDEV.HWRNG;
} }

View file

@ -7,13 +7,19 @@
*/ */
#include <esp/interrupts.h> #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; 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. /* Generic ISR handler.
@ -25,17 +31,20 @@ uint16_t IRAM _xt_isr_handler(uint16_t intset)
esp_in_isr = true; esp_in_isr = true;
/* WDT has highest priority (occasional WDT resets otherwise) */ /* WDT has highest priority (occasional WDT resets otherwise) */
if(intset & BIT(INUM_WDT)) { if (intset & BIT(INUM_WDT)) {
_xt_clear_ints(BIT(INUM_WDT)); _xt_clear_ints(BIT(INUM_WDT));
isr[INUM_WDT](); isr[INUM_WDT].handler(NULL);
intset -= BIT(INUM_WDT); intset -= BIT(INUM_WDT);
} }
while(intset) { while (intset) {
uint8_t index = __builtin_ffs(intset) - 1; uint8_t index = __builtin_ffs(intset) - 1;
uint16_t mask = BIT(index); uint16_t mask = BIT(index);
_xt_clear_ints(mask); _xt_clear_ints(mask);
isr[index](); _xt_isr handler = isr[index].handler;
if (handler) {
handler(isr[index].arg);
}
intset -= mask; intset -= mask;
} }

View file

@ -27,6 +27,7 @@
#define _SPI1_FUNC IOMUX_FUNC(2) #define _SPI1_FUNC IOMUX_FUNC(2)
#define _SPI_BUF_SIZE 64 #define _SPI_BUF_SIZE 64
#define __min(a,b) ((a > b) ? (b):(a))
static bool _minimal_pins[2] = {false, false}; static bool _minimal_pins[2] = {false, false};
@ -158,6 +159,22 @@ inline static void _start(uint8_t bus)
SPI(bus).CMD |= SPI_CMD_USR; 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) inline static uint32_t _swap_bytes(uint32_t value)
{ {
return (value << 24) | ((value << 8) & 0x00ff0000) | ((value >> 8) & 0x0000ff00) | (value >> 24); 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); _wait(bus);
size_t bytes = len * (uint8_t)word_size; size_t bytes = len * (uint8_t)word_size;
_set_size(bus, bytes); _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); _spi_buf_prepare(bus, len, e, word_size);
_start(bus); _start(bus);
_wait(bus); _wait(bus);
@ -220,6 +237,39 @@ uint32_t spi_transfer_32(uint8_t bus, uint32_t data)
return res; 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) 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; 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; size_t offset = i * _SPI_BUF_SIZE;
_spi_buf_transfer(bus, (const uint8_t *)out_data + offset, _spi_buf_transfer(bus, (const uint8_t *)out_data + offset,
in_data ? (uint8_t *)in_data + offset : NULL, buf_size, e, word_size); in_data ? (uint8_t *)in_data + offset : NULL, buf_size, e, word_size);
_rearm_extras_bit(bus, false);
} }
uint8_t tail = len % buf_size; 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); in_data ? (uint8_t *)in_data + blocks * _SPI_BUF_SIZE : NULL, tail, e, word_size);
} }
if (blocks) _rearm_extras_bit(bus, true);
return len; 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);
}

View file

@ -83,6 +83,11 @@ int timer_set_frequency(const timer_frc_t frc, uint32_t freq)
uint32_t counts = 0; uint32_t counts = 0;
timer_clkdiv_t div = timer_freq_to_div(freq); 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); counts = timer_freq_to_count(frc, freq, div);
if(counts == 0) if(counts == 0)
{ {

View file

@ -127,21 +127,44 @@ static inline bool gpio_read(const uint8_t gpio_num)
return GPIO.IN & BIT(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 /* Set the interrupt type for a given pin
* *
* If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be * If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be
* attached and unmasked. * attached and unmasked.
*/ */
static inline void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type) void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type, gpio_interrupt_handler_t 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);
_xt_isr_unmask(1<<INUM_GPIO);
}
}
/* Return the interrupt type set for a pin */ /* Return the interrupt type set for a pin */
static inline gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num) static inline gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)

View file

@ -70,7 +70,7 @@ struct GPIO_REGS {
uint32_t volatile STATUS_SET; // 0x20 uint32_t volatile STATUS_SET; // 0x20
uint32_t volatile STATUS_CLEAR; // 0x24 uint32_t volatile STATUS_CLEAR; // 0x24
uint32_t volatile CONF[16]; // 0x28 - 0x64 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; // 0x6c
uint32_t volatile RTC_CALIB_RESULT; // 0x70 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_OPEN_DRAIN does not appear to work on all pins.
* *
* *
* GPIO_CONF_SOURCE_PWM (boolean) * GPIO_CONF_SOURCE_DSM (boolean)
* When set, GPIO pin output will be connected to the sigma-delta PWM * When set, GPIO pin output will be connected to the sigma-delta
* generator (controlled by the GPIO.PWM register). When cleared, pin * generator (controlled by the GPIO.DSM register). When cleared, pin
* output will function as a normal GPIO output (controlled by the * output will function as a normal GPIO output (controlled by the
* GPIO.OUT* registers). * 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_M 0x00000007
#define GPIO_CONF_INTTYPE_S 7 #define GPIO_CONF_INTTYPE_S 7
#define GPIO_CONF_OPEN_DRAIN BIT(2) #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 */ /* Valid values for the GPIO_CONF_INTTYPE field */
typedef enum { typedef enum {
@ -142,13 +142,13 @@ typedef enum {
GPIO_INTTYPE_LEVEL_HIGH = 5, GPIO_INTTYPE_LEVEL_HIGH = 5,
} gpio_inttype_t; } gpio_inttype_t;
/* Details for PWM register */ /* Details for DSM register */
#define GPIO_PWM_ENABLE BIT(16) #define GPIO_DSM_ENABLE BIT(16)
#define GPIO_PWM_PRESCALER_M 0x000000ff #define GPIO_DSM_PRESCALER_M 0x000000ff
#define GPIO_PWM_PRESCALER_S 8 #define GPIO_DSM_PRESCALER_S 8
#define GPIO_PWM_TARGET_M 0x000000ff #define GPIO_DSM_TARGET_M 0x000000ff
#define GPIO_PWM_TARGET_S 0 #define GPIO_DSM_TARGET_S 0
/* Details for RTC_CALIB register */ /* Details for RTC_CALIB register */

View file

@ -35,19 +35,37 @@ typedef enum {
INUM_TIMER_FRC2 = 10, INUM_TIMER_FRC2 = 10,
} xt_isr_num_t; } xt_isr_num_t;
void sdk__xt_int_exit (void); void sdk__xt_int_exit(void);
void _xt_user_exit (void); void _xt_user_exit(void);
void sdk__xt_tick_timer_init (void); void sdk__xt_tick_timer_init(void);
void sdk__xt_timer_int(void); void sdk__xt_timer_int(void *);
void sdk__xt_timer_int1(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) static inline uint32_t _xt_get_intlevel(void)
{ {
uint32_t level; uint32_t level;
__asm__ volatile("rsr %0, intlevel" : "=a"(level)); __asm__ volatile("rsr %0, ps" : "=a"(level));
return 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 /* Disable interrupts and return the old ps value, to pass into
_xt_restore_interrupts later. _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)); __asm__ volatile ("wsr %0, ps; rsync" :: "a" (new_ps));
} }
/* ESPTODO: the mask/unmask functions aren't thread safe */ static inline uint32_t _xt_isr_unmask(uint32_t unmask)
static inline void _xt_isr_unmask(uint32_t unmask)
{ {
uint32_t old_level = _xt_disable_interrupts();
uint32_t intenable; uint32_t intenable;
asm volatile ("rsr %0, intenable" : "=a" (intenable)); asm volatile ("rsr %0, intenable" : "=a" (intenable));
intenable |= unmask; asm volatile ("wsr %0, intenable;" :: "a" (intenable | unmask));
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable)); _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; uint32_t intenable;
asm volatile ("rsr %0, intenable" : "=a" (intenable)); asm volatile ("rsr %0, intenable" : "=a" (intenable));
intenable &= ~mask; asm volatile ("wsr %0, intenable;" :: "a" (intenable & ~mask));
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable)); _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; uint32_t interrupt;
asm volatile ("rsr %0, interrupt" : "=a" (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)); asm volatile ("wsr %0, intclear; esync" :: "a" (mask));
} }
typedef void (* _xt_isr)(void); typedef void (* _xt_isr)(void *arg);
/* This function is implemeneted in FreeRTOS port.c at the moment, void _xt_isr_attach (uint8_t i, _xt_isr func, void *arg);
should be moved or converted to an inline */
void _xt_isr_attach (uint8_t i, _xt_isr func);
#endif #endif

View file

@ -36,6 +36,15 @@
#define SPI_FREQ_DIV_40M SPI_GET_FREQ_DIV(1, 2) ///< 40MHz #define SPI_FREQ_DIV_40M SPI_GET_FREQ_DIV(1, 2) ///< 40MHz
#define SPI_FREQ_DIV_80M SPI_GET_FREQ_DIV(1, 1) ///< 80MHz #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 #ifdef __cplusplus
extern "C" 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); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -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); 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 */ #endif /* _ESP_UART_H */

View file

@ -50,6 +50,25 @@ struct UART_REGS {
_Static_assert(sizeof(struct UART_REGS) == 0x80, "UART_REGS is the wrong size"); _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 */ /* Details for FIFO register */
#define UART_FIFO_DATA_M 0x000000ff #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_M 0x00000003
#define UART_CONF0_BYTE_LEN_S 2 #define UART_CONF0_BYTE_LEN_S 2
#define UART_CONF0_PARITY_ENABLE BIT(1) #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 */ /* Details for CONF1 register */

View file

@ -36,4 +36,6 @@ typedef struct {
uint32_t status_mask; uint32_t status_mask;
} sdk_flashchip_t; } sdk_flashchip_t;
extern sdk_flashchip_t sdk_flashchip;
#endif /* _FLASHCHIP_H */ #endif /* _FLASHCHIP_H */

View file

@ -14,23 +14,111 @@
// 'info' is declared in app_main.o at .bss+0x4 // 'info' is declared in app_main.o at .bss+0x4
struct sdk_info_st { struct sdk_info_st {
uint32_t _unknown0; // 0x00 ip4_addr_t softap_ipaddr; // 0x00
uint32_t _unknown4; // 0x04 ip4_addr_t softap_netmask; // 0x04
uint32_t _unknown8; // 0x08 ip4_addr_t softap_gw; // 0x08
ip_addr_t ipaddr; // 0x0c ip4_addr_t sta_ipaddr; // 0x0c
ip_addr_t netmask; // 0x10 ip4_addr_t sta_netmask; // 0x10
ip_addr_t gw; // 0x14 ip4_addr_t sta_gw; // 0x14
uint8_t softap_mac_addr[6]; // 0x18 uint8_t softap_mac_addr[6]; // 0x18
uint8_t sta_mac_addr[6]; // 0x1e 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 struct wl_channel {
extern struct sdk_rst_info sdk_rst_if; 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 sdk_g_ic_netif_info {
struct netif *netif; // 0x00 struct netif *netif; // 0x00
@ -38,16 +126,22 @@ struct sdk_g_ic_netif_info {
uint8_t _unknown20[28]; // 0x20 - 0x3c uint8_t _unknown20[28]; // 0x20 - 0x3c
uint32_t _unknown3c; // 0x3c (referenced by sdk_wifi_station_disconnect) uint32_t _unknown3c; // 0x3c (referenced by sdk_wifi_station_disconnect)
uint8_t _unknown40[6]; // 0x40 - 0x46 uint8_t _unknown40[6]; // 0x40 - 0x46
uint8_t _unknown46[66]; // 0x46 - 0x88 uint8_t _unknown46[2]; // 0x46 - 0x47
struct sdk_netif_conninfo *_unknown88; // 0x88 uint32_t _unknown48; // 0x48
uint8_t _unknown4c; // 0x4c
uint8_t _unknown4d[59]; // 0x4d - 0x88
struct sdk_cnx_node *_unknown88; // 0x88
uint32_t _unknown8c; // 0x8c uint32_t _unknown8c; // 0x8c
struct sdk_netif_conninfo *conninfo[6]; // 0x90 - 0xa8 struct sdk_cnx_node *cnx_nodes[6]; // 0x90 - 0xa8
uint8_t _unknowna8[16]; // 0xa8 - 0xb8 uint8_t _unknowna8[12]; // 0xa8 - 0xb4
uint8_t _unknownb8; // 0xb8 (referenced by sdk_wifi_station_connect / sdk_wifi_station_disconnect) struct _unknown_softap1 *_unknownb4;
uint8_t _unknownb9; // 0xb9 (referenced by sdk_wifi_station_connect / sdk_wifi_station_disconnect) uint8_t statusb8; // 0xb8 (arg of sta_status_set)
uint8_t connect_status; // 0xba (referenced by sdk_system_station_got_ip_set / sdk_wifi_station_disconnect) 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 // This is the portion of g_ic which is not loaded/saved to the flash ROM, and
// starts out zeroed on every boot. // starts out zeroed on every boot.
struct sdk_g_ic_volatile_st { struct sdk_g_ic_volatile_st {
@ -73,9 +167,11 @@ struct sdk_g_ic_volatile_st {
uint8_t _unknown7e; uint8_t _unknown7e;
uint8_t _unknown7f; 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]; uint8_t _unknown150[20];
@ -92,8 +188,7 @@ struct sdk_g_ic_volatile_st {
void *_unknown184; void *_unknown184;
struct station_info *station_info_head; struct station_info *station_info_head;
struct station_info *station_info_tail; struct station_info *station_info_tail;
uint32_t _unknown190; void *_unknown190[2]; // cnx_sta_leave
uint32_t _unknown194;
uint8_t _unknown198[40]; uint8_t _unknown198[40];
@ -112,9 +207,10 @@ struct sdk_g_ic_volatile_st {
uint8_t _unknown1d5[3]; uint8_t _unknown1d5[3];
}; };
struct sdk_g_ic_unk0_st {
uint32_t _unknown1e4; struct sdk_g_ic_ssid_with_length {
uint8_t _unknown1e8[32]; 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 // 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_mode;
uint8_t wifi_led_enable; uint8_t wifi_led_enable;
uint8_t wifi_led_gpio; 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 _unknown208;
uint8_t _unknown209; uint8_t _unknown209; // sdk_wpa_config_profile
uint8_t _unknown20a; uint8_t _unknown20a; // sdk_wpa_config_profile
uint8_t _unknown20b; uint8_t _unknown20b;
uint8_t _unknown20c; uint8_t _unknown20c; // sdk_wpa_config_profile
uint8_t _unknown20d; uint8_t _unknown20d;
uint8_t _unknown20e; uint8_t _unknown20e;
uint8_t _unknown20f[64]; uint8_t sta_password[64]; // 0x20f Null terminated string.
uint8_t _unknown24f; uint8_t _unknown24f;
uint8_t _unknown250[49]; 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 _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 _unknonwn2ec;
uint8_t _unknown2ed[32]; uint8_t _unknown2ed[32];
uint8_t _unknown30d; uint8_t _unknown30d; // result of ieee80211_chan2ieee
uint8_t _unknown30e; uint8_t _unknown30e;
uint8_t _unknown30f; uint8_t _unknown30f;
uint8_t _unknown310; uint8_t _unknown310; // count of entries in the softap cnx_node array, less two.
uint8_t _unknown311[3]; uint8_t _unknown311[3];
@ -194,7 +296,20 @@ struct sdk_g_ic_st {
struct sdk_g_ic_saved_st s; // 0x1d8 - 0x548 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 // 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(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(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(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!"); _Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!");
/////////////////////////////////////////////////////////////////////////////// _Static_assert(sizeof(struct esf_buf) == 0x24, "struct esf_buf: wrong size");
// Function Prototypes // _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); // The SDK access some slots in lwip structures.
sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
void sdk_cnx_attach(struct sdk_g_ic_st *); // The netif->state is initialized in netif_add within lwip with a struct
void sdk_ets_timer_init(void); // sdk_g_ic_netif_info, see sdk_wifi_station_start and sdk_wifi_softap_start.
void sdk_ieee80211_ifattach(struct sdk_g_ic_st *, uint8_t *); // There is a known sdk read of the netif->state in ieee80211_output.o
void sdk_ieee80211_phy_init(enum sdk_phy_mode); // ieee80211_output_pbuf and perhaps elsewhere. The value is just passed through
void sdk_lmacInit(void); // lwip and and not used by lwip so just ensure this slot is at the expected
void sdk_phy_disable_agc(void); // offset.
void sdk_phy_enable_agc(void); _Static_assert(offsetof(struct netif, state) == 4, "netif->state offset wrong!");
void sdk_pm_attach(void);
void sdk_pp_attach(void); // Some sdk uses of netif->hwaddr have been converted to source code, but many
void sdk_pp_soft_wdt_init(void); // remain, but the content of this slot should not change in future versions of
int sdk_register_chipv6_phy(sdk_phy_info_t *); // lwip, so just ensure it is at the expected offset. Note the sdk binary
void sdk_sleep_reset_analog_rtcreg_8266(void); // libraries have been patched to move this offset from 41 to 42 to keep it
uint32_t sdk_system_get_checksum(uint8_t *, uint32_t); // 16-bit aligned to keep lwip v2 happy.
void sdk_wDevEnableRx(void); _Static_assert(offsetof(struct netif, hwaddr) == 8, "netif->hwaddr offset wrong!");
void sdk_wDev_Initialize(void);
void sdk_wifi_mode_set(uint8_t); _Static_assert(offsetof(struct pbuf, esf_buf) == 16, "pbuf->esf_buf offset wrong!");
void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *);
void sdk_wifi_softap_set_default_ssid(void);
void sdk_wifi_softap_start(void); /// Misc.
void sdk_wifi_station_start(void);
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif, struct pbuf *p);
#endif /* _INTERNAL_SDK_STRUCTURES_H */ #endif /* _INTERNAL_SDK_STRUCTURES_H */

View file

@ -21,14 +21,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef __ESP_SPIFFS_FLASH_H__ #ifndef __SPIFLASH_H__
#define __ESP_SPIFFS_FLASH_H__ #define __SPIFLASH_H__
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "common_macros.h" #include "common_macros.h"
#define ESP_SPIFFS_FLASH_OK 0 #define SPI_FLASH_SECTOR_SIZE 4096
#define ESP_SPIFFS_FLASH_ERROR 1
/** /**
* Read data from SPI flash. * Read data from SPI flash.
@ -37,9 +37,9 @@
* @param buf Buffer to read to. Doesn't have to be aligned. * @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. * @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. * 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 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. * @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. * Erase a sector.
* *
* @param addr Address of sector to erase. Must be sector aligned. * @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__

View 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_ */

View file

@ -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); 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 /** Get the value associated with a key
* *
* This is the core "get value" function. It will retrieve the value for the * 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); 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 * This performs the same function as sysparam_get_data() but without
* performing any memory allocations. It can thus be used before the heap has * allocating memory for the result value. It can thus be used before the heap
* been configured or in other cases where using the heap would be a problem * has been configured or in other cases where using the heap would be a
* (i.e. in an OOM handler, etc). It requires that the caller pass in a * problem (i.e. in an OOM handler, etc). It requires that the caller pass in
* suitably sized buffer for the value to be read (if the supplied buffer is * 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 * not large enough, the returned value will be truncated and the full required
* required length will be returned in `actual_length`). * 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.
* *
* @param[in] key Key name (zero-terminated string) * @param[in] key Key name (zero-terminated string)
* @param[in] buffer Pointer to a buffer to hold the returned value * @param[in] dest Pointer to a buffer to hold the returned value.
* @param[in] buffer_size Length of the supplied buffer in bytes * @param[in] dest_size Length of the supplied buffer in bytes.
* @param[out] actual_length pointer to a location to hold the actual length * @param[out] actual_length Pointer to a location to hold the actual length
* of the data which was associated with the key * of the data which was associated with the key
* (may be NULL). * (may be NULL).
* @param[out] is_binary Pointer to a bool to hold whether the returned * @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_CORRUPT Sysparam region has bad/corrupted data
* @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash * @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 /** 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 /** 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 * 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 * 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 * 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 /** 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 * 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 * 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 * 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` * 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 * 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, * 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 * 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 /** Set a key's value as a number
* *
* Write an int32_t binary value to the specified key. This does the inverse of * 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] key Key name (zero-terminated string)
* @param[in] value Value to set * @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 /** Set a key's value as a number
* *
* Write an int8_t binary value to the specified key. This does the inverse of * Write an int8_t binary value to the specified key. This does the inverse of
* the sysparam_get_int8() function. * the sysparam_get_int8() function. This is done without allocating any
* * memory.
* Note that if the key already contains a value which parses to the same
* boolean (true/false) value, it is left unchanged.
* *
* @param[in] key Key name (zero-terminated string) * @param[in] key Key name (zero-terminated string)
* @param[in] value Value to set * @param[in] value Value to set

View 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

View file

@ -12,10 +12,31 @@
#include <xtensa_ops.h> #include <xtensa_ops.h>
#include <esp/uart.h> #include <esp/uart.h>
#include <stdlib.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; 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 */ extern char _heap_start; /* linker script defined */
static char * heap_end; static char * heap_end;
@ -40,44 +61,118 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
return (caddr_t) prev_heap_end; 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 */ /* 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++) { for(int i = 0; i < len; i++) {
/* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */ /* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */
if(ptr[i] == '\r') if(((char *)ptr)[i] == '\r')
continue; continue;
if(ptr[i] == '\n') if(((char *)ptr)[i] == '\n')
uart_putc(0, '\r'); uart_putc(0, '\r');
uart_putc(0, ptr[i]); uart_putc(0, ((char *)ptr)[i]);
} }
return len; 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 */ /* 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; int ch, i;
uart_rxfifo_wait(0, 1); uart_rxfifo_wait(0, 1);
for(i = 0; i < len; i++) { for(i = 0; i < len; i++) {
ch = uart_getc_nowait(0); ch = uart_getc_nowait(0);
if (ch < 0) break; if (ch < 0) break;
ptr[i] = ch; ((char *)ptr)[i] = ch;
} }
return i; 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; r->_errno = EBADF;
return -1; 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); 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 /* 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"))) __attribute__((weak, alias("syscall_returns_enosys")))
int _open_r(struct _reent *r, const char *pathname, int flags, int mode); 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"))) __attribute__((weak, alias("syscall_returns_enosys")))
int _unlink_r(struct _reent *r, const char *path); int _unlink_r(struct _reent *r, const char *path);
__attribute__((weak, alias("syscall_returns_enosys"))) __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"))) __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"))) __attribute__((weak, alias("syscall_returns_enosys")))
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence); 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 /* Generic stub for any newlib syscall that fails with errno ENOSYS
("Function not implemented") and a return value equivalent to ("Function not implemented") and a return value equivalent to
(int)-1. */ (int)-1. */
@ -109,3 +209,125 @@ static int syscall_returns_enosys(struct _reent *r)
r->_errno=ENOSYS; r->_errno=ENOSYS;
return -1; 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);
}
}

View file

@ -21,12 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "esp_spiffs_flash.h" #include "include/spiflash.h"
#include "flashchip.h"
#include "espressif/spi_flash.h" #include "include/flashchip.h"
#include "FreeRTOS.h" #include "include/esp/rom.h"
#include "esp/rom.h" #include "include/esp/spi_regs.h"
#include "esp/spi_regs.h"
#include <FreeRTOS.h>
#include <string.h> #include <string.h>
/** /**
@ -52,25 +53,6 @@
#define SPI_READ_MAX_SIZE 60 #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. * 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); 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); 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. * 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) uint8_t *buf, uint32_t size)
{ {
// check if block to write doesn't cross page boundary // check if block to write doesn't cross page boundary
if (flashchip->page_size < size + (dest_addr % flashchip->page_size)) { if (flashchip->page_size < size + (dest_addr % flashchip->page_size)) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
if (size < 1) { if (size < 1) {
return ESP_SPIFFS_FLASH_OK; return true;
} }
while (size >= SPI_WRITE_MAX_SIZE) { 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; buf += SPI_WRITE_MAX_SIZE;
if (size < 1) { if (size < 1) {
return ESP_SPIFFS_FLASH_OK; return true;
} }
} }
spi_write_data(flashchip, dest_addr, buf, size); spi_write_data(flashchip, dest_addr, buf, size);
return ESP_SPIFFS_FLASH_OK; return true;
} }
/** /**
* Split block of data into pages and write pages. * 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)) { if (sdk_flashchip.chip_size < (addr + size)) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
uint32_t write_bytes_to_page = sdk_flashchip.page_size - uint32_t write_bytes_to_page = sdk_flashchip.page_size -
(addr % sdk_flashchip.page_size); // TODO: place for optimization (addr % sdk_flashchip.page_size); // TODO: place for optimization
if (size < write_bytes_to_page) { if (size < write_bytes_to_page) {
if (spi_write_page(&sdk_flashchip, addr, dst, size)) { if (!spi_write_page(&sdk_flashchip, addr, dst, size)) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
} else { } else {
if (spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) { if (!spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
uint32_t offset = write_bytes_to_page; uint32_t offset = write_bytes_to_page;
uint32_t pages_to_write = (size - offset) / sdk_flashchip.page_size; uint32_t pages_to_write = (size - offset) / sdk_flashchip.page_size;
for (uint8_t i = 0; i != pages_to_write; i++) { for (uint32_t i = 0; i < pages_to_write; i++) {
if (spi_write_page(&sdk_flashchip, addr + offset, if (!spi_write_page(&sdk_flashchip, addr + offset,
dst + offset, sdk_flashchip.page_size)) { dst + offset, sdk_flashchip.page_size)) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
offset += sdk_flashchip.page_size; 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)) { 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) { if (buf) {
vPortEnterCritical(); vPortEnterCritical();
@ -197,21 +181,23 @@ static inline void IRAM read_block(sdk_flashchip_t *chip, uint32_t addr,
while (SPI(0).CMD) {}; 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. * 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) uint8_t *dst, uint32_t size)
{ {
if (size < 1) { if (size < 1) {
return ESP_SPIFFS_FLASH_OK; return true;
} }
if ((addr + size) > flashchip->chip_size) { if ((addr + size) > flashchip->chip_size) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
while (size >= SPI_READ_MAX_SIZE) { 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); 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) { if (buf) {
vPortEnterCritical(); vPortEnterCritical();
@ -245,14 +231,14 @@ uint32_t IRAM esp_spiffs_flash_read(uint32_t dest_addr, uint8_t *buf, uint32_t s
return result; 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) { if ((addr + sdk_flashchip.sector_size) > sdk_flashchip.chip_size) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
if (addr & 0xFFF) { if (addr & 0xFFF) {
return ESP_SPIFFS_FLASH_ERROR; return false;
} }
vPortEnterCritical(); vPortEnterCritical();
@ -269,5 +255,5 @@ uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr)
Cache_Read_Enable(0, 0, 1); Cache_Read_Enable(0, 0, 1);
vPortExitCritical(); vPortExitCritical();
return ESP_SPIFFS_FLASH_OK; return true;
} }

View file

@ -8,14 +8,12 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <sysparam.h> #include <sysparam.h>
#include <espressif/spi_flash.h> #include "spiflash.h"
#include "flashchip.h"
#include <common_macros.h> #include <common_macros.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "semphr.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. /* The "magic" value that indicates the start of a sysparam region in flash.
*/ */
#define SYSPARAM_MAGIC 0x70524f45 // "EORp" in little-endian #define SYSPARAM_MAGIC 0x70524f45 // "EORp" in little-endian
@ -33,11 +31,14 @@
*/ */
#define SCAN_BUFFER_SIZE 8 // words #define SCAN_BUFFER_SIZE 8 // words
/* The size of the temporary buffer used for reading back and verifying data /* The size in words of the buffer used for reading keys when searching for a
* written to flash. Making this larger will make the write-and-verify * match, for reading payloads to check if the value has changed, and reading
* operation slightly faster, but will use more heap during writes * 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 /* Size of region/entry headers. These should not normally need tweaking (and
* will probably require some code changes if they are tweaked). * will probably require some code changes if they are tweaked).
@ -76,14 +77,16 @@
/******************************* Useful Macros *******************************/ /******************************* Useful Macros *******************************/
#define ROUND_TO_WORD_BOUNDARY(x) (((x) + 3) & 0xfffffffc) #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 max(x, y) ((x) > (y) ? (x) : (y))
#define min(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 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 *********************/ /********************* Internal datatypes and structures *********************/
@ -119,50 +122,28 @@ static struct {
/***************************** Internal routines *****************************/ /***************************** Internal routines *****************************/
static inline IRAM sysparam_status_t _do_write(uint32_t addr, const void *data, size_t data_size) { static sysparam_status_t _write_and_verify(uint32_t addr, const void *data, size_t data_size) {
CHECK_FLASH_OP(sdk_spi_flash_write(addr, (void*) data, data_size)); uint8_t bounce[BOUNCE_BUFFER_SIZE];
return SYSPARAM_OK;
}
static inline IRAM sysparam_status_t _do_verify(uint32_t addr, const void *data, void *buffer, size_t len) { for (int i = 0; i < data_size; i += BOUNCE_BUFFER_SIZE) {
CHECK_FLASH_OP(sdk_spi_flash_read(addr, buffer, len)); size_t count = min(data_size - i, BOUNCE_BUFFER_SIZE);
if (memcmp(data, buffer, len)) { 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_ERR_IO;
} }
}
return SYSPARAM_OK; 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 */ /** Erase the sectors of a region */
static sysparam_status_t _format_region(uint32_t addr, uint16_t num_sectors) { static sysparam_status_t _format_region(uint32_t addr, uint16_t num_sectors) {
uint16_t sector = addr / sdk_flashchip.sector_size;
int i; int i;
for (i = 0; i < num_sectors; 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; return SYSPARAM_OK;
} }
@ -212,7 +193,7 @@ static sysparam_status_t init_write_context(struct sysparam_context *ctx) {
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
ctx->addr = _sysparam_info.end_addr; ctx->addr = _sysparam_info.end_addr;
debug(3, "read entry header @ 0x%08x", ctx->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; 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 // workaround is to make sure that the next write operation
// will always start with a compaction, which will leave off // will always start with a compaction, which will leave off
// the invalid data at the end and fix the issue going forward. // 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; _sysparam_info.force_compact = true;
break; 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); 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); debug(3, " idflags = 0x%04x", ctx->entry.idflags);
if (ctx->entry.idflags == 0xffff) { if (ctx->entry.idflags == 0xffff) {
// 0xffff is never a valid id field, so this means we've hit the // 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` */ /** 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) { 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); uint32_t addr = ctx->addr + ENTRY_HEADER_SIZE;
CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr + ENTRY_HEADER_SIZE, (void*) buffer, min(buffer_size, ctx->entry.len))); 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; return SYSPARAM_OK;
} }
/** Find the entry corresponding to the specified key name */ /** 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; 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) { while (true) {
// Find the next key entry // Find the next key entry
status = _find_entry(ctx, ENTRY_ID_ANY, false); 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; break;
} }
if (ctx->entry.len == key_len) { if (ctx->entry.len == key_len) {
status = _read_payload(ctx, buffer, key_len); status = _compare_payload(ctx, (uint8_t *)key, key_len);
if (status < 0) return status; if (status == SYSPARAM_OK) {
if (!memcmp(key, buffer, key_len)) {
// We have a match // We have a match
break; break;
} }
if (status != SYSPARAM_NOTFOUND) return status;
debug(3, "entry payload does not match"); debug(3, "entry payload does not match");
} else { } else {
debug(3, "key length (%d) does not match (%d)", ctx->entry.len, key_len); 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(2, "Deleting entry @ 0x%08x", addr);
debug(3, "read entry header @ 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" // Set the ID to zero to mark it as "deleted"
entry.idflags &= ~ENTRY_FLAG_ALIVE; entry.idflags &= ~ENTRY_FLAG_ALIVE;
debug(3, "write entry header @ 0x%08x", addr); debug(3, "write entry header @ 0x%08x", addr);
CHECK_FLASH_OP(sdk_spi_flash_write(addr, (void*) &entry, ENTRY_HEADER_SIZE)); return _write_and_verify(addr, &entry, ENTRY_HEADER_SIZE);
return SYSPARAM_OK;
} }
/** Compact the current region, removing all deleted/unused entries, and write /** Compact the current region, removing all deleted/unused entries, and write
* the result to the alternate region, then make the new alternate region the * the result to the alternate region, then make the new alternate region the
* active one. * 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 * 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 * 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 binary_flag;
uint16_t num_sectors = _sysparam_info.region_size / sdk_flashchip.sector_size; 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); status = _format_region(new_base, num_sectors);
if (status < 0) return status; if (status < 0) return status;
status = sysparam_iter_start(&iter); 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; if (status < 0) break;
addr += ENTRY_SIZE(iter.key_len); 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 // Update key_id to have the correct id for the compacted result
*key_id = current_key_id; *key_id = current_key_id;
// Don't copy the old value, since we'll just be deleting it // 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.end_addr = addr;
_sysparam_info.force_compact = false; _sysparam_info.force_compact = false;
if (ctx) {
// Fix up ctx so it doesn't point to invalid stuff // Fix up ctx so it doesn't point to invalid stuff
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
ctx->addr = addr; ctx->addr = addr;
ctx->max_key_id = current_key_id; ctx->max_key_id = current_key_id;
}
debug(1, "done compacting (current size %d)", _sysparam_info.end_addr - _sysparam_info.cur_base); 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; struct sysparam_context ctx;
uint16_t num_sectors; uint16_t num_sectors;
_sysparam_info.sem = xSemaphoreCreateMutex();
// Make sure we're starting at the beginning of the sector // Make sure we're starting at the beginning of the sector
base_addr -= (base_addr % sdk_flashchip.sector_size); 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; top_addr = base_addr + sdk_flashchip.sector_size;
} }
for (addr0 = base_addr; addr0 < top_addr; addr0 += 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) { if (header0.magic == SYSPARAM_MAGIC) {
// Found a starting point... // Found a starting point...
break; break;
@ -521,7 +533,7 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
} else { } else {
addr1 = addr0 + num_sectors * sdk_flashchip.sector_size; 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) { if (header1.magic == SYSPARAM_MAGIC) {
// Yay! Found the other one. Sanity-check it.. // 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.end_addr = ctx.addr;
} }
_sysparam_info.sem = xSemaphoreCreateMutex();
return SYSPARAM_OK; return SYSPARAM_OK;
} }
@ -596,9 +606,9 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, uint16_t num_sectors,
if (!force) { if (!force) {
// First, scan through the area and make sure it's actually empty and // First, scan through the area and make sure it's actually empty and
// we're not going to be clobbering something else important. // 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); 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++) { for (i = 0; i < SCAN_BUFFER_SIZE; i++) {
if (buffer[i] != 0xffffffff) { if (buffer[i] != 0xffffffff) {
// Uh oh, not empty. // 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; 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) { sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary) {
struct sysparam_context ctx; struct sysparam_context ctx;
sysparam_status_t status; sysparam_status_t status;
size_t key_len = strlen(key); size_t key_len = strlen(key);
uint8_t *buffer; 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); _init_context(&ctx);
status = _find_key(&ctx, key, key_len, buffer); status = _find_key(&ctx, key, key_len);
if (status != SYSPARAM_OK) break; if (status != SYSPARAM_OK) goto done;
// Find the associated value // Find the associated value
status = _find_value(&ctx, ctx.entry.idflags); 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); buffer = malloc(ctx.entry.len + 1);
if (!newbuf) { if (!buffer) {
status = SYSPARAM_ERR_NOMEM; status = SYSPARAM_ERR_NOMEM;
break; goto done;
} }
buffer = newbuf;
status = _read_payload(&ctx, buffer, ctx.entry.len); 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 // 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 // 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; *destptr = buffer;
if (actual_length) *actual_length = ctx.entry.len; if (actual_length) *actual_length = ctx.entry.len;
if (is_binary) *is_binary = (bool)(ctx.entry.idflags & ENTRY_FLAG_BINARY); if (is_binary) *is_binary = (bool)(ctx.entry.idflags & ENTRY_FLAG_BINARY);
return SYSPARAM_OK; status = SYSPARAM_OK;
} while (false);
free(buffer); done:
if (actual_length) *actual_length = 0; xSemaphoreGive(_sysparam_info.sem);
return status; 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; struct sysparam_context ctx;
sysparam_status_t status = SYSPARAM_OK; sysparam_status_t status = SYSPARAM_OK;
size_t key_len = strlen(key); size_t key_len = strlen(key);
if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
// 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;
if (actual_length) *actual_length = 0; if (actual_length) *actual_length = 0;
if (!_sysparam_info.cur_base) {
status = SYSPARAM_ERR_NOINIT;
goto done;
}
_init_context(&ctx); _init_context(&ctx);
status = _find_key(&ctx, key, key_len, buffer); status = _find_key(&ctx, key, key_len);
if (status != SYSPARAM_OK) return status; if (status != SYSPARAM_OK) goto done;
status = _find_value(&ctx, ctx.entry.idflags); status = _find_value(&ctx, ctx.entry.idflags);
if (status != SYSPARAM_OK) return status; if (status != SYSPARAM_OK) goto done;
status = _read_payload(&ctx, buffer, buffer_size); status = _read_payload(&ctx, dest, dest_size);
if (status != SYSPARAM_OK) return status; if (status != SYSPARAM_OK) goto done;
if (actual_length) *actual_length = ctx.entry.len; if (actual_length) *actual_length = ctx.entry.len;
if (is_binary) *is_binary = (bool)(ctx.entry.idflags & ENTRY_FLAG_BINARY); 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) { 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) { sysparam_status_t sysparam_get_int32(const char *key, int32_t *result) {
char *buffer;
char *endptr;
int32_t value; int32_t value;
size_t actual_length;
bool is_binary;
sysparam_status_t status; 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; if (status != SYSPARAM_OK) return status;
value = strtol(buffer, &endptr, 0); if (!is_binary || actual_length != sizeof(int32_t))
if (*endptr) {
// There was extra crap at the end of the string.
free(buffer);
return SYSPARAM_PARSEFAILED; return SYSPARAM_PARSEFAILED;
}
*result = value; *result = value;
free(buffer); return status;
return SYSPARAM_OK;
} }
sysparam_status_t sysparam_get_int8(const char *key, int8_t *result) { 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; sysparam_status_t status;
status = sysparam_get_int32(key, &value); status = sysparam_get_data_static(key, (uint8_t *)&value, sizeof(int8_t),
if (status == SYSPARAM_OK) { &actual_length, &is_binary);
if (status != SYSPARAM_OK) return status;
if (!is_binary || actual_length != sizeof(int8_t))
return SYSPARAM_PARSEFAILED;
*result = value; *result = value;
}
return status; return status;
} }
sysparam_status_t sysparam_get_bool(const char *key, bool *result) { 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; 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; if (status != SYSPARAM_OK) return status;
do { do {
if (!strcasecmp(buffer, "y") || if (binary) {
!strcasecmp(buffer, "yes") || if (data_len == 1) { // int8 value
!strcasecmp(buffer, "t") || uint8_t value;
!strcasecmp(buffer, "true") || memcpy(&value, buf, sizeof(value));
!strcmp(buffer, "1")) { *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; *result = true;
break; break;
} }
if (!strcasecmp(buffer, "n") || if (!strcasecmp(buf, "n") ||
!strcasecmp(buffer, "no") || !strcasecmp(buf, "no") ||
!strcasecmp(buffer, "f") || !strcasecmp(buf, "f") ||
!strcasecmp(buffer, "false") || !strcasecmp(buf, "false") ||
!strcmp(buffer, "0")) { !strcmp(buf, "0")) {
*result = false; *result = false;
break; break;
} }
status = SYSPARAM_PARSEFAILED; status = SYSPARAM_PARSEFAILED;
} while (0); } while (0);
free(buffer);
return status; 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; struct sysparam_context write_ctx;
sysparam_status_t status = SYSPARAM_OK; sysparam_status_t status = SYSPARAM_OK;
uint16_t key_len = strlen(key); uint16_t key_len = strlen(key);
uint8_t *buffer;
uint8_t *newbuf;
size_t free_space; size_t free_space;
size_t needed_space; size_t needed_space;
bool free_value = false;
int key_id = -1; int key_id = -1;
uint32_t old_value_addr = 0; uint32_t old_value_addr = 0;
uint16_t binary_flag; uint16_t binary_flag;
if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
if (!key_len) return SYSPARAM_ERR_BADVALUE; if (!key_len) return SYSPARAM_ERR_BADVALUE;
if (key_len > MAX_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; if (value_len > MAX_VALUE_LEN) return SYSPARAM_ERR_BADVALUE;
xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
if (!value) value_len = 0; if (!value) value_len = 0;
debug(1, "updating value for '%s' (%d bytes)", key, value_len); 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 xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY);
// when calling `sdk_spi_flash_write`, so make a word-aligned copy.
buffer = malloc(value_len); if (!_sysparam_info.cur_base) {
if (!buffer) { status = SYSPARAM_ERR_NOINIT;
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;
goto done; goto done;
} }
do { do {
_init_context(&ctx); _init_context(&ctx);
status = _find_key(&ctx, key, key_len, buffer); status = _find_key(&ctx, key, key_len);
if (status == SYSPARAM_OK) { if (status == SYSPARAM_OK) {
// Key already exists, see if there's a current value. // Key already exists, see if there's a current value.
key_id = ctx.entry.idflags & ENTRY_MASK_ID; 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 (value_len) {
if (old_value_addr) { 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? // Are we trying to write the same value that's already there?
if (value_len > key_len) { status = _compare_payload(&ctx, (uint8_t *)value, value_len);
newbuf = realloc(buffer, value_len); if (status == SYSPARAM_OK) {
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)) {
// Yup, it's a match! No need to do anything further, // Yup, it's a match! No need to do anything further,
// just leave the current value as-is. // just leave the current value as-is.
status = SYSPARAM_OK; status = SYSPARAM_OK;
break; break;
} }
if (status != SYSPARAM_NOTFOUND) goto done;
} }
// Since we will be deleting the old value (if any) make sure // 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); 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); } while (false);
if (free_value) free((void *)value);
free(buffer);
done: done:
xSemaphoreGive(_sysparam_info.sem); 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) { sysparam_status_t sysparam_set_int32(const char *key, int32_t value) {
uint8_t buffer[12]; return sysparam_set_data(key, (const uint8_t *)&value, sizeof(value), true);
int len;
len = snprintf((char *)buffer, 12, "%d", value);
return sysparam_set_data(key, buffer, len, false);
} }
sysparam_status_t sysparam_set_int8(const char *key, int8_t value) { 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) { 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) { sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
uint8_t buffer[2];
sysparam_status_t status; sysparam_status_t status;
size_t required_len; size_t required_len;
struct sysparam_context *ctx = iter->ctx; struct sysparam_context *ctx = iter->ctx;
@ -1036,7 +1055,7 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
char *newbuf; char *newbuf;
while (true) { while (true) {
status = _find_key(ctx, NULL, 0, buffer); status = _find_key(ctx, NULL, 0);
if (status != SYSPARAM_OK) return status; if (status != SYSPARAM_OK) return status;
memcpy(&value_ctx, ctx, sizeof(value_ctx)); 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 < 0) return status;
if (status == SYSPARAM_NOTFOUND) continue; 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; required_len = key_space + value_ctx.entry.len + 1;
if (required_len > iter->bufsize) { if (required_len > iter->bufsize) {
newbuf = realloc(iter->key, required_len); newbuf = realloc(iter->key, required_len);

View file

@ -2,6 +2,7 @@ EXAMPLES = $(shell find $(dir $(lastword $(MAKEFILE_LIST))) -mindepth 2 -name Ma
# Generate some dummy .dummybuild/.dummyrebuild target files # Generate some dummy .dummybuild/.dummyrebuild target files
EXAMPLES_BUILD = $(patsubst %,%.dummybuild,$(EXAMPLES)) EXAMPLES_BUILD = $(patsubst %,%.dummybuild,$(EXAMPLES))
EXAMPLES_REBUILD = $(patsubst %,%.dummyrebuild,$(EXAMPLES)) EXAMPLES_REBUILD = $(patsubst %,%.dummyrebuild,$(EXAMPLES))
EXAMPLES_CLEAN = $(patsubst %,%.dummyclean,$(EXAMPLES))
warning: warning:
@echo "******************************************************" @echo "******************************************************"
@ -21,12 +22,17 @@ build-examples: $(EXAMPLES_BUILD)
rebuild-examples: $(EXAMPLES_REBUILD) rebuild-examples: $(EXAMPLES_REBUILD)
clean-examples: $(EXAMPLES_CLEAN)
%.dummybuild: %.dummybuild:
$(MAKE) -C $(dir $@) $(MAKE) -C $(dir $@)
%.dummyrebuild: %.dummyrebuild:
$(MAKE) -C $(dir $@) rebuild $(MAKE) -C $(dir $@) rebuild
.PHONY: warning rebuild-examples build-examples %.dummyclean:
$(MAKE) -C $(dir $@) clean
.PHONY: warning rebuild-examples build-examples clean-examples
.NOTPARALLEL: .NOTPARALLEL:
.ONESHELL: .ONESHELL:

View file

@ -1,11 +1,11 @@
/* Very basic example showing usage of access point mode and the DHCP server. /**
* 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 * 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 * outputs some status information if you connect to it, then closes
the connection. * the connection.
*
This example code is in the public domain. * This example code is in the public domain.
*/ */
#include <string.h> #include <string.h>
#include <espressif/esp_common.h> #include <espressif/esp_common.h>
@ -36,44 +36,39 @@ void user_init(void)
IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0); IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0);
sdk_wifi_set_ip_info(1, &ap_ip); sdk_wifi_set_ip_info(1, &ap_ip);
struct sdk_softap_config ap_config = { struct sdk_softap_config ap_config = { .ssid = AP_SSID, .ssid_hidden = 0, .channel = 3, .ssid_len = strlen(AP_SSID), .authmode =
.ssid = AP_SSID, AUTH_WPA_WPA2_PSK, .password = AP_PSK, .max_connection = 3, .beacon_interval = 100, };
.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); 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); xTaskCreate(telnetTask, "telnetTask", 512, NULL, 2, NULL);
} }
/* Telnet task listens on port 23, returns some status information and then closes /* Telnet task listens on port 23, returns some status information and then closes
the connection if you connect to it. the connection if you connect to it.
*/ */
static void telnetTask(void *pvParameters) static void telnetTask(void *pvParameters)
{ {
struct netconn *nc = netconn_new (NETCONN_TCP); ip_addr_t first_client_ip;
if(!nc) { 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"); printf("Status monitor: Failed to allocate socket.\r\n");
return; return;
} }
netconn_bind(nc, IP_ADDR_ANY, TELNET_PORT); netconn_bind(nc, IP_ANY_TYPE, TELNET_PORT);
netconn_listen(nc); netconn_listen(nc);
while(1) { while (1)
{
struct netconn *client = NULL; struct netconn *client = NULL;
err_t err = netconn_accept(nc, &client); err_t err = netconn_accept(nc, &client);
if ( err != ERR_OK ) { if (err != ERR_OK)
if(client) {
if (client)
netconn_delete(client); netconn_delete(client);
continue; continue;
} }
@ -83,14 +78,12 @@ static void telnetTask(void *pvParameters)
netconn_peer(client, &client_addr, &port_ignore); netconn_peer(client, &client_addr, &port_ignore);
char buf[80]; char buf[80];
snprintf(buf, sizeof(buf), "Uptime %d seconds\r\n", snprintf(buf, sizeof(buf), "Uptime %d seconds\r\n", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
xTaskGetTickCount()*portTICK_PERIOD_MS/1000);
netconn_write(client, buf, strlen(buf), NETCONN_COPY); 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); netconn_write(client, buf, strlen(buf), NETCONN_COPY);
snprintf(buf, sizeof(buf), "Your address is %d.%d.%d.%d\r\n\r\n", char abuf[40];
ip4_addr1(&client_addr), ip4_addr2(&client_addr), snprintf(buf, sizeof(buf), "Your address is %s\r\n\r\n", ipaddr_ntoa_r(&client_addr, abuf, sizeof(abuf)));
ip4_addr3(&client_addr), ip4_addr4(&client_addr));
netconn_write(client, buf, strlen(buf), NETCONN_COPY); netconn_write(client, buf, strlen(buf), NETCONN_COPY);
netconn_delete(client); netconn_delete(client);
} }

4
examples/ad770x/Makefile Normal file
View file

@ -0,0 +1,4 @@
PROGRAM = ad770x
EXTRA_COMPONENTS = extras/ad770x
#ESPBAUD = 460800
include ../../common.mk

49
examples/ad770x/main.c Normal file
View 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);
}
}

View file

@ -0,0 +1,4 @@
PROGRAM = ads1115_test
EXTRA_COMPONENTS = extras/i2c extras/ads111x
#ESPBAUD = 460800
include ../../common.mk

View 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);
}
}

View file

@ -4,7 +4,7 @@
// this must be ahead of any mbedtls header files so the local mbedtls/config.h can be properly referenced // 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/config.h"
#include "mbedtls/net.h" #include "mbedtls/net_sockets.h"
#include "mbedtls/debug.h" #include "mbedtls/debug.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#include "mbedtls/entropy.h" #include "mbedtls/entropy.h"

3
examples/bh1750/Makefile Normal file
View file

@ -0,0 +1,3 @@
PROGRAM=bh1750_example
EXTRA_COMPONENTS = extras/i2c extras/bh1750
include ../../common.mk

View 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);
}

View file

@ -17,13 +17,13 @@ const int freq_frc2 = 10;
static volatile uint32_t frc1_count; static volatile uint32_t frc1_count;
static volatile uint32_t frc2_count; static volatile uint32_t frc2_count;
void frc1_interrupt_handler(void) void frc1_interrupt_handler(void *arg)
{ {
frc1_count++; frc1_count++;
gpio_toggle(gpio_frc1); 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 */ /* FRC2 needs the match register updated on each timer interrupt */
timer_set_frequency(FRC2, freq_frc2); timer_set_frequency(FRC2, freq_frc2);
@ -47,8 +47,8 @@ void user_init(void)
timer_set_run(FRC2, false); timer_set_run(FRC2, false);
/* set up ISRs */ /* set up ISRs */
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler); _xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
_xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler); _xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler, NULL);
/* configure timer frequencies */ /* configure timer frequencies */
timer_set_frequency(FRC1, freq_frc1); timer_set_frequency(FRC1, freq_frc1);

46
examples/bme680/README.md Normal file
View 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.

View file

@ -0,0 +1,3 @@
PROGRAM=BME680_heating_profiles
EXTRA_COMPONENTS = extras/i2c extras/bme680
include ../../../common.mk

View file

@ -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");
}

View file

@ -0,0 +1,3 @@
PROGRAM=BME680_One_Sensor
EXTRA_COMPONENTS = extras/i2c extras/bme680
include ../../../common.mk

View 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");
}

View file

@ -0,0 +1,3 @@
PROGRAM=BME680_Tow_Sensors
EXTRA_COMPONENTS = extras/i2c extras/bme680
include ../../../common.mk

View 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);
}
}

View file

@ -13,18 +13,25 @@
// BMP180 driver // BMP180 driver
#include "bmp180/bmp180.h" #include "bmp180/bmp180.h"
#define MY_EVT_TIMER 0x01 #define I2C_BUS 0
#define MY_EVT_BMP180 0x02
#define SCL_PIN GPIO_ID_PIN((0)) #define SCL_PIN GPIO_ID_PIN((0))
#define SDA_PIN GPIO_ID_PIN((2)) #define SDA_PIN GPIO_ID_PIN((2))
#define MY_EVT_TIMER 0x01
#define MY_EVT_BMP180 0x02
typedef struct typedef struct
{ {
uint8_t event_type; uint8_t event_type;
bmp180_result_t bmp180_data; bmp180_result_t bmp180_data;
} my_event_t; } my_event_t;
//device descriptor
i2c_dev_t dev = {
.addr = BMP180_DEVICE_ADDRESS,
.bus = I2C_BUS,
};
// Communication Queue // Communication Queue
static QueueHandle_t mainqueue; static QueueHandle_t mainqueue;
static TimerHandle_t timerHandle; static TimerHandle_t timerHandle;
@ -70,7 +77,7 @@ void bmp180_task(void *pvParameters)
case MY_EVT_TIMER: case MY_EVT_TIMER:
printf("%s: Received Timer Event\n", __FUNCTION__); printf("%s: Received Timer Event\n", __FUNCTION__);
bmp180_trigger_measurement(com_queue); bmp180_trigger_measurement(&dev, com_queue);
break; break;
case MY_EVT_BMP180: case MY_EVT_BMP180:
printf("%s: Received BMP180 Event temp:=%d.%dC press=%d.%02dhPa\n", __FUNCTION__, \ 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 // Give the UART some time to settle
sdk_os_delay_us(500); sdk_os_delay_us(500);
// Init I2C bus Interface
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);
} }
void user_init(void) void user_init(void)
@ -107,7 +117,7 @@ void user_init(void)
bmp180_informUser = bmp180_i2c_informUser; bmp180_informUser = bmp180_i2c_informUser;
// Init BMP180 Interface // Init BMP180 Interface
bmp180_init(SCL_PIN, SDA_PIN); bmp180_init(&dev);
// Create Main Communication Queue // Create Main Communication Queue
mainqueue = xQueueCreate(10, sizeof(my_event_t)); mainqueue = xQueueCreate(10, sizeof(my_event_t));

View file

@ -12,7 +12,7 @@
// In forced mode user initiate measurement each time. // In forced mode user initiate measurement each time.
// In normal mode measurement is done continuously with specified standby time. // In normal mode measurement is done continuously with specified standby time.
// #define MODE_FORCED // #define MODE_FORCED
const uint8_t i2c_bus = 0;
const uint8_t scl_pin = 0; const uint8_t scl_pin = 0;
const uint8_t sda_pin = 2; const uint8_t sda_pin = 2;
@ -26,7 +26,8 @@ static void bmp280_task_forced(void *pvParameters)
params.mode = BMP280_MODE_FORCED; params.mode = BMP280_MODE_FORCED;
bmp280_t bmp280_dev; 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 (1) {
while (!bmp280_init(&bmp280_dev, &params)) { while (!bmp280_init(&bmp280_dev, &params)) {
@ -67,7 +68,8 @@ static void bmp280_task_normal(void *pvParameters)
bmp280_init_default_params(&params); bmp280_init_default_params(&params);
bmp280_t bmp280_dev; 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 (1) {
while (!bmp280_init(&bmp280_dev, &params)) { while (!bmp280_init(&bmp280_dev, &params)) {
@ -103,7 +105,7 @@ void user_init(void)
printf("SDK version : %s\n", sdk_system_get_sdk_version()); printf("SDK version : %s\n", sdk_system_get_sdk_version());
printf("GIT version : %s\n", GITSHORTREV); 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 #ifdef MODE_FORCED
xTaskCreate(bmp280_task_forced, "bmp280_task", 256, NULL, 2, NULL); xTaskCreate(bmp280_task_forced, "bmp280_task", 256, NULL, 2, NULL);

View file

@ -16,7 +16,6 @@
const int gpio = 0; /* gpio 0 usually has "PROGRAM" button attached */ const int gpio = 0; /* gpio 0 usually has "PROGRAM" button attached */
const int active = 0; /* active == 0 for active low */ const int active = 0; /* active == 0 for active low */
const gpio_inttype_t int_type = GPIO_INTTYPE_EDGE_NEG; 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 /* 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 /* This task configures the GPIO interrupt and uses it to tell
when the button is pressed. 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); printf("Waiting for button press interrupt on gpio %d...\r\n", gpio);
QueueHandle_t *tsqueue = (QueueHandle_t *)pvParameters; 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; uint32_t last = 0;
while(1) { while(1) {
@ -67,7 +68,7 @@ void buttonIntTask(void *pvParameters)
static QueueHandle_t tsqueue; static QueueHandle_t tsqueue;
void GPIO_HANDLER(void) void gpio_intr_handler(uint8_t gpio_num)
{ {
uint32_t now = xTaskGetTickCountFromISR(); uint32_t now = xTaskGetTickCountFromISR();
xQueueSendToBackFromISR(tsqueue, &now, NULL); xQueueSendToBackFromISR(tsqueue, &now, NULL);

57
examples/ccs811/README.md Normal file
View 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.

View file

@ -0,0 +1,4 @@
PROGRAM=CCS811_One_Sensor
EXTRA_COMPONENTS = extras/i2c extras/ccs811
include ../../../common.mk

View 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");
}

View file

@ -0,0 +1,3 @@
PROGRAM=CCS811_Plus_SHT3x
EXTRA_COMPONENTS = extras/i2c extras/ccs811 extras/sht3x
include ../../../common.mk

View 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);
}

View file

@ -0,0 +1,4 @@
PROGRAM=CCS811_Temperature
EXTRA_COMPONENTS = extras/i2c extras/ccs811
LIBS ?= gcc hal m
include ../../../common.mk

View 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);
}
}

View file

@ -0,0 +1,3 @@
PROGRAM=crc_example
EXTRA_COMPONENTS = extras/crc_generic
include ../../common.mk

View 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"

View 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_ */

View 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);
}

View file

@ -11,6 +11,7 @@
#include <ds1307/ds1307.h> #include <ds1307/ds1307.h>
#include <stdio.h> #include <stdio.h>
#define I2C_BUS 0
#define SCL_PIN 5 #define SCL_PIN 5
#define SDA_PIN 4 #define SDA_PIN 4
@ -19,8 +20,12 @@ void user_init(void)
uart_set_baud(0, 115200); uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version()); printf("SDK version:%s\n", sdk_system_get_sdk_version());
i2c_init(SCL_PIN, SDA_PIN); i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K);
ds1307_start(true); i2c_dev_t dev = {
.addr = DS1307_ADDR,
.bus = I2C_BUS,
};
ds1307_start(&dev, true);
// setup datetime: 2016-10-09 13:50:10 // setup datetime: 2016-10-09 13:50:10
struct tm time = { struct tm time = {
@ -31,11 +36,11 @@ void user_init(void)
.tm_min = 50, .tm_min = 50,
.tm_sec = 10 .tm_sec = 10
}; };
ds1307_set_time(&time); ds1307_set_time(&dev, &time);
while (true) 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, 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); time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);

View file

@ -12,15 +12,21 @@
#include "ds3231/ds3231.h" #include "ds3231/ds3231.h"
#define ADDR DS3231_ADDR
#define I2C_BUS 0
void task1(void *pvParameters) void task1(void *pvParameters)
{ {
struct tm time; struct tm time;
float tempFloat; float tempFloat;
i2c_dev_t dev = {
.addr = ADDR,
.bus = I2C_BUS,
};
while(1) { while(1) {
vTaskDelay(100); vTaskDelay(100);
ds3231_getTime(&time); ds3231_getTime(&dev, &time);
ds3231_getTempFloat(&tempFloat); ds3231_getTempFloat(&dev, &tempFloat);
printf("TIME:%d:%d:%d, TEMPERATURE:%.2f DegC\r\n", time.tm_hour, time.tm_min, time.tm_sec, 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("SDK version : %s\n", sdk_system_get_sdk_version());
printf("GIT version : %s\n", GITSHORTREV); 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); xTaskCreate(task1, "tsk1", 256, NULL, 2, NULL);
} }

View file

@ -0,0 +1,4 @@
# Simple makefile for simple example
PROGRAM=dsm_test
EXTRA_COMPONENTS = extras/dsm
include ../../common.mk

View 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);
}

View 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>

View 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

View 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;
}

View 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
View 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
View 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