diff --git a/libraries/WiFi/library.properties b/libraries/WiFi/library.properties index d2c878c7015..a9a5457e640 100644 --- a/libraries/WiFi/library.properties +++ b/libraries/WiFi/library.properties @@ -1,5 +1,5 @@ name=WiFi -version=2.0.0 +version=2.0.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 0c3acc28688..7023daf8148 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -557,6 +557,18 @@ bool wifiLowLevelInit(bool persistent){ } wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + +#if 1 + // TWEAK to force Dynamic Buffer instead of Static ones + // This uses less heap space in Arduino and makes it similar to 1.0.6 configuration + cfg.static_tx_buf_num = 0; + cfg.dynamic_tx_buf_num = 32; + cfg.tx_buf_type = 1; + cfg.cache_tx_buf_num = 1; // it can't be zero for WPA/WPA2 + cfg.static_rx_buf_num = 4; + cfg.dynamic_rx_buf_num = 32; +#endif + esp_err_t err = esp_wifi_init(&cfg); if(err){ log_e("esp_wifi_init %d", err); diff --git a/platform.txt b/platform.txt index 1b92b64efa8..1c143b591d2 100644 --- a/platform.txt +++ b/platform.txt @@ -25,9 +25,9 @@ compiler.prefix={build.tarch}-{build.target}-elf- # compiler.cpreprocessor.flags.esp32=-DHAVE_CONFIG_H -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DUNITY_INCLUDE_CONFIG_H -DWITH_POSIX -D_GNU_SOURCE -DIDF_VER="v4.4-dev-3235-g3e370c4296" -DESP_PLATFORM "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/newlib/platform_include" "-I{compiler.sdk.path}/include/freertos/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions/freertos" "-I{compiler.sdk.path}/include/freertos/port/xtensa/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions" "-I{compiler.sdk.path}/include/esp_hw_support/include" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc/esp32" "-I{compiler.sdk.path}/include/esp_hw_support/port/esp32" "-I{compiler.sdk.path}/include/heap/include" "-I{compiler.sdk.path}/include/log/include" "-I{compiler.sdk.path}/include/lwip/include/apps" "-I{compiler.sdk.path}/include/lwip/include/apps/sntp" "-I{compiler.sdk.path}/include/lwip/lwip/src/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include/arch" "-I{compiler.sdk.path}/include/soc/include" "-I{compiler.sdk.path}/include/soc/esp32" "-I{compiler.sdk.path}/include/soc/esp32/include" "-I{compiler.sdk.path}/include/hal/esp32/include" "-I{compiler.sdk.path}/include/hal/include" "-I{compiler.sdk.path}/include/hal/platform_port/include" "-I{compiler.sdk.path}/include/esp_rom/include" "-I{compiler.sdk.path}/include/esp_rom/include/esp32" "-I{compiler.sdk.path}/include/esp_rom/esp32" "-I{compiler.sdk.path}/include/esp_common/include" "-I{compiler.sdk.path}/include/esp_system/include" "-I{compiler.sdk.path}/include/esp_system/port/soc" "-I{compiler.sdk.path}/include/esp_system/port/public_compat" "-I{compiler.sdk.path}/include/esp32/include" "-I{compiler.sdk.path}/include/xtensa/include" "-I{compiler.sdk.path}/include/xtensa/esp32/include" "-I{compiler.sdk.path}/include/driver/include" "-I{compiler.sdk.path}/include/driver/esp32/include" "-I{compiler.sdk.path}/include/esp_pm/include" "-I{compiler.sdk.path}/include/esp_ringbuf/include" "-I{compiler.sdk.path}/include/efuse/include" "-I{compiler.sdk.path}/include/efuse/esp32/include" "-I{compiler.sdk.path}/include/vfs/include" "-I{compiler.sdk.path}/include/esp_wifi/include" "-I{compiler.sdk.path}/include/esp_event/include" "-I{compiler.sdk.path}/include/esp_netif/include" "-I{compiler.sdk.path}/include/esp_eth/include" "-I{compiler.sdk.path}/include/tcpip_adapter/include" "-I{compiler.sdk.path}/include/esp_phy/include" "-I{compiler.sdk.path}/include/esp_phy/esp32/include" "-I{compiler.sdk.path}/include/esp_ipc/include" "-I{compiler.sdk.path}/include/app_trace/include" "-I{compiler.sdk.path}/include/esp_timer/include" "-I{compiler.sdk.path}/include/mbedtls/port/include" "-I{compiler.sdk.path}/include/mbedtls/mbedtls/include" "-I{compiler.sdk.path}/include/mbedtls/esp_crt_bundle/include" "-I{compiler.sdk.path}/include/app_update/include" "-I{compiler.sdk.path}/include/spi_flash/include" "-I{compiler.sdk.path}/include/bootloader_support/include" "-I{compiler.sdk.path}/include/nvs_flash/include" "-I{compiler.sdk.path}/include/pthread/include" "-I{compiler.sdk.path}/include/esp_gdbstub/include" "-I{compiler.sdk.path}/include/esp_gdbstub/xtensa" "-I{compiler.sdk.path}/include/esp_gdbstub/esp32" "-I{compiler.sdk.path}/include/espcoredump/include" "-I{compiler.sdk.path}/include/espcoredump/include/port/xtensa" "-I{compiler.sdk.path}/include/wpa_supplicant/include" "-I{compiler.sdk.path}/include/wpa_supplicant/port/include" "-I{compiler.sdk.path}/include/wpa_supplicant/esp_supplicant/include" "-I{compiler.sdk.path}/include/ieee802154/include" "-I{compiler.sdk.path}/include/asio/asio/asio/include" "-I{compiler.sdk.path}/include/asio/port/include" "-I{compiler.sdk.path}/include/bt/common/osi/include" "-I{compiler.sdk.path}/include/bt/include/esp32/include" "-I{compiler.sdk.path}/include/bt/common/api/include/api" "-I{compiler.sdk.path}/include/bt/common/btc/profile/esp/blufi/include" "-I{compiler.sdk.path}/include/bt/common/btc/profile/esp/include" "-I{compiler.sdk.path}/include/bt/host/bluedroid/api/include/api" "-I{compiler.sdk.path}/include/cbor/port/include" "-I{compiler.sdk.path}/include/unity/include" "-I{compiler.sdk.path}/include/unity/unity/src" "-I{compiler.sdk.path}/include/cmock/CMock/src" "-I{compiler.sdk.path}/include/coap/port/include" "-I{compiler.sdk.path}/include/coap/libcoap/include" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/nghttp/port/include" "-I{compiler.sdk.path}/include/nghttp/nghttp2/lib/includes" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp-tls/esp-tls-crypto" "-I{compiler.sdk.path}/include/esp_adc_cal/include" "-I{compiler.sdk.path}/include/esp_hid/include" "-I{compiler.sdk.path}/include/tcp_transport/include" "-I{compiler.sdk.path}/include/esp_http_client/include" "-I{compiler.sdk.path}/include/esp_http_server/include" "-I{compiler.sdk.path}/include/esp_https_ota/include" "-I{compiler.sdk.path}/include/esp_lcd/include" "-I{compiler.sdk.path}/include/esp_lcd/interface" "-I{compiler.sdk.path}/include/protobuf-c/protobuf-c" "-I{compiler.sdk.path}/include/protocomm/include/common" "-I{compiler.sdk.path}/include/protocomm/include/security" "-I{compiler.sdk.path}/include/protocomm/include/transports" "-I{compiler.sdk.path}/include/mdns/include" "-I{compiler.sdk.path}/include/esp_local_ctrl/include" "-I{compiler.sdk.path}/include/sdmmc/include" "-I{compiler.sdk.path}/include/esp_serial_slave_link/include" "-I{compiler.sdk.path}/include/esp_websocket_client/include" "-I{compiler.sdk.path}/include/expat/expat/expat/lib" "-I{compiler.sdk.path}/include/expat/port/include" "-I{compiler.sdk.path}/include/wear_levelling/include" "-I{compiler.sdk.path}/include/fatfs/diskio" "-I{compiler.sdk.path}/include/fatfs/vfs" "-I{compiler.sdk.path}/include/fatfs/src" "-I{compiler.sdk.path}/include/freemodbus/common/include" "-I{compiler.sdk.path}/include/idf_test/include" "-I{compiler.sdk.path}/include/idf_test/include/esp32" "-I{compiler.sdk.path}/include/jsmn/include" "-I{compiler.sdk.path}/include/json/cJSON" "-I{compiler.sdk.path}/include/libsodium/libsodium/src/libsodium/include" "-I{compiler.sdk.path}/include/libsodium/port_include" "-I{compiler.sdk.path}/include/mqtt/esp-mqtt/include" "-I{compiler.sdk.path}/include/openssl/include" "-I{compiler.sdk.path}/include/perfmon/include" "-I{compiler.sdk.path}/include/spiffs/include" "-I{compiler.sdk.path}/include/ulp/include" "-I{compiler.sdk.path}/include/wifi_provisioning/include" "-I{compiler.sdk.path}/include/button/button/include" "-I{compiler.sdk.path}/include/json_parser" "-I{compiler.sdk.path}/include/json_parser/jsmn/include" "-I{compiler.sdk.path}/include/json_generator" "-I{compiler.sdk.path}/include/esp_schedule/include" "-I{compiler.sdk.path}/include/esp_rainmaker/include" "-I{compiler.sdk.path}/include/qrcode/include" "-I{compiler.sdk.path}/include/ws2812_led" "-I{compiler.sdk.path}/include/esp_littlefs/src" "-I{compiler.sdk.path}/include/esp_littlefs/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/dotprod/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/support/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/hann/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman_harris/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman_nuttall/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/nuttall/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/flat_top/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/iir/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/fir/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/add/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/sub/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/mul/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/addc/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/mulc/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/sqrt/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/matrix/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/fft/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/dct/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/conv/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/common/include" "-I{compiler.sdk.path}/include/esp-face/include" "-I{compiler.sdk.path}/include/esp-face/include/tool" "-I{compiler.sdk.path}/include/esp-face/include/typedef" "-I{compiler.sdk.path}/include/esp-face/include/image" "-I{compiler.sdk.path}/include/esp-face/include/math" "-I{compiler.sdk.path}/include/esp-face/include/nn" "-I{compiler.sdk.path}/include/esp-face/include/layer" "-I{compiler.sdk.path}/include/esp-face/include/detect" "-I{compiler.sdk.path}/include/esp-face/include/model_zoo" "-I{compiler.sdk.path}/include/esp32-camera/driver/include" "-I{compiler.sdk.path}/include/esp32-camera/conversions/include" "-I{compiler.sdk.path}/include/fb_gfx/include" compiler.c.elf.libs.esp32=-lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lasio -lbt -lcbor -lunity -lcmock -lcoap -lconsole -lnghttp -lesp-tls -lesp_adc_cal -lesp_hid -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lesp_lcd -lprotobuf-c -lprotocomm -lmdns -lesp_local_ctrl -lsdmmc -lesp_serial_slave_link -lesp_websocket_client -lexpat -lwear_levelling -lfatfs -lfreemodbus -ljsmn -ljson -llibsodium -lmqtt -lopenssl -lperfmon -lspiffs -lulp -lwifi_provisioning -lbutton -ljson_parser -ljson_generator -lesp_schedule -lesp_rainmaker -lqrcode -lws2812_led -lesp-dsp -lesp32-camera -lesp_littlefs -lfb_gfx -lasio -lcbor -lcmock -lunity -lcoap -lesp_lcd -lesp_local_ctrl -lesp_websocket_client -lexpat -lfreemodbus -ljsmn -llibsodium -lperfmon -lesp_adc_cal -lesp_hid -lfatfs -lwear_levelling -lopenssl -lspiffs -lesp_rainmaker -lmqtt -lwifi_provisioning -lprotocomm -lbt -lbtdm_app -lprotobuf-c -lmdns -lconsole -ljson -ljson_parser -ljson_generator -lesp_schedule -lqrcode -lcat_face_detect -lhuman_face_detect -ldl -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lphy -lrtc -lesp_phy -lphy -lrtc -lesp_phy -lphy -lrtc -lxt_hal -lm -lnewlib -lstdc++ -lpthread -lgcc -lcxx -lapp_trace -lgcov -lapp_trace -lgcov -lc -compiler.c.flags.esp32=-mlongcalls -Wno-frame-address -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c -compiler.cpp.flags.esp32=-mlongcalls -Wno-frame-address -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fexceptions -fno-rtti -MMD -c -compiler.S.flags.esp32=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c +compiler.c.flags.esp32=-mlongcalls -Wno-frame-address -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c +compiler.cpp.flags.esp32=-mlongcalls -Wno-frame-address -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fexceptions -fno-rtti -MMD -c +compiler.S.flags.esp32=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c compiler.c.elf.flags.esp32=-T esp32.rom.redefined.ld -T memory.ld -T sections.ld -T esp32.rom.ld -T esp32.rom.api.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T esp32.peripherals.ld -mlongcalls -Wno-frame-address -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u ld_include_hli_vectors_bt -u _Z5setupv -u _Z4loopv -Wl,--wrap=mbedtls_mpi_exp_mod -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u ld_include_highint_hdl -u start_app -u start_app_other_cores -u __ubsan_include -Wl,--wrap=longjmp -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u newlib_include_assert_impl -u __cxa_guard_dummy compiler.ar.flags.esp32=cr build.extra_flags.esp32=-DARDUINO_USB_CDC_ON_BOOT=0 @@ -40,9 +40,9 @@ build.extra_flags.esp32=-DARDUINO_USB_CDC_ON_BOOT=0 # compiler.cpreprocessor.flags.esp32s2=-DHAVE_CONFIG_H -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DUNITY_INCLUDE_CONFIG_H -DWITH_POSIX -D_GNU_SOURCE -DIDF_VER="v4.4-dev-3235-g3e370c4296" -DESP_PLATFORM "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/newlib/platform_include" "-I{compiler.sdk.path}/include/freertos/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions/freertos" "-I{compiler.sdk.path}/include/freertos/port/xtensa/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions" "-I{compiler.sdk.path}/include/esp_hw_support/include" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc/esp32s2" "-I{compiler.sdk.path}/include/esp_hw_support/port/esp32s2" "-I{compiler.sdk.path}/include/esp_hw_support/port/esp32s2/private_include" "-I{compiler.sdk.path}/include/heap/include" "-I{compiler.sdk.path}/include/log/include" "-I{compiler.sdk.path}/include/lwip/include/apps" "-I{compiler.sdk.path}/include/lwip/include/apps/sntp" "-I{compiler.sdk.path}/include/lwip/lwip/src/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include/arch" "-I{compiler.sdk.path}/include/soc/include" "-I{compiler.sdk.path}/include/soc/esp32s2" "-I{compiler.sdk.path}/include/soc/esp32s2/include" "-I{compiler.sdk.path}/include/hal/esp32s2/include" "-I{compiler.sdk.path}/include/hal/include" "-I{compiler.sdk.path}/include/hal/platform_port/include" "-I{compiler.sdk.path}/include/esp_rom/include" "-I{compiler.sdk.path}/include/esp_rom/include/esp32s2" "-I{compiler.sdk.path}/include/esp_rom/esp32s2" "-I{compiler.sdk.path}/include/esp_common/include" "-I{compiler.sdk.path}/include/esp_system/include" "-I{compiler.sdk.path}/include/esp_system/port/soc" "-I{compiler.sdk.path}/include/esp_system/port/public_compat" "-I{compiler.sdk.path}/include/xtensa/include" "-I{compiler.sdk.path}/include/xtensa/esp32s2/include" "-I{compiler.sdk.path}/include/driver/include" "-I{compiler.sdk.path}/include/driver/esp32s2/include" "-I{compiler.sdk.path}/include/esp_pm/include" "-I{compiler.sdk.path}/include/esp_ringbuf/include" "-I{compiler.sdk.path}/include/efuse/include" "-I{compiler.sdk.path}/include/efuse/esp32s2/include" "-I{compiler.sdk.path}/include/vfs/include" "-I{compiler.sdk.path}/include/esp_wifi/include" "-I{compiler.sdk.path}/include/esp_event/include" "-I{compiler.sdk.path}/include/esp_netif/include" "-I{compiler.sdk.path}/include/esp_eth/include" "-I{compiler.sdk.path}/include/tcpip_adapter/include" "-I{compiler.sdk.path}/include/esp_phy/include" "-I{compiler.sdk.path}/include/esp_phy/esp32s2/include" "-I{compiler.sdk.path}/include/esp_ipc/include" "-I{compiler.sdk.path}/include/app_trace/include" "-I{compiler.sdk.path}/include/esp_timer/include" "-I{compiler.sdk.path}/include/mbedtls/port/include" "-I{compiler.sdk.path}/include/mbedtls/mbedtls/include" "-I{compiler.sdk.path}/include/mbedtls/esp_crt_bundle/include" "-I{compiler.sdk.path}/include/app_update/include" "-I{compiler.sdk.path}/include/spi_flash/include" "-I{compiler.sdk.path}/include/bootloader_support/include" "-I{compiler.sdk.path}/include/nvs_flash/include" "-I{compiler.sdk.path}/include/pthread/include" "-I{compiler.sdk.path}/include/esp_gdbstub/include" "-I{compiler.sdk.path}/include/esp_gdbstub/xtensa" "-I{compiler.sdk.path}/include/esp_gdbstub/esp32s2" "-I{compiler.sdk.path}/include/espcoredump/include" "-I{compiler.sdk.path}/include/espcoredump/include/port/xtensa" "-I{compiler.sdk.path}/include/wpa_supplicant/include" "-I{compiler.sdk.path}/include/wpa_supplicant/port/include" "-I{compiler.sdk.path}/include/wpa_supplicant/esp_supplicant/include" "-I{compiler.sdk.path}/include/ieee802154/include" "-I{compiler.sdk.path}/include/asio/asio/asio/include" "-I{compiler.sdk.path}/include/asio/port/include" "-I{compiler.sdk.path}/include/cbor/port/include" "-I{compiler.sdk.path}/include/unity/include" "-I{compiler.sdk.path}/include/unity/unity/src" "-I{compiler.sdk.path}/include/cmock/CMock/src" "-I{compiler.sdk.path}/include/coap/port/include" "-I{compiler.sdk.path}/include/coap/libcoap/include" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/nghttp/port/include" "-I{compiler.sdk.path}/include/nghttp/nghttp2/lib/includes" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp-tls/esp-tls-crypto" "-I{compiler.sdk.path}/include/esp_adc_cal/include" "-I{compiler.sdk.path}/include/esp_hid/include" "-I{compiler.sdk.path}/include/tcp_transport/include" "-I{compiler.sdk.path}/include/esp_http_client/include" "-I{compiler.sdk.path}/include/esp_http_server/include" "-I{compiler.sdk.path}/include/esp_https_ota/include" "-I{compiler.sdk.path}/include/esp_https_server/include" "-I{compiler.sdk.path}/include/esp_lcd/include" "-I{compiler.sdk.path}/include/esp_lcd/interface" "-I{compiler.sdk.path}/include/protobuf-c/protobuf-c" "-I{compiler.sdk.path}/include/protocomm/include/common" "-I{compiler.sdk.path}/include/protocomm/include/security" "-I{compiler.sdk.path}/include/protocomm/include/transports" "-I{compiler.sdk.path}/include/mdns/include" "-I{compiler.sdk.path}/include/esp_local_ctrl/include" "-I{compiler.sdk.path}/include/sdmmc/include" "-I{compiler.sdk.path}/include/esp_serial_slave_link/include" "-I{compiler.sdk.path}/include/esp_websocket_client/include" "-I{compiler.sdk.path}/include/expat/expat/expat/lib" "-I{compiler.sdk.path}/include/expat/port/include" "-I{compiler.sdk.path}/include/wear_levelling/include" "-I{compiler.sdk.path}/include/fatfs/diskio" "-I{compiler.sdk.path}/include/fatfs/vfs" "-I{compiler.sdk.path}/include/fatfs/src" "-I{compiler.sdk.path}/include/freemodbus/common/include" "-I{compiler.sdk.path}/include/idf_test/include" "-I{compiler.sdk.path}/include/idf_test/include/esp32s2" "-I{compiler.sdk.path}/include/jsmn/include" "-I{compiler.sdk.path}/include/json/cJSON" "-I{compiler.sdk.path}/include/libsodium/libsodium/src/libsodium/include" "-I{compiler.sdk.path}/include/libsodium/port_include" "-I{compiler.sdk.path}/include/mqtt/esp-mqtt/include" "-I{compiler.sdk.path}/include/openssl/include" "-I{compiler.sdk.path}/include/perfmon/include" "-I{compiler.sdk.path}/include/spiffs/include" "-I{compiler.sdk.path}/include/usb/include" "-I{compiler.sdk.path}/include/touch_element/include" "-I{compiler.sdk.path}/include/ulp/include" "-I{compiler.sdk.path}/include/wifi_provisioning/include" "-I{compiler.sdk.path}/include/freertos/include/freertos" "-I{compiler.sdk.path}/include/arduino_tinyusb/tinyusb/src" "-I{compiler.sdk.path}/include/arduino_tinyusb/include" "-I{compiler.sdk.path}/include/esp_littlefs/src" "-I{compiler.sdk.path}/include/esp_littlefs/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/dotprod/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/support/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/hann/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman_harris/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/blackman_nuttall/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/nuttall/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/windows/flat_top/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/iir/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/fir/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/add/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/sub/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/mul/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/addc/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/mulc/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/math/sqrt/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/matrix/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/fft/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/dct/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/conv/include" "-I{compiler.sdk.path}/include/esp-dsp/modules/common/include" "-I{compiler.sdk.path}/include/esp-face/include" "-I{compiler.sdk.path}/include/esp-face/include/tool" "-I{compiler.sdk.path}/include/esp-face/include/typedef" "-I{compiler.sdk.path}/include/esp-face/include/image" "-I{compiler.sdk.path}/include/esp-face/include/math" "-I{compiler.sdk.path}/include/esp-face/include/nn" "-I{compiler.sdk.path}/include/esp-face/include/layer" "-I{compiler.sdk.path}/include/esp-face/include/detect" "-I{compiler.sdk.path}/include/esp-face/include/model_zoo" "-I{compiler.sdk.path}/include/esp32-camera/driver/include" "-I{compiler.sdk.path}/include/esp32-camera/conversions/include" "-I{compiler.sdk.path}/include/fb_gfx/include" compiler.c.elf.libs.esp32s2=-lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lasio -lcbor -lunity -lcmock -lcoap -lconsole -lnghttp -lesp-tls -lesp_adc_cal -lesp_hid -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lesp_https_server -lesp_lcd -lprotobuf-c -lprotocomm -lmdns -lesp_local_ctrl -lsdmmc -lesp_serial_slave_link -lesp_websocket_client -lexpat -lwear_levelling -lfatfs -lfreemodbus -ljsmn -ljson -llibsodium -lmqtt -lopenssl -lperfmon -lspiffs -lusb -ltouch_element -lulp -lwifi_provisioning -lesp-dsp -lesp32-camera -lesp_littlefs -lfb_gfx -lasio -lcbor -lcmock -lunity -lcoap -lesp_lcd -lesp_local_ctrl -lesp_https_server -lesp_websocket_client -lexpat -lfreemodbus -ljsmn -llibsodium -lmqtt -lperfmon -lusb -ltouch_element -lesp_adc_cal -lesp_hid -lfatfs -lwear_levelling -lopenssl -lspiffs -lwifi_provisioning -lprotocomm -lprotobuf-c -lmdns -lconsole -ljson -larduino_tinyusb -lcat_face_detect -lhuman_face_detect -ldl -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lphy -lesp_phy -lphy -lesp_phy -lphy -lxt_hal -lm -lnewlib -lstdc++ -lpthread -lgcc -lcxx -lapp_trace -lgcov -lapp_trace -lgcov -lc -compiler.c.flags.esp32s2=-mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c -compiler.cpp.flags.esp32s2=-mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fexceptions -fno-rtti -MMD -c -compiler.S.flags.esp32s2=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -O2 -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c +compiler.c.flags.esp32s2=-mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c +compiler.cpp.flags.esp32s2=-mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fexceptions -fno-rtti -MMD -c +compiler.S.flags.esp32s2=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c compiler.c.elf.flags.esp32s2=-T memory.ld -T sections.ld -T esp32s2.rom.ld -T esp32s2.rom.api.ld -T esp32s2.rom.libgcc.ld -T esp32s2.rom.newlib-funcs.ld -T esp32s2.rom.newlib-data.ld -T esp32s2.rom.spiflash.ld -T esp32s2.peripherals.ld -mlongcalls -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u _Z5setupv -u _Z4loopv -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u ld_include_highint_hdl -u start_app -u __ubsan_include -Wl,--wrap=longjmp -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u newlib_include_assert_impl -u __cxa_guard_dummy compiler.ar.flags.esp32s2=cr build.extra_flags.esp32s2=-DARDUINO_USB_CDC_ON_BOOT={build.cdc_on_boot} -DARDUINO_USB_MSC_ON_BOOT={build.msc_on_boot} -DARDUINO_USB_DFU_ON_BOOT={build.dfu_on_boot} @@ -55,9 +55,9 @@ build.extra_flags.esp32s2=-DARDUINO_USB_CDC_ON_BOOT={build.cdc_on_boot} -DARDUIN # compiler.cpreprocessor.flags.esp32c3=-DHAVE_CONFIG_H -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DUNITY_INCLUDE_CONFIG_H -DWITH_POSIX -D_GNU_SOURCE -DIDF_VER="v4.4-dev-3235-g3e370c4296" -DESP_PLATFORM "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/newlib/platform_include" "-I{compiler.sdk.path}/include/freertos/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions/freertos" "-I{compiler.sdk.path}/include/freertos/port/riscv/include" "-I{compiler.sdk.path}/include/freertos/include/esp_additions" "-I{compiler.sdk.path}/include/esp_hw_support/include" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc" "-I{compiler.sdk.path}/include/esp_hw_support/include/soc/esp32c3" "-I{compiler.sdk.path}/include/esp_hw_support/port/esp32c3" "-I{compiler.sdk.path}/include/esp_hw_support/port/esp32c3/private_include" "-I{compiler.sdk.path}/include/heap/include" "-I{compiler.sdk.path}/include/log/include" "-I{compiler.sdk.path}/include/lwip/include/apps" "-I{compiler.sdk.path}/include/lwip/include/apps/sntp" "-I{compiler.sdk.path}/include/lwip/lwip/src/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include" "-I{compiler.sdk.path}/include/lwip/port/esp32/include/arch" "-I{compiler.sdk.path}/include/soc/include" "-I{compiler.sdk.path}/include/soc/esp32c3" "-I{compiler.sdk.path}/include/soc/esp32c3/include" "-I{compiler.sdk.path}/include/hal/esp32c3/include" "-I{compiler.sdk.path}/include/hal/include" "-I{compiler.sdk.path}/include/hal/platform_port/include" "-I{compiler.sdk.path}/include/esp_rom/include" "-I{compiler.sdk.path}/include/esp_rom/include/esp32c3" "-I{compiler.sdk.path}/include/esp_rom/esp32c3" "-I{compiler.sdk.path}/include/esp_common/include" "-I{compiler.sdk.path}/include/esp_system/include" "-I{compiler.sdk.path}/include/esp_system/port/soc" "-I{compiler.sdk.path}/include/esp_system/port/include/riscv" "-I{compiler.sdk.path}/include/esp_system/port/public_compat" "-I{compiler.sdk.path}/include/riscv/include" "-I{compiler.sdk.path}/include/driver/include" "-I{compiler.sdk.path}/include/driver/esp32c3/include" "-I{compiler.sdk.path}/include/esp_pm/include" "-I{compiler.sdk.path}/include/esp_ringbuf/include" "-I{compiler.sdk.path}/include/efuse/include" "-I{compiler.sdk.path}/include/efuse/esp32c3/include" "-I{compiler.sdk.path}/include/vfs/include" "-I{compiler.sdk.path}/include/esp_wifi/include" "-I{compiler.sdk.path}/include/esp_event/include" "-I{compiler.sdk.path}/include/esp_netif/include" "-I{compiler.sdk.path}/include/esp_eth/include" "-I{compiler.sdk.path}/include/tcpip_adapter/include" "-I{compiler.sdk.path}/include/esp_phy/include" "-I{compiler.sdk.path}/include/esp_phy/esp32c3/include" "-I{compiler.sdk.path}/include/esp_ipc/include" "-I{compiler.sdk.path}/include/app_trace/include" "-I{compiler.sdk.path}/include/esp_timer/include" "-I{compiler.sdk.path}/include/mbedtls/port/include" "-I{compiler.sdk.path}/include/mbedtls/mbedtls/include" "-I{compiler.sdk.path}/include/mbedtls/esp_crt_bundle/include" "-I{compiler.sdk.path}/include/app_update/include" "-I{compiler.sdk.path}/include/spi_flash/include" "-I{compiler.sdk.path}/include/bootloader_support/include" "-I{compiler.sdk.path}/include/nvs_flash/include" "-I{compiler.sdk.path}/include/pthread/include" "-I{compiler.sdk.path}/include/esp_gdbstub/include" "-I{compiler.sdk.path}/include/esp_gdbstub/riscv" "-I{compiler.sdk.path}/include/esp_gdbstub/esp32c3" "-I{compiler.sdk.path}/include/espcoredump/include" "-I{compiler.sdk.path}/include/espcoredump/include/port/riscv" "-I{compiler.sdk.path}/include/wpa_supplicant/include" "-I{compiler.sdk.path}/include/wpa_supplicant/port/include" "-I{compiler.sdk.path}/include/wpa_supplicant/esp_supplicant/include" "-I{compiler.sdk.path}/include/ieee802154/include" "-I{compiler.sdk.path}/include/asio/asio/asio/include" "-I{compiler.sdk.path}/include/asio/port/include" "-I{compiler.sdk.path}/include/bt/common/osi/include" "-I{compiler.sdk.path}/include/bt/include/esp32c3/include" "-I{compiler.sdk.path}/include/bt/common/api/include/api" "-I{compiler.sdk.path}/include/bt/common/btc/profile/esp/blufi/include" "-I{compiler.sdk.path}/include/bt/common/btc/profile/esp/include" "-I{compiler.sdk.path}/include/bt/host/bluedroid/api/include/api" "-I{compiler.sdk.path}/include/cbor/port/include" "-I{compiler.sdk.path}/include/unity/include" "-I{compiler.sdk.path}/include/unity/unity/src" "-I{compiler.sdk.path}/include/cmock/CMock/src" "-I{compiler.sdk.path}/include/coap/port/include" "-I{compiler.sdk.path}/include/coap/libcoap/include" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/nghttp/port/include" "-I{compiler.sdk.path}/include/nghttp/nghttp2/lib/includes" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp-tls/esp-tls-crypto" "-I{compiler.sdk.path}/include/esp_adc_cal/include" "-I{compiler.sdk.path}/include/esp_hid/include" "-I{compiler.sdk.path}/include/tcp_transport/include" "-I{compiler.sdk.path}/include/esp_http_client/include" "-I{compiler.sdk.path}/include/esp_http_server/include" "-I{compiler.sdk.path}/include/esp_https_ota/include" "-I{compiler.sdk.path}/include/esp_https_server/include" "-I{compiler.sdk.path}/include/esp_lcd/include" "-I{compiler.sdk.path}/include/esp_lcd/interface" "-I{compiler.sdk.path}/include/protobuf-c/protobuf-c" "-I{compiler.sdk.path}/include/protocomm/include/common" "-I{compiler.sdk.path}/include/protocomm/include/security" "-I{compiler.sdk.path}/include/protocomm/include/transports" "-I{compiler.sdk.path}/include/mdns/include" "-I{compiler.sdk.path}/include/esp_local_ctrl/include" "-I{compiler.sdk.path}/include/sdmmc/include" "-I{compiler.sdk.path}/include/esp_serial_slave_link/include" "-I{compiler.sdk.path}/include/esp_websocket_client/include" "-I{compiler.sdk.path}/include/expat/expat/expat/lib" "-I{compiler.sdk.path}/include/expat/port/include" "-I{compiler.sdk.path}/include/wear_levelling/include" "-I{compiler.sdk.path}/include/fatfs/diskio" "-I{compiler.sdk.path}/include/fatfs/vfs" "-I{compiler.sdk.path}/include/fatfs/src" "-I{compiler.sdk.path}/include/freemodbus/common/include" "-I{compiler.sdk.path}/include/idf_test/include" "-I{compiler.sdk.path}/include/idf_test/include/esp32c3" "-I{compiler.sdk.path}/include/jsmn/include" "-I{compiler.sdk.path}/include/json/cJSON" "-I{compiler.sdk.path}/include/libsodium/libsodium/src/libsodium/include" "-I{compiler.sdk.path}/include/libsodium/port_include" "-I{compiler.sdk.path}/include/mqtt/esp-mqtt/include" "-I{compiler.sdk.path}/include/openssl/include" "-I{compiler.sdk.path}/include/spiffs/include" "-I{compiler.sdk.path}/include/wifi_provisioning/include" "-I{compiler.sdk.path}/include/esp_littlefs/src" "-I{compiler.sdk.path}/include/esp_littlefs/include" "-I{compiler.sdk.path}/include/fb_gfx/include" compiler.c.elf.libs.esp32c3=-lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lasio -lbt -lcbor -lunity -lcmock -lcoap -lconsole -lnghttp -lesp-tls -lesp_adc_cal -lesp_hid -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lesp_https_server -lesp_lcd -lprotobuf-c -lprotocomm -lmdns -lesp_local_ctrl -lsdmmc -lesp_serial_slave_link -lesp_websocket_client -lexpat -lwear_levelling -lfatfs -lfreemodbus -ljsmn -ljson -llibsodium -lmqtt -lopenssl -lspiffs -lwifi_provisioning -lesp_littlefs -lfb_gfx -lasio -lcbor -lcmock -lunity -lcoap -lesp_lcd -lesp_local_ctrl -lesp_https_server -lesp_websocket_client -lexpat -lfreemodbus -ljsmn -llibsodium -lmqtt -lesp_adc_cal -lesp_hid -lfatfs -lwear_levelling -lopenssl -lspiffs -lwifi_provisioning -lprotocomm -lbt -lbtdm_app -lprotobuf-c -lmdns -lconsole -ljson -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lriscv -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lphy -lbtbb -lesp_phy -lphy -lbtbb -lesp_phy -lphy -lbtbb -lm -lnewlib -lstdc++ -lpthread -lgcc -lcxx -lapp_trace -lgcov -lapp_trace -lgcov -lc -compiler.c.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c -compiler.cpp.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fno-exceptions -fno-rtti -MMD -c -compiler.S.flags.esp32c3=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c +compiler.c.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Os -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu99 -Wno-old-style-declaration -MMD -c +compiler.cpp.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Os -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -std=gnu++11 -fno-exceptions -fno-rtti -MMD -c +compiler.S.flags.esp32c3=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Os -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c compiler.c.elf.flags.esp32c3=-T memory.ld -T sections.ld -T esp32c3.rom.ld -T esp32c3.rom.api.ld -T esp32c3.rom.libgcc.ld -T esp32c3.rom.newlib.ld -T esp32c3.rom.version.ld -T esp32c3.peripherals.ld -nostartfiles -march=rv32imc --specs=nosys.specs -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u _Z5setupv -u _Z4loopv -Wl,--wrap=mbedtls_mpi_exp_mod -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u start_app -u __ubsan_include -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u newlib_include_assert_impl -Wl,--wrap=_Unwind_SetEnableExceptionFdeSorting -Wl,--wrap=__register_frame_info_bases -Wl,--wrap=__register_frame_info -Wl,--wrap=__register_frame -Wl,--wrap=__register_frame_info_table_bases -Wl,--wrap=__register_frame_info_table -Wl,--wrap=__register_frame_table -Wl,--wrap=__deregister_frame_info_bases -Wl,--wrap=__deregister_frame_info -Wl,--wrap=_Unwind_Find_FDE -Wl,--wrap=_Unwind_GetGR -Wl,--wrap=_Unwind_GetCFA -Wl,--wrap=_Unwind_GetIP -Wl,--wrap=_Unwind_GetIPInfo -Wl,--wrap=_Unwind_GetRegionStart -Wl,--wrap=_Unwind_GetDataRelBase -Wl,--wrap=_Unwind_GetTextRelBase -Wl,--wrap=_Unwind_SetIP -Wl,--wrap=_Unwind_SetGR -Wl,--wrap=_Unwind_GetLanguageSpecificData -Wl,--wrap=_Unwind_FindEnclosingFunction -Wl,--wrap=_Unwind_Resume -Wl,--wrap=_Unwind_RaiseException -Wl,--wrap=_Unwind_DeleteException -Wl,--wrap=_Unwind_ForcedUnwind -Wl,--wrap=_Unwind_Resume_or_Rethrow -Wl,--wrap=_Unwind_Backtrace -Wl,--wrap=__cxa_call_unexpected -Wl,--wrap=__gxx_personality_v0 -u __cxa_guard_dummy -u __cxx_fatal_exception compiler.ar.flags.esp32c3=cr build.extra_flags.esp32c3=-DARDUINO_HW_CDC_ON_BOOT={build.cdc_on_boot} diff --git a/tools/sdk/esp32/include/asio/port/include/esp_asio_config.h b/tools/sdk/esp32/include/asio/port/include/esp_asio_config.h index cba316527e6..3f3a9b03ed4 100644 --- a/tools/sdk/esp32/include/asio/port/include/esp_asio_config.h +++ b/tools/sdk/esp32/include/asio/port/include/esp_asio_config.h @@ -18,6 +18,11 @@ # define ASIO_NO_TYPEID # endif // CONFIG_COMPILER_RTTI +// +// Supress OpenSSL deprecation warning, when building ASIO +// +#define ESP_OPENSSL_SUPPRESS_LEGACY_WARNING + // // LWIP compatibility inet and address macros/functions // diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/address.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/address.h new file mode 100644 index 00000000000..a51236d5a60 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/address.h @@ -0,0 +1,177 @@ +/* + * address.h -- representation of network addresses + * + * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file address.h + * @brief Representation of network addresses + */ + +#ifndef COAP_ADDRESS_H_ +#define COAP_ADDRESS_H_ + +#include +#include +#include +#include +#include "libcoap.h" + +#if defined(WITH_LWIP) + +#include + +typedef struct coap_address_t { + uint16_t port; + ip_addr_t addr; +} coap_address_t; + +#define _coap_address_equals_impl(A, B) \ + ((A)->port == (B)->port \ + && (!!ip_addr_cmp(&(A)->addr,&(B)->addr))) + +#define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) + +#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr) + +#elif defined(WITH_CONTIKI) + +#include "uip.h" + +typedef struct coap_address_t { + uip_ipaddr_t addr; + uint16_t port; +} coap_address_t; + +#define _coap_address_equals_impl(A,B) \ + ((A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) + +/** @todo implementation of _coap_address_isany_impl() for Contiki */ +#define _coap_address_isany_impl(A) 0 + +#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) + +#else /* WITH_LWIP || WITH_CONTIKI */ + + /** multi-purpose address abstraction */ +typedef struct coap_address_t { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +} coap_address_t; + +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +int coap_address_equals(const coap_address_t *a, const coap_address_t *b); + +COAP_STATIC_INLINE int +_coap_address_isany_impl(const coap_address_t *a) { + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return a->addr.sin.sin_addr.s_addr == INADDR_ANY; + case AF_INET6: + return memcmp(&in6addr_any, + &a->addr.sin6.sin6_addr, + sizeof(in6addr_any)) == 0; + default: + ; + } + + return 0; +} +#endif /* WITH_LWIP || WITH_CONTIKI */ + +/** + * Resets the given coap_address_t object @p addr to its default values. In + * particular, the member size must be initialized to the available size for + * storing addresses. + * + * @param addr The coap_address_t object to initialize. + */ +COAP_STATIC_INLINE void +coap_address_init(coap_address_t *addr) { + assert(addr); + memset(addr, 0, sizeof(coap_address_t)); +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + /* lwip and Contiki have constant address sizes and doesn't need the .size part */ + addr->size = sizeof(addr->addr); +#endif +} + +/* Convenience function to copy IPv6 addresses without garbage. */ + +COAP_STATIC_INLINE void +coap_address_copy( coap_address_t *dst, const coap_address_t *src ) { +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) + memcpy( dst, src, sizeof( coap_address_t ) ); +#else + memset( dst, 0, sizeof( coap_address_t ) ); + dst->size = src->size; + if ( src->addr.sa.sa_family == AF_INET6 ) { + dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family; + dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr; + dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port; + dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id; + } else if ( src->addr.sa.sa_family == AF_INET ) { + dst->addr.sin = src->addr.sin; + } else { + memcpy( &dst->addr, &src->addr, src->size ); + } +#endif +} + +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_equals(const coap_address_t *a, const coap_address_t *b) { + assert(a); assert(b); + return _coap_address_equals_impl(a, b); +} +#endif + +/** + * Checks if given address object @p a denotes the wildcard address. This + * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p + * a must not be @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_isany(const coap_address_t *a) { + assert(a); + return _coap_address_isany_impl(a); +} + +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +int coap_is_mcast(const coap_address_t *a); +#else /* !WITH_LWIP && !WITH_CONTIKI */ +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +coap_is_mcast(const coap_address_t *a) { + return a && _coap_is_mcast_impl(a); +} +#endif /* !WITH_LWIP && !WITH_CONTIKI */ + +#endif /* COAP_ADDRESS_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/async.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/async.h new file mode 100644 index 00000000000..e399929677d --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/async.h @@ -0,0 +1,148 @@ +/* + * async.h -- state management for asynchronous messages + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file async.h + * @brief State management for asynchronous messages + */ + +#ifndef COAP_ASYNC_H_ +#define COAP_ASYNC_H_ + +#include "net.h" + +#ifndef WITHOUT_ASYNC + +/** + * @defgroup coap_async Asynchronous Messaging + * @{ + * Structure for managing asynchronous state of CoAP resources. A + * coap_resource_t object holds a list of coap_async_state_t objects that can be + * used to generate a separate response in case a result of an operation cannot + * be delivered in time, or the resource has been explicitly subscribed to with + * the option @c observe. + */ +typedef struct coap_async_state_t { + unsigned char flags; /**< holds the flags to control behaviour */ + + /** + * Holds the internal time when the object was registered with a + * resource. This field will be updated whenever + * coap_register_async() is called for a specific resource. + */ + coap_tick_t created; + + /** + * This field can be used to register opaque application data with the + * asynchronous state object. + */ + void *appdata; + coap_session_t *session; /**< transaction session */ + coap_tid_t id; /**< transaction id */ + struct coap_async_state_t *next; /**< internally used for linking */ + size_t tokenlen; /**< length of the token */ + uint8_t token[8]; /**< the token to use in a response */ +} coap_async_state_t; + +/* Definitions for Async Status Flags These flags can be used to control the + * behaviour of asynchronous response generation. + */ +#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */ +#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */ +#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */ + +/** release application data on destruction */ +#define COAP_ASYNC_RELEASE_DATA 0x08 + +/** + * Allocates a new coap_async_state_t object and fills its fields according to + * the given @p request. The @p flags are used to control generation of empty + * ACK responses to stop retransmissions and to release registered @p data when + * the resource is deleted by coap_free_async(). This function returns a pointer + * to the registered coap_async_t object or @c NULL on error. Note that this + * function will return @c NULL in case that an object with the same identifier + * is already registered. + * + * @param context The context to use. + * @param session The session that is used for asynchronous transmissions. + * @param request The request that is handled asynchronously. + * @param flags Flags to control state management. + * @param data Opaque application data to register. Note that the + * storage occupied by @p data is released on destruction + * only if flag COAP_ASYNC_RELEASE_DATA is set. + * + * @return A pointer to the registered coap_async_state_t object or @c + * NULL in case of an error. + */ +coap_async_state_t * +coap_register_async(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request, + unsigned char flags, + void *data); + +/** + * Removes the state object identified by @p id from @p context. The removed + * object is returned in @p s, if found. Otherwise, @p s is undefined. This + * function returns @c 1 if the object was removed, @c 0 otherwise. Note that + * the storage allocated for the stored object is not released by this + * functions. You will have to call coap_free_async() to do so. + * + * @param context The context where the async object is registered. + * @param session The session that is used for asynchronous transmissions. + * @param id The identifier of the asynchronous transaction. + * @param s Will be set to the object identified by @p id after removal. + * + * @return @c 1 if object was removed and @p s updated, or @c 0 if no + * object was found with the given id. @p s is valid only if the + * return value is @c 1. + */ +int coap_remove_async(coap_context_t *context, + coap_session_t *session, + coap_tid_t id, + coap_async_state_t **s); + +/** + * Releases the memory that was allocated by coap_async_state_init() for the + * object @p s. The registered application data will be released automatically + * if COAP_ASYNC_RELEASE_DATA is set. + * + * @param state The object to delete. + */ +void +coap_free_async(coap_async_state_t *state); + +/** + * Retrieves the object identified by @p id from the list of asynchronous + * transactions that are registered with @p context. This function returns a + * pointer to that object or @c NULL if not found. + * + * @param context The context where the asynchronous objects are registered + * with. + * @param session The session that is used for asynchronous transmissions. + * @param id The id of the object to retrieve. + * + * @return A pointer to the object identified by @p id or @c NULL if + * not found. + */ +coap_async_state_t *coap_find_async(coap_context_t *context, coap_session_t *session, coap_tid_t id); + +/** + * Updates the time stamp of @p s. + * + * @param s The state object to update. + */ +COAP_STATIC_INLINE void +coap_touch_async(coap_async_state_t *s) { coap_ticks(&s->created); } + +/** @} */ + +#endif /* WITHOUT_ASYNC */ + +#endif /* COAP_ASYNC_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/bits.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/bits.h new file mode 100644 index 00000000000..3b1871487c9 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/bits.h @@ -0,0 +1,78 @@ +/* + * bits.h -- bit vector manipulation + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file bits.h + * @brief Bit vector manipulation + */ + +#ifndef COAP_BITS_H_ +#define COAP_BITS_H_ + +#include + +/** + * Sets the bit @p bit in bit-vector @p vec. This function returns @c 1 if bit + * was set or @c -1 on error (i.e. when the given bit does not fit in the + * vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to set in @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_setb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07)); + return 1; +} + +/** + * Clears the bit @p bit from bit-vector @p vec. This function returns @c 1 if + * bit was cleared or @c -1 on error (i.e. when the given bit does not fit in + * the vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to clear from @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_clrb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07))); + return 1; +} + +/** + * Gets the status of bit @p bit from bit-vector @p vec. This function returns + * @c 1 if the bit is set, @c 0 otherwise (even in case of an error). + * + * @param vec The bit-vector to read from. + * @param size The size of @p vec in bytes. + * @param bit The bit to get from @p vec. + * + * @return @c 1 if the bit is set, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +bits_getb(const uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0; +} + +#endif /* COAP_BITS_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/block.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/block.h new file mode 100644 index 00000000000..848897639c9 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/block.h @@ -0,0 +1,173 @@ +/* + * block.h -- block transfer + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_BLOCK_H_ +#define COAP_BLOCK_H_ + +#include "encode.h" +#include "option.h" +#include "pdu.h" + +struct coap_resource_t; +struct coap_session_t; + +/** + * @defgroup block Block Transfer + * API functions for handling PDUs using CoAP BLOCK options + * @{ + */ + +#ifndef COAP_MAX_BLOCK_SZX +/** + * The largest value for the SZX component in a Block option. + */ +#define COAP_MAX_BLOCK_SZX 6 +#endif /* COAP_MAX_BLOCK_SZX */ + +/** + * Structure of Block options. + */ +typedef struct { + unsigned int num; /**< block number */ + unsigned int m:1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx:3; /**< block size */ +} coap_block_t; + +/** + * Returns the value of the least significant byte of a Block option @p opt. + * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST + * returns @c NULL. + */ +#define COAP_OPT_BLOCK_LAST(opt) \ + (coap_opt_length(opt) ? (coap_opt_value(opt) + (coap_opt_length(opt)-1)) : 0) + +/** Returns the value of the More-bit of a Block option @p opt. */ +#define COAP_OPT_BLOCK_MORE(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0) + +/** Returns the value of the SZX-field of a Block option @p opt. */ +#define COAP_OPT_BLOCK_SZX(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0) + +/** + * Returns the value of field @c num in the given block option @p block_opt. + */ +unsigned int coap_opt_block_num(const coap_opt_t *block_opt); + +/** + * Checks if more than @p num blocks are required to deliver @p data_len + * bytes of data for a block size of 1 << (@p szx + 4). + */ +COAP_STATIC_INLINE int +coap_more_blocks(size_t data_len, unsigned int num, uint16_t szx) { + return ((num+1) << (szx + 4)) < data_len; +} + +#if 0 +/** Sets the More-bit in @p block_opt */ +COAP_STATIC_INLINE void +coap_opt_block_set_m(coap_opt_t *block_opt, int m) { + if (m) + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) |= 0x08; + else + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) &= ~0x08; +} +#endif + +/** + * Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1 + * or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block is + * initialized with values from this option and the function returns the value + * @c 1. Otherwise, @c 0 is returned. + * + * @param pdu The pdu to search for option @p type. + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * COAP_OPTION_BLOCK2). + * @param block The block structure to initilize. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_get_block(coap_pdu_t *pdu, uint16_t type, coap_block_t *block); + +/** + * Writes a block option of type @p type to message @p pdu. If the requested + * block size is too large to fit in @p pdu, it is reduced accordingly. An + * exception is made for the final block when less space is required. The actual + * length of the resource is specified in @p data_length. + * + * This function may change *block to reflect the values written to @p pdu. As + * the function takes into consideration the remaining space @p pdu, no more + * options should be added after coap_write_block_opt() has returned. + * + * @param block The block structure to use. On return, this object is + * updated according to the values that have been written to + * @p pdu. + * @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2. + * @param pdu The message where the block option should be written. + * @param data_length The length of the actual data that will be added the @p + * pdu by calling coap_add_block(). + * + * @return @c 1 on success, or a negative value on error. + */ +int coap_write_block_opt(coap_block_t *block, + uint16_t type, + coap_pdu_t *pdu, + size_t data_length); + +/** + * Adds the @p block_num block of size 1 << (@p block_szx + 4) from source @p + * data to @p pdu. + * + * @param pdu The message to add the block. + * @param len The length of @p data. + * @param data The source data to fill the block with. + * @param block_num The actual block number. + * @param block_szx Encoded size of block @p block_number. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_add_block(coap_pdu_t *pdu, + unsigned int len, + const uint8_t *data, + unsigned int block_num, + unsigned char block_szx); + +/** + * Adds the appropriate part of @p data to the @p response pdu. If blocks are + * required, then the appropriate block will be added to the PDU and sent. + * Adds a ETAG option that is the hash of the entire data if the data is to be + * split into blocks + * Used by a GET request handler. + * + * @param resource The resource the data is associated with. + * @param session The coap session. + * @param request The requesting pdu. + * @param response The response pdu. + * @param token The token taken from the (original) requesting pdu. + * @param media_type The format of the data. + * @param maxage The maxmimum life of the data. If @c -1, then there + * is no maxage. + * @param length The total length of the data. + * @param data The entire data block to transmit. + * + */ +void +coap_add_data_blocked_response(struct coap_resource_t *resource, + struct coap_session_t *session, + coap_pdu_t *request, + coap_pdu_t *response, + const coap_binary_t *token, + uint16_t media_type, + int maxage, + size_t length, + const uint8_t* data); + +/**@}*/ + +#endif /* COAP_BLOCK_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_debug.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_debug.h new file mode 100644 index 00000000000..e4631b71f2b --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_debug.h @@ -0,0 +1,209 @@ +/* + * coap_debug.h -- debug utilities + * + * Copyright (C) 2010-2011,2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DEBUG_H_ +#define COAP_DEBUG_H_ + +/** + * @defgroup logging Logging Support + * API functions for logging support + * @{ + */ + +#ifndef COAP_DEBUG_FD +/** + * Used for output for @c LOG_DEBUG to @c LOG_ERR. + */ +#define COAP_DEBUG_FD stdout +#endif + +#ifndef COAP_ERR_FD +/** + * Used for output for @c LOG_CRIT to @c LOG_EMERG. + */ +#define COAP_ERR_FD stderr +#endif + +#ifdef HAVE_SYSLOG_H +#include +/** + * Logging type. One of LOG_* from @b syslog. + */ +typedef short coap_log_t; +#else +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { + LOG_EMERG=0, /**< Emergency */ + LOG_ALERT, /**< Alert */ + LOG_CRIT, /**< Critical */ + LOG_ERR, /**< Error */ + LOG_WARNING, /**< Warning */ + LOG_NOTICE, /**< Notice */ + LOG_INFO, /**< Information */ + LOG_DEBUG /**< Debug */ +} coap_log_t; +#endif + +/** + * Get the current logging level. + * + * @return One of the LOG_* values. + */ +coap_log_t coap_get_log_level(void); + +/** + * Sets the log level to the specified value. + * + * @param level One of the LOG_* values. + */ +void coap_set_log_level(coap_log_t level); + +/** + * Logging call-back handler definition. + * + * @param level One of the LOG_* values. + * @param message Zero-terminated string message to log. + */ +typedef void (*coap_log_handler_t) (coap_log_t level, const char *message); + +/** + * Add a custom log callback handler. + * + * @param handler The logging handler to use or @p NULL to use default handler. + */ +void coap_set_log_handler(coap_log_handler_t handler); + +/** + * Get the library package name. + * + * @return Zero-terminated string with the name of this library. + */ +const char *coap_package_name(void); + +/** + * Get the library package version. + * + * @return Zero-terminated string with the library version. + */ +const char *coap_package_version(void); + +/** + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * Internal function. + * + * @param level One of the LOG_* values. + & @param format The format string to use. + */ +#if (defined(__GNUC__)) +void coap_log_impl(coap_log_t level, + const char *format, ...) __attribute__ ((format(printf, 2, 3))); +#else +void coap_log_impl(coap_log_t level, const char *format, ...); +#endif + +#ifndef coap_log +/** + * Logging function. + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * @param level One of the LOG_* values. + */ +#define coap_log(level, ...) do { \ + if ((int)((level))<=(int)coap_get_log_level()) \ + coap_log_impl((level), __VA_ARGS__); \ +} while(0) +#endif + +#include "pdu.h" + +/** + * Defines the output mode for the coap_show_pdu() function. + * + * @param use_fprintf @p 1 if the output is to use fprintf() (the default) + * @p 0 if the output is to use coap_log(). + */ +void coap_set_show_pdu_output(int use_fprintf); + +/** + * Display the contents of the specified @p pdu. + * Note: The output method of coap_show_pdu() is dependent on the setting of + * coap_set_show_pdu_output(). + * + * @param level The required minimum logging level. + * @param pdu The PDU to decode. + */ +void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu); + +/** + * Display the current (D)TLS library linked with and built for version. + * + * @param level The required minimum logging level. + */ +void coap_show_tls_version(coap_log_t level); + +/** + * Build a string containing the current (D)TLS library linked with and + * built for version. + * + * @param buffer The buffer to put the string into. + * @param bufsize The size of the buffer to put the string into. + * + * @return A pointer to the provided buffer. + */ +char *coap_string_tls_version(char *buffer, size_t bufsize); + +struct coap_address_t; + +/** + * Print the address into the defined buffer. + * + * Internal Function. + * + * @param address The address to print. + * @param buffer The buffer to print into. + * @param size The size of the buffer to print into. + * + * @return The amount written into the buffer. + */ +size_t coap_print_addr(const struct coap_address_t *address, + unsigned char *buffer, size_t size); + +/** @} */ + +/** + * Set the packet loss level for testing. This can be in one of two forms. + * + * Percentage : 0% to 100%. Use the specified probability. + * 0% is send all packets, 100% is drop all packets. + * + * List: A comma separated list of numbers or number ranges that are the + * packets to drop. + * + * @param loss_level The defined loss level (percentage or list). + * + * @return @c 1 If loss level set, @c 0 if there is an error. + */ +int coap_debug_set_packet_loss(const char *loss_level); + +/** + * Check to see whether a packet should be sent or not. + * + * Internal function + * + * @return @c 1 if packet is to be sent, @c 0 if packet is to be dropped. + */ +int coap_debug_send_packet(void); + + +#endif /* COAP_DEBUG_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_dtls.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_dtls.h new file mode 100644 index 00000000000..f0554f3dfea --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_dtls.h @@ -0,0 +1,611 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +#define COAP_TLS_LIBRARY_NOTLS 0 /**< No DTLS library */ +#define COAP_TLS_LIBRARY_TINYDTLS 1 /**< Using TinyDTLS library */ +#define COAP_TLS_LIBRARY_OPENSSL 2 /**< Using OpenSSL library */ +#define COAP_TLS_LIBRARY_GNUTLS 3 /**< Using GnuTLS library */ + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + int type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t reserved[6]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 6 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_event.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_event.h new file mode 100644 index 00000000000..81a3b0511fd --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_event.h @@ -0,0 +1,102 @@ +/* + * coap_event.h -- libcoap Event API + * + * Copyright (C) 2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_EVENT_H_ +#define COAP_EVENT_H_ + +#include "libcoap.h" + +struct coap_context_t; +struct coap_session_t; + +/** + * @defgroup events Event API + * API functions for event delivery from lower-layer library functions. + * @{ + */ + +/** + * Scalar type to represent different events, e.g. DTLS events or + * retransmission timeouts. + */ + typedef unsigned int coap_event_t; + +/** + * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS + */ +#define COAP_EVENT_DTLS_CLOSED 0x0000 +#define COAP_EVENT_DTLS_CONNECTED 0x01DE +#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF +#define COAP_EVENT_DTLS_ERROR 0x0200 + +/** + * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS + */ +#define COAP_EVENT_TCP_CONNECTED 0x1001 +#define COAP_EVENT_TCP_CLOSED 0x1002 +#define COAP_EVENT_TCP_FAILED 0x1003 + +/** + * CSM exchange events for reliable protocols only + */ +#define COAP_EVENT_SESSION_CONNECTED 0x2001 +#define COAP_EVENT_SESSION_CLOSED 0x2002 +#define COAP_EVENT_SESSION_FAILED 0x2003 + +/** + * Type for event handler functions that can be registered with a CoAP + * context using the unction coap_set_event_handler(). When called by + * the library, the first argument will be the coap_context_t object + * where the handler function has been registered. The second argument + * is the event type that may be complemented by event-specific data + * passed as the third argument. + */ +typedef int (*coap_event_handler_t)(struct coap_context_t *, + coap_event_t event, + struct coap_session_t *session); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. @c NULL if to be + * de-registered. + */ +void coap_register_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @deprecated Use coap_register_event_handler() instead. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. + */ +COAP_DEPRECATED +void coap_set_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Clears the event handler registered with @p context. + * + * @deprecated Use coap_register_event_handler() instead with NULL for hnd. + * + * @param context The CoAP context whose event handler is to be removed. + */ +COAP_DEPRECATED +void coap_clear_event_handler(struct coap_context_t *context); + +/** @} */ + +#endif /* COAP_EVENT_H */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_hashkey.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_hashkey.h new file mode 100644 index 00000000000..252f34822d4 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_hashkey.h @@ -0,0 +1,59 @@ +/* + * coap_hashkey.h -- definition of hash key type and helper functions + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_hashkey.h + * @brief definition of hash key type and helper functions + */ + +#ifndef COAP_HASHKEY_H_ +#define COAP_HASHKEY_H_ + +#include "libcoap.h" +#include "uthash.h" +#include "str.h" + +typedef unsigned char coap_key_t[4]; + +#ifndef coap_hash +/** + * Calculates a fast hash over the given string @p s of length @p len and stores + * the result into @p h. Depending on the exact implementation, this function + * cannot be used as one-way function to check message integrity or simlar. + * + * @param s The string used for hash calculation. + * @param len The length of @p s. + * @param h The result buffer to store the calculated hash key. + */ +void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); + +#define coap_hash(String,Length,Result) \ + coap_hash_impl((String),(Length),(Result)) + +/* This is used to control the pre-set hash-keys for resources. */ +#define COAP_DEFAULT_HASH +#else +#undef COAP_DEFAULT_HASH +#endif /* coap_hash */ + +/** + * Calls coap_hash() with given @c coap_string_t object as parameter. + * + * @param Str Must contain a pointer to a coap string object. + * @param H A coap_key_t object to store the result. + * + * @hideinitializer + */ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((Str)->s, (Str)->length, (H)); \ + } + +#endif /* COAP_HASHKEY_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_io.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_io.h new file mode 100644 index 00000000000..1854501be89 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_io.h @@ -0,0 +1,210 @@ +/* + * coap_io.h -- Default network I/O functions for libcoap + * + * Copyright (C) 2012-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_IO_H_ +#define COAP_IO_H_ + +#include +#include + +#include "address.h" + +#ifndef COAP_RXBUFFER_SIZE +#define COAP_RXBUFFER_SIZE 1472 +#endif /* COAP_RXBUFFER_SIZE */ + +#ifdef _WIN32 +typedef SOCKET coap_fd_t; +#define coap_closesocket closesocket +#define COAP_SOCKET_ERROR SOCKET_ERROR +#define COAP_INVALID_SOCKET INVALID_SOCKET +#else +typedef int coap_fd_t; +#define coap_closesocket close +#define COAP_SOCKET_ERROR (-1) +#define COAP_INVALID_SOCKET (-1) +#endif + +struct coap_packet_t; +struct coap_session_t; +struct coap_pdu_t; + +typedef uint16_t coap_socket_flags_t; + +typedef struct coap_socket_t { +#if defined(WITH_LWIP) + struct udp_pcb *pcb; +#elif defined(WITH_CONTIKI) + void *conn; +#else + coap_fd_t fd; +#endif /* WITH_LWIP */ + coap_socket_flags_t flags; +} coap_socket_t; + +/** + * coap_socket_flags_t values + */ +#define COAP_SOCKET_EMPTY 0x0000 /**< the socket is not used */ +#define COAP_SOCKET_NOT_EMPTY 0x0001 /**< the socket is not empty */ +#define COAP_SOCKET_BOUND 0x0002 /**< the socket is bound */ +#define COAP_SOCKET_CONNECTED 0x0004 /**< the socket is connected */ +#define COAP_SOCKET_WANT_READ 0x0010 /**< non blocking socket is waiting for reading */ +#define COAP_SOCKET_WANT_WRITE 0x0020 /**< non blocking socket is waiting for writing */ +#define COAP_SOCKET_WANT_ACCEPT 0x0040 /**< non blocking server socket is waiting for accept */ +#define COAP_SOCKET_WANT_CONNECT 0x0080 /**< non blocking client socket is waiting for connect */ +#define COAP_SOCKET_CAN_READ 0x0100 /**< non blocking socket can now read without blocking */ +#define COAP_SOCKET_CAN_WRITE 0x0200 /**< non blocking socket can now write without blocking */ +#define COAP_SOCKET_CAN_ACCEPT 0x0400 /**< non blocking server socket can now accept without blocking */ +#define COAP_SOCKET_CAN_CONNECT 0x0800 /**< non blocking client socket can now connect without blocking */ +#define COAP_SOCKET_MULTICAST 0x1000 /**< socket is used for multicast communication */ + +struct coap_endpoint_t *coap_malloc_endpoint( void ); +void coap_mfree_endpoint( struct coap_endpoint_t *ep ); + +int +coap_socket_connect_udp(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_udp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr ); + +int +coap_socket_connect_tcp1(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_connect_tcp2(coap_socket_t *sock, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_tcp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr); + +int +coap_socket_accept_tcp(coap_socket_t *server, + coap_socket_t *new_client, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +void coap_socket_close(coap_socket_t *sock); + +ssize_t +coap_socket_send( coap_socket_t *sock, struct coap_session_t *session, + const uint8_t *data, size_t data_len ); + +ssize_t +coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len); + +ssize_t +coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len); + +#ifdef WITH_LWIP +ssize_t +coap_socket_send_pdu( coap_socket_t *sock, struct coap_session_t *session, + struct coap_pdu_t *pdu ); +#endif + +const char *coap_socket_strerror( void ); + +/** + * Function interface for data transmission. This function returns the number of + * bytes that have been transmitted, or a value less than zero on error. + * + * @param sock Socket to send data with + * @param session Addressing information for unconnected sockets, or NULL + * @param data The data to send. + * @param datalen The actual length of @p data. + * + * @return The number of bytes written on success, or a value + * less than zero on error. + */ +ssize_t coap_network_send( coap_socket_t *sock, const struct coap_session_t *session, const uint8_t *data, size_t datalen ); + +/** + * Function interface for reading data. This function returns the number of + * bytes that have been read, or a value less than zero on error. In case of an + * error, @p *packet is set to NULL. + * + * @param sock Socket to read data from + * @param packet Received packet metadata and payload. src and dst should be preset. + * + * @return The number of bytes received on success, or a value less than + * zero on error. + */ +ssize_t coap_network_read( coap_socket_t *sock, struct coap_packet_t *packet ); + +#ifndef coap_mcast_interface +# define coap_mcast_interface(Local) 0 +#endif + +/** + * Given a packet, set msg and msg_len to an address and length of the packet's + * data in memory. + * */ +void coap_packet_get_memmapped(struct coap_packet_t *packet, + unsigned char **address, + size_t *length); + +#ifdef WITH_LWIP +/** + * Get the pbuf of a packet. The caller takes over responsibility for freeing + * the pbuf. + */ +struct pbuf *coap_packet_extract_pbuf(struct coap_packet_t *packet); +#endif + +#if defined(WITH_LWIP) +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in lwippools.h. + * Simple carry-over of the incoming pbuf that is later turned into a node. + * + * Source address data is currently side-banded via ip_current_dest_addr & co + * as the packets have limited lifetime anyway. + */ +struct coap_packet_t { + struct pbuf *pbuf; + const struct coap_endpoint_t *local_interface; + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ +// uint16_t srcport; +}; +#else +struct coap_packet_t { + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ + size_t length; /**< length of payload */ + unsigned char payload[COAP_RXBUFFER_SIZE]; /**< payload */ +}; +#endif +typedef struct coap_packet_t coap_packet_t; + +typedef enum { + COAP_NACK_TOO_MANY_RETRIES, + COAP_NACK_NOT_DELIVERABLE, + COAP_NACK_RST, + COAP_NACK_TLS_FAILED +} coap_nack_reason_t; + +#endif /* COAP_IO_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_mutex.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_mutex.h new file mode 100644 index 00000000000..99d7d335e47 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_mutex.h @@ -0,0 +1,50 @@ +/* + * coap_mutex.h -- mutex utilities + * + * Copyright (C) 2019 Jon Shallow + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_mutex.h + * @brief COAP mutex mechanism wrapper + */ + +#ifndef COAP_MUTEX_H_ +#define COAP_MUTEX_H_ + +#if defined(RIOT_VERSION) + +#include + +typedef mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER MUTEX_INIT +#define coap_mutex_lock(a) mutex_lock(a) +#define coap_mutex_trylock(a) mutex_trylock(a) +#define coap_mutex_unlock(a) mutex_unlock(a) + +#elif defined(WITH_CONTIKI) + +/* CONTIKI does not support mutex */ + +typedef int coap_mutex_t; +#define COAP_MUTEX_INITIALIZER 0 +#define coap_mutex_lock(a) *(a) = 1 +#define coap_mutex_trylock(a) *(a) = 1 +#define coap_mutex_unlock(a) *(a) = 0 + +#else /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#include + +typedef pthread_mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define coap_mutex_lock(a) pthread_mutex_lock(a) +#define coap_mutex_trylock(a) pthread_mutex_trylock(a) +#define coap_mutex_unlock(a) pthread_mutex_unlock(a) + +#endif /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#endif /* COAP_MUTEX_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_session.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_session.h new file mode 100644 index 00000000000..1dc0103e3e7 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_session.h @@ -0,0 +1,492 @@ +/* coap_session.h -- Session management for libcoap +* +* Copyright (C) 2017 Jean-Claue Michelou +* +* This file is part of the CoAP library libcoap. Please see +* README for terms of use. +*/ + +#ifndef COAP_SESSION_H_ +#define COAP_SESSION_H_ + + +#include "coap_io.h" +#include "coap_time.h" +#include "pdu.h" + +struct coap_endpoint_t; +struct coap_context_t; +struct coap_queue_t; + +/** +* Abstraction of a fixed point number that can be used where necessary instead +* of a float. 1,000 fractional bits equals one integer +*/ +typedef struct coap_fixed_point_t { + uint16_t integer_part; /**< Integer part of fixed point variable */ + uint16_t fractional_part; /**< Fractional part of fixed point variable + 1/1000 (3 points) precision */ +} coap_fixed_point_t; + +#define COAP_DEFAULT_SESSION_TIMEOUT 300 +#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND) +#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100 + +#define COAP_PROTO_NOT_RELIABLE(p) ((p)==COAP_PROTO_UDP || (p)==COAP_PROTO_DTLS) +#define COAP_PROTO_RELIABLE(p) ((p)==COAP_PROTO_TCP || (p)==COAP_PROTO_TLS) + +typedef uint8_t coap_session_type_t; +/** + * coap_session_type_t values + */ +#define COAP_SESSION_TYPE_CLIENT 1 /**< client-side */ +#define COAP_SESSION_TYPE_SERVER 2 /**< server-side */ +#define COAP_SESSION_TYPE_HELLO 3 /**< server-side ephemeral session for responding to a client hello */ + +typedef uint8_t coap_session_state_t; +/** + * coap_session_state_t values + */ +#define COAP_SESSION_STATE_NONE 0 +#define COAP_SESSION_STATE_CONNECTING 1 +#define COAP_SESSION_STATE_HANDSHAKE 2 +#define COAP_SESSION_STATE_CSM 3 +#define COAP_SESSION_STATE_ESTABLISHED 4 + +typedef struct coap_session_t { + struct coap_session_t *next; + coap_proto_t proto; /**< protocol used */ + coap_session_type_t type; /**< client or server side socket */ + coap_session_state_t state; /**< current state of relationaship with peer */ + unsigned ref; /**< reference count from queues */ + unsigned tls_overhead; /**< overhead of TLS layer */ + unsigned mtu; /**< path or CSM mtu */ + coap_address_t local_if; /**< optional local interface address */ + coap_address_t remote_addr; /**< remote address and port */ + coap_address_t local_addr; /**< local address and port */ + int ifindex; /**< interface index */ + coap_socket_t sock; /**< socket object for the session, if any */ + struct coap_endpoint_t *endpoint; /**< session's endpoint */ + struct coap_context_t *context; /**< session's context */ + void *tls; /**< security parameters */ + uint16_t tx_mid; /**< the last message id that was used in this session */ + uint8_t con_active; /**< Active CON request sent */ + struct coap_queue_t *delayqueue; /**< list of delayed messages waiting to be sent */ + size_t partial_write; /**< if > 0 indicates number of bytes already written from the pdu at the head of sendqueue */ + uint8_t read_header[8]; /**< storage space for header of incoming message header */ + size_t partial_read; /**< if > 0 indicates number of bytes already read for an incoming message */ + coap_pdu_t *partial_pdu; /**< incomplete incoming pdu */ + coap_tick_t last_rx_tx; + coap_tick_t last_tx_rst; + coap_tick_t last_ping; + coap_tick_t last_pong; + coap_tick_t csm_tx; + uint8_t *psk_identity; + size_t psk_identity_len; + uint8_t *psk_key; + size_t psk_key_len; + void *app; /**< application-specific data */ + unsigned int max_retransmit; /**< maximum re-transmit count (default 4) */ + coap_fixed_point_t ack_timeout; /**< timeout waiting for ack (default 2 secs) */ + coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default 1.5) */ + unsigned int dtls_timeout_count; /**< dtls setup retry counter */ + int dtls_event; /**< Tracking any (D)TLS events on this sesison */ +} coap_session_t; + +/** +* Increment reference counter on a session. +* +* @param session The CoAP session. +* @return same as session +*/ +coap_session_t *coap_session_reference(coap_session_t *session); + +/** +* Decrement reference counter on a session. +* Note that the session may be deleted as a result and should not be used +* after this call. +* +* @param session The CoAP session. +*/ +void coap_session_release(coap_session_t *session); + +/** +* Stores @p data with the given session. This function overwrites any value +* that has previously been stored with @p session. +*/ +void coap_session_set_app_data(coap_session_t *session, void *data); + +/** +* Returns any application-specific data that has been stored with @p +* session using the function coap_session_set_app_data(). This function will +* return @c NULL if no data has been stored. +*/ +void *coap_session_get_app_data(const coap_session_t *session); + +/** +* Notify session that it has failed. +* +* @param session The CoAP session. +* @param reason The reason why the session was disconnected. +*/ +void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason); + +/** +* Notify session transport has just connected and CSM exchange can now start. +* +* @param session The CoAP session. +*/ +void coap_session_send_csm(coap_session_t *session); + +/** +* Notify session that it has just connected or reconnected. +* +* @param session The CoAP session. +*/ +void coap_session_connected(coap_session_t *session); + +/** +* Set the session MTU. This is the maximum message size that can be sent, +* excluding IP and UDP overhead. +* +* @param session The CoAP session. +* @param mtu maximum message size +*/ +void coap_session_set_mtu(coap_session_t *session, unsigned mtu); + +/** + * Get maximum acceptable PDU size + * + * @param session The CoAP session. + * @return maximum PDU size, not including header (but including token). + */ +size_t coap_session_max_pdu_size(const coap_session_t *session); + +/** +* Creates a new client session to the designated server. +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto +); + +/** +* Creates a new client session to the designated server with PSK credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* @param identity PSK client identity +* @param key PSK shared key +* @param key_len PSK shared key length +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session_psk( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + const char *identity, + const uint8_t *key, + unsigned key_len +); + +struct coap_dtls_pki_t; + +/** +* Creates a new client session to the designated server with PKI credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to +* let the operating system choose a suitable local interface. +* If an address is specified, the port number should be zero, +* which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default +* port for the protocol will be used. +* @param proto CoAP Protocol. +* @param setup_data PKI parameters. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release() +* to free. +*/ +coap_session_t *coap_new_client_session_pki( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + struct coap_dtls_pki_t *setup_data +); + +/** +* Creates a new server session for the specified endpoint. +* @param ctx The CoAP context. +* @param ep An endpoint where an incoming connection request is pending. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_server_session( + struct coap_context_t *ctx, + struct coap_endpoint_t *ep +); + +/** +* Function interface for datagram data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Function interface for stream data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. The number of bytes written may be less than datalen because of +* congestion control. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_write(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Send a pdu according to the session's protocol. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send pdu on. +* @param pdu The pdu to send. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu); + + +/** + * @ingroup logging + * Get session description. + * + * @param session The CoAP session. + * @return description string. + */ +const char *coap_session_str(const coap_session_t *session); + +ssize_t +coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, + struct coap_queue_t *node); +/** +* Abstraction of virtual endpoint that can be attached to coap_context_t. The +* tuple (handle, addr) must uniquely identify this endpoint. +*/ +typedef struct coap_endpoint_t { + struct coap_endpoint_t *next; + struct coap_context_t *context; /**< endpoint's context */ + coap_proto_t proto; /**< protocol used on this interface */ + uint16_t default_mtu; /**< default mtu for this interface */ + coap_socket_t sock; /**< socket object for the interface, if any */ + coap_address_t bind_addr; /**< local interface address */ + coap_session_t *sessions; /**< list of active sessions */ +} coap_endpoint_t; + +/** +* Create a new endpoint for communicating with peers. +* +* @param context The coap context that will own the new endpoint +* @param listen_addr Address the endpoint will listen for incoming requests on or originate outgoing requests from. Use NULL to specify that no incoming request will be accepted and use a random endpoint. +* @param proto Protocol used on this endpoint +*/ + +coap_endpoint_t *coap_new_endpoint(struct coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto); + +/** +* Set the endpoint's default MTU. This is the maximum message size that can be +* sent, excluding IP and UDP overhead. +* +* @param endpoint The CoAP endpoint. +* @param mtu maximum message size +*/ +void coap_endpoint_set_default_mtu(coap_endpoint_t *endpoint, unsigned mtu); + +void coap_free_endpoint(coap_endpoint_t *ep); + + +/** + * @ingroup logging +* Get endpoint description. +* +* @param endpoint The CoAP endpoint. +* @return description string. +*/ +const char *coap_endpoint_str(const coap_endpoint_t *endpoint); + +/** +* Lookup the server session for the packet received on an endpoint, or create +* a new one. +* +* @param endpoint Active endpoint the packet was received on. +* @param packet Received packet. +* @param now The current time in ticks. +* @return The CoAP session or @c NULL if error. +*/ +coap_session_t *coap_endpoint_get_session(coap_endpoint_t *endpoint, + const struct coap_packet_t *packet, coap_tick_t now); + +/** + * Create a new DTLS session for the @p session. + * Note: the @p session is released if no DTLS server session can be created. + * + * @ingroup dtls_internal + * + * @param session Session to add DTLS session to + * @param now The current time in ticks. + * + * @return CoAP session or @c NULL if error. + */ +coap_session_t *coap_session_new_dtls_session(coap_session_t *session, + coap_tick_t now); + +coap_session_t *coap_session_get_by_peer(struct coap_context_t *ctx, + const struct coap_address_t *remote_addr, int ifindex); + +void coap_session_free(coap_session_t *session); +void coap_session_mfree(coap_session_t *session); + + /** + * @defgroup cc Rate Control + * The transmission parameters for CoAP rate control ("Congestion + * Control" in stream-oriented protocols) are defined in + * https://tools.ietf.org/html/rfc7252#section-4.8 + * @{ + */ + + /** + * Number of seconds when to expect an ACK or a response to an + * outstanding CON message. + * RFC 7252, Section 4.8 Default value of ACK_TIMEOUT is 2 + */ +#define COAP_DEFAULT_ACK_TIMEOUT ((coap_fixed_point_t){2,0}) + + /** + * A factor that is used to randomize the wait time before a message + * is retransmitted to prevent synchronization effects. + * RFC 7252, Section 4.8 Default value of ACK_RANDOM_FACTOR is 1.5 + */ +#define COAP_DEFAULT_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1,500}) + + /** + * Number of message retransmissions before message sending is stopped + * RFC 7252, Section 4.8 Default value of MAX_RETRANSMIT is 4 + */ +#define COAP_DEFAULT_MAX_RETRANSMIT 4 + + /** + * The number of simultaneous outstanding interactions that a client + * maintains to a given server. + * RFC 7252, Section 4.8 Default value of NSTART is 1 + */ +#define COAP_DEFAULT_NSTART 1 + + /** @} */ + +/** +* Set the CoAP maximum retransmit count before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* @param value The value to set to. The default is 4 and should not normally +* get changed. +*/ +void coap_session_set_max_retransmit(coap_session_t *session, + unsigned int value); + +/** +* Set the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 2 and should not normally +* get changed. +*/ +void coap_session_set_ack_timeout(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Set the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 1.5 and should not normally +* get changed. +*/ +void coap_session_set_ack_random_factor(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Get the CoAP maximum retransmit before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* +* @return Current maximum retransmit value +*/ +unsigned int coap_session_get_max_transmit(coap_session_t *session); + +/** +* Get the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* +* @return Current ack response timeout value +*/ +coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t *session); + +/** +* Get the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* +* @return Current ack randomize value +*/ +coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t *session); + +/** + * Send a ping message for the session. + * @param session The CoAP session. + * + * @return COAP_INVALID_TID if there is an error + */ +coap_tid_t coap_session_send_ping(coap_session_t *session); + +#endif /* COAP_SESSION_H */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_time.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_time.h new file mode 100644 index 00000000000..e4a8e7c7c73 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/coap_time.h @@ -0,0 +1,162 @@ +/* + * coap_time.h -- Clock Handling + * + * Copyright (C) 2010-2019 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_time.h + * @brief Clock Handling + */ + +#ifndef COAP_TIME_H_ +#define COAP_TIME_H_ + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. + * @{ + */ + +#if defined(WITH_LWIP) + +#include +#include + +/* lwIP provides ms in sys_now */ +#define COAP_TICKS_PER_SECOND 1000 + +typedef uint32_t coap_tick_t; +typedef uint32_t coap_time_t; +typedef int32_t coap_tick_diff_t; + +COAP_STATIC_INLINE void coap_ticks_impl(coap_tick_t *t) { + *t = sys_now(); +} + +COAP_STATIC_INLINE void coap_clock_init_impl(void) { +} + +#define coap_clock_init coap_clock_init_impl +#define coap_ticks coap_ticks_impl + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#elif defined(WITH_CONTIKI) + +#include "clock.h" + +typedef clock_time_t coap_tick_t; +typedef clock_time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int coap_tick_diff_t; + +#define COAP_TICKS_PER_SECOND CLOCK_SECOND + +COAP_STATIC_INLINE void coap_clock_init(void) { + clock_init(); +} + +COAP_STATIC_INLINE void coap_ticks(coap_tick_t *t) { + *t = clock_time(); +} + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#else +#include + +/** + * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND + * resolution. + */ +typedef uint64_t coap_tick_t; + +/** + * CoAP time in seconds since epoch. + */ +typedef time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int64_t coap_tick_diff_t; + +/** Use ms resolution on POSIX systems */ +#define COAP_TICKS_PER_SECOND ((coap_tick_t)(1000U)) + +/** + * Initializes the internal clock. + */ +void coap_clock_init(void); + +/** + * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. + */ +void coap_ticks(coap_tick_t *t); + +/** + * Helper function that converts coap ticks to wallclock time. On POSIX, this + * function returns the number of seconds since the epoch. On other systems, it + * may be the calculated number of seconds since last reboot or so. + * + * @param t Internal system ticks. + * + * @return The number of seconds that has passed since a specific reference + * point (seconds since epoch on POSIX). + */ +coap_time_t coap_ticks_to_rt(coap_tick_t t); + +/** +* Helper function that converts coap ticks to POSIX wallclock time in us. +* +* @param t Internal system ticks. +* +* @return The number of seconds that has passed since a specific reference +* point (seconds since epoch on POSIX). +*/ +uint64_t coap_ticks_to_rt_us(coap_tick_t t); + +/** +* Helper function that converts POSIX wallclock time in us to coap ticks. +* +* @param t POSIX time is us +* +* @return coap ticks +*/ +coap_tick_t coap_ticks_from_rt_us(uint64_t t); +#endif + +/** + * Returns @c 1 if and only if @p a is less than @p b where less is defined on a + * signed data type. + */ +COAP_STATIC_INLINE int coap_time_lt(coap_tick_t a, coap_tick_t b) { + return ((coap_tick_diff_t)(a - b)) < 0; +} + +/** + * Returns @c 1 if and only if @p a is less than or equal @p b where less is + * defined on a signed data type. + */ +COAP_STATIC_INLINE int coap_time_le(coap_tick_t a, coap_tick_t b) { + return a == b || coap_time_lt(a,b); +} + +/** @} */ + +#endif /* COAP_TIME_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/encode.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/encode.h new file mode 100644 index 00000000000..b6d1524443c --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/encode.h @@ -0,0 +1,96 @@ +/* + * encode.h -- encoding and decoding of CoAP data types + * + * Copyright (C) 2010-2012 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_ENCODE_H_ +#define COAP_ENCODE_H_ + +#if (BSD >= 199103) || defined(WITH_CONTIKI) || defined(_WIN32) +# include +#else +# include +#endif + +#include + +#define Nn 8 /* duplicate definition of N if built on sky motes */ +#define ENCODE_HEADER_SIZE 4 +#define HIBIT (1 << (Nn - 1)) +#define EMASK ((1 << ENCODE_HEADER_SIZE) - 1) +#define MMASK ((1 << Nn) - 1 - EMASK) +#define MAX_VALUE ( (1 << Nn) - (1 << ENCODE_HEADER_SIZE) ) * (1 << ((1 << ENCODE_HEADER_SIZE) - 1)) + +#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK)) + +#ifndef HAVE_FLS +/* include this only if fls() is not available */ +extern int coap_fls(unsigned int i); +#else +#define coap_fls(i) fls(i) +#endif + +#ifndef HAVE_FLSLL + /* include this only if flsll() is not available */ +extern int coap_flsll(long long i); +#else +#define coap_flsll(i) flsll(i) +#endif + +/* ls and s must be integer variables */ +#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls) +#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls)) + +/** + * Decodes multiple-length byte sequences. @p buf points to an input byte + * sequence of length @p length. Returns the decoded value. + * + * @param buf The input byte sequence to decode from + * @param length The length of the input byte sequence + * + * @return The decoded value + */ +unsigned int coap_decode_var_bytes(const uint8_t *buf, unsigned int length); + +/** + * Encodes multiple-length byte sequences. @p buf points to an output buffer of + * sufficient length to store the encoded bytes. @p value is the value to + * encode. + * Returns the number of bytes used to encode @p value or 0 on error. + * + * @param buf The output buffer to decode into + * @param length The output buffer size to encode into (must be sufficient) + * @param value The value to encode into the buffer + * + * @return The number of bytes used to encode @p value or @c 0 on error. + */ +unsigned int coap_encode_var_safe(uint8_t *buf, + size_t length, + unsigned int value); + +/** + * @deprecated Use coap_encode_var_safe() instead. + * Provided for backward compatibility. As @p value has a + * maximum value of 0xffffffff, and buf is usually defined as an array, it + * is unsafe to continue to use this variant if buf[] is less than buf[4]. + * + * For example + * char buf[1],oops; + * .. + * coap_encode_var_bytes(buf, 0xfff); + * would cause oops to get overwritten. This error can only be found by code + * inspection. + * coap_encode_var_safe(buf, sizeof(buf), 0xfff); + * would catch this error at run-time and should be used instead. + */ +COAP_STATIC_INLINE COAP_DEPRECATED int +coap_encode_var_bytes(uint8_t *buf, unsigned int value +) { + return (int)coap_encode_var_safe(buf, sizeof(value), value); +} + +#endif /* COAP_ENCODE_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/libcoap.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/libcoap.h new file mode 100644 index 00000000000..77ba5db23e2 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/libcoap.h @@ -0,0 +1,54 @@ +/* + * libcoap.h -- platform specific header file for CoAP stack + * + * Copyright (C) 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_LIBCOAP_H_ +#define COAP_LIBCOAP_H_ + +/* The non posix embedded platforms like Contiki, TinyOS, RIOT, ... doesn't have + * a POSIX compatible header structure so we have to slightly do some platform + * related things. Currently there is only Contiki available so we check for a + * CONTIKI environment and do *not* include the POSIX related network stuff. If + * there are other platforms in future there need to be analogous environments. + * + * The CONTIKI variable is within the Contiki build environment! */ + +#if defined(_WIN32) +#pragma comment(lib,"Ws2_32.lib") +#include +typedef SSIZE_T ssize_t; +typedef USHORT in_port_t; +#elif !defined (CONTIKI) +#include +#include +#endif /* CONTIKI */ + +#ifndef COAP_STATIC_INLINE +# if defined(__cplusplus) +# define COAP_STATIC_INLINE inline +# else +# if defined(_MSC_VER) +# define COAP_STATIC_INLINE static __inline +# else +# define COAP_STATIC_INLINE static inline +# endif +# endif +#endif +#ifndef COAP_DEPRECATED +# if defined(_MSC_VER) +# define COAP_DEPRECATED __declspec(deprecated) +# else +# define COAP_DEPRECATED __attribute__ ((deprecated)) +# endif +#endif + +void coap_startup(void); + +void coap_cleanup(void); + +#endif /* COAP_LIBCOAP_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/lwippools.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/lwippools.h new file mode 100644 index 00000000000..cb90d8099db --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/lwippools.h @@ -0,0 +1,81 @@ +/* + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/* Memory pool definitions for the libcoap when used with lwIP (which has its + * own mechanism for quickly allocating chunks of data with known sizes). Has + * to be findable by lwIP (ie. an #include must either directly + * include this or include something more generic which includes this), and + * MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */ + +#include "coap_config.h" +#include +#include +#include + +#ifndef MEMP_NUM_COAPCONTEXT +#define MEMP_NUM_COAPCONTEXT 1 +#endif + +#ifndef MEMP_NUM_COAPENDPOINT +#define MEMP_NUM_COAPENDPOINT 1 +#endif + +/* 1 is sufficient as this is very short-lived */ +#ifndef MEMP_NUM_COAPPACKET +#define MEMP_NUM_COAPPACKET 1 +#endif + +#ifndef MEMP_NUM_COAPNODE +#define MEMP_NUM_COAPNODE 4 +#endif + +#ifndef MEMP_NUM_COAPPDU +#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE +#endif + +#ifndef MEMP_NUM_COAPSESSION +#define MEMP_NUM_COAPSESSION 2 +#endif + +#ifndef MEMP_NUM_COAP_SUBSCRIPTION +#define MEMP_NUM_COAP_SUBSCRIPTION 4 +#endif + +#ifndef MEMP_NUM_COAPRESOURCE +#define MEMP_NUM_COAPRESOURCE 10 +#endif + +#ifndef MEMP_NUM_COAPRESOURCEATTR +#define MEMP_NUM_COAPRESOURCEATTR 20 +#endif + +#ifndef MEMP_NUM_COAPOPTLIST +#define MEMP_NUM_COAPOPTLIST 1 +#endif + +#ifndef MEMP_LEN_COAPOPTLIST +#define MEMP_LEN_COAPOPTLIST 12 +#endif + +#ifndef MEMP_NUM_COAPSTRING +#define MEMP_NUM_COAPSTRING 10 +#endif + +#ifndef MEMP_LEN_COAPSTRING +#define MEMP_LEN_COAPSTRING 32 +#endif + +LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") +LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") +LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") +LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") +LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION") +LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") +LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") +LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") +LWIP_MEMPOOL(COAP_OPTLIST, MEMP_NUM_COAPOPTLIST, sizeof(coap_optlist_t)+MEMP_LEN_COAPOPTLIST, "COAP_OPTLIST") +LWIP_MEMPOOL(COAP_STRING, MEMP_NUM_COAPSTRING, sizeof(coap_string_t)+MEMP_LEN_COAPSTRING, "COAP_STRING") + diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/mem.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/mem.h new file mode 100644 index 00000000000..ea3c619fd30 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/mem.h @@ -0,0 +1,116 @@ +/* + * mem.h -- CoAP memory handling + * + * Copyright (C) 2010-2011,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_MEM_H_ +#define COAP_MEM_H_ + +#include + +#ifndef WITH_LWIP +/** + * Initializes libcoap's memory management. + * This function must be called once before coap_malloc() can be used on + * constrained devices. + */ +void coap_memory_init(void); +#endif /* WITH_LWIP */ + +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed to + * facilitate arrays of type objects to be used instead of dynamic memory + * management on constrained devices. + */ +typedef enum { + COAP_STRING, + COAP_ATTRIBUTE_NAME, + COAP_ATTRIBUTE_VALUE, + COAP_PACKET, + COAP_NODE, + COAP_CONTEXT, + COAP_ENDPOINT, + COAP_PDU, + COAP_PDU_BUF, + COAP_RESOURCE, + COAP_RESOURCEATTR, +#ifdef HAVE_LIBTINYDTLS + COAP_DTLS_SESSION, +#endif + COAP_SESSION, + COAP_OPTLIST, +} coap_memory_tag_t; + +#ifndef WITH_LWIP + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the newly + * allocated memory. The @p type is used to select the appropriate storage + * container on constrained devices. The storage allocated by coap_malloc_type() + * must be released with coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). The type tag @p + * type must be the same that was used for allocating the object pointed to by + * @p . + * + * @param type The type of the object to release. + * @param p A pointer to memory that was allocated by coap_malloc_type(). + */ +void coap_free_type(coap_memory_tag_t type, void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void coap_free(void *object) { + coap_free_type(COAP_STRING, object); +} + +#endif /* not WITH_LWIP */ + +#ifdef WITH_LWIP + +#include + +/* no initialization needed with lwip (or, more precisely: lwip must be + * completely initialized anyway by the time coap gets active) */ +COAP_STATIC_INLINE void coap_memory_init(void) {} + +/* It would be nice to check that size equals the size given at the memp + * declaration, but i currently don't see a standard way to check that without + * sourcing the custom memp pools and becoming dependent of its syntax + */ +#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_free_type(type, p) memp_free(MEMP_ ## type, p) + +/* Those are just here to make uri.c happy where string allocation has not been + * made conditional. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + LWIP_ASSERT("coap_malloc must not be used in lwIP", 0); +} + +COAP_STATIC_INLINE void coap_free(void *pointer) { + LWIP_ASSERT("coap_free must not be used in lwIP", 0); +} + +#endif /* WITH_LWIP */ + +#endif /* COAP_MEM_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/net.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/net.h new file mode 100644 index 00000000000..7fccf3326c7 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/net.h @@ -0,0 +1,746 @@ +/* + * net.h -- CoAP network interface + * + * Copyright (C) 2010-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_NET_H_ +#define COAP_NET_H_ + +#include +#include +#include +#ifndef _WIN32 +#include +#endif +#include + +#ifdef WITH_LWIP +#include +#endif + +#include "coap_io.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_time.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "coap_session.h" + +struct coap_queue_t; + +/** + * Queue entry + */ +typedef struct coap_queue_t { + struct coap_queue_t *next; + coap_tick_t t; /**< when to send PDU for the next time */ + unsigned char retransmit_cnt; /**< retransmission counter, will be removed + * when zero */ + unsigned int timeout; /**< the randomized timeout value */ + coap_session_t *session; /**< the CoAP session */ + coap_tid_t id; /**< CoAP transaction id */ + coap_pdu_t *pdu; /**< the CoAP PDU to send */ +} coap_queue_t; + +/** + * Adds @p node to given @p queue, ordered by variable t in @p node. + * + * @param queue Queue to add to. + * @param node Node entry to add to Queue. + * + * @return @c 1 added to queue, @c 0 failure. + */ +int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); + +/** + * Destroys specified @p node. + * + * @param node Node entry to remove. + * + * @return @c 1 node deleted from queue, @c 0 failure. + */ +int coap_delete_node(coap_queue_t *node); + +/** + * Removes all items from given @p queue and frees the allocated storage. + * + * @param queue The queue to delete. + */ +void coap_delete_all(coap_queue_t *queue); + +/** + * Creates a new node suitable for adding to the CoAP sendqueue. + * + * @return New node entry, or @c NULL if failure. + */ +coap_queue_t *coap_new_node(void); + +struct coap_resource_t; +struct coap_context_t; +#ifndef WITHOUT_ASYNC +struct coap_async_state_t; +#endif + +/** + * Response handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_response_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Negative Acknowedge handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param reason The reason for the NACK. + * @param id CoAP transaction ID. + */ +typedef void (*coap_nack_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_nack_reason_t reason, + const coap_tid_t id); + +/** + * Recieved Ping handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_ping_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Recieved Pong handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_pong_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * The CoAP stack's global state is stored in a coap_context_t object. + */ +typedef struct coap_context_t { + coap_opt_filter_t known_options; + struct coap_resource_t *resources; /**< hash table or list of known + resources */ + struct coap_resource_t *unknown_resource; /**< can be used for handling + unknown resources */ + +#ifndef WITHOUT_ASYNC + /** + * list of asynchronous transactions */ + struct coap_async_state_t *async_state; +#endif /* WITHOUT_ASYNC */ + + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue; + coap_endpoint_t *endpoint; /**< the endpoints used for listening */ + coap_session_t *sessions; /**< client sessions */ + +#ifdef WITH_CONTIKI + struct uip_udp_conn *conn; /**< uIP connection object */ + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ + struct etimer notify_timer; /**< used to check resources periodically */ +#endif /* WITH_CONTIKI */ + +#ifdef WITH_LWIP + uint8_t timer_configured; /**< Set to 1 when a retransmission is + * scheduled using lwIP timers for this + * context, otherwise 0. */ +#endif /* WITH_LWIP */ + + coap_response_handler_t response_handler; + coap_nack_handler_t nack_handler; + coap_ping_handler_t ping_handler; + coap_pong_handler_t pong_handler; + + /** + * Callback function that is used to signal events to the + * application. This field is set by coap_set_event_handler(). + */ + coap_event_handler_t handle_event; + + ssize_t (*network_send)(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen); + + ssize_t (*network_read)(coap_socket_t *sock, struct coap_packet_t *packet); + + size_t(*get_client_psk)(const coap_session_t *session, const uint8_t *hint, size_t hint_len, uint8_t *identity, size_t *identity_len, size_t max_identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_psk)(const coap_session_t *session, const uint8_t *identity, size_t identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len); + + void *dtls_context; + uint8_t *psk_hint; + size_t psk_hint_len; + uint8_t *psk_key; + size_t psk_key_len; + + unsigned int session_timeout; /**< Number of seconds of inactivity after which an unused session will be closed. 0 means use default. */ + unsigned int max_idle_sessions; /**< Maximum number of simultaneous unused sessions per endpoint. 0 means no maximum. */ + unsigned int max_handshake_sessions; /**< Maximum number of simultaneous negotating sessions per endpoint. 0 means use default. */ + unsigned int ping_timeout; /**< Minimum inactivity time before sending a ping message. 0 means disabled. */ + unsigned int csm_timeout; /**< Timeout for waiting for a CSM from the remote side. 0 means disabled. */ + + void *app; /**< application-specific data */ +} coap_context_t; + +/** + * Registers a new message handler that is called whenever a response was + * received that matches an ongoing transaction. + * + * @param context The context to register the handler for. + * @param handler The response handler to register. + */ +COAP_STATIC_INLINE void +coap_register_response_handler(coap_context_t *context, + coap_response_handler_t handler) { + context->response_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a confirmable + * message (request or response) is dropped after all retries have been + * exhausted, or a rst message was received, or a network or TLS level + * event was received that indicates delivering the message is not possible. + * + * @param context The context to register the handler for. + * @param handler The nack handler to register. + */ +COAP_STATIC_INLINE void +coap_register_nack_handler(coap_context_t *context, + coap_nack_handler_t handler) { + context->nack_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Ping + * message is received. + * + * @param context The context to register the handler for. + * @param handler The ping handler to register. + */ +COAP_STATIC_INLINE void +coap_register_ping_handler(coap_context_t *context, + coap_ping_handler_t handler) { + context->ping_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Pong + * message is received. + * + * @param context The context to register the handler for. + * @param handler The pong handler to register. + */ +COAP_STATIC_INLINE void +coap_register_pong_handler(coap_context_t *context, + coap_pong_handler_t handler) { + context->pong_handler = handler; +} + +/** + * Registers the option type @p type with the given context object @p ctx. + * + * @param ctx The context to use. + * @param type The option type to register. + */ +COAP_STATIC_INLINE void +coap_register_option(coap_context_t *ctx, uint16_t type) { + coap_option_setb(ctx->known_options, type); +} + +/** + * Set sendqueue_basetime in the given context object @p ctx to @p now. This + * function returns the number of elements in the queue head that have timed + * out. + */ +unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); + +/** + * Returns the next pdu to send without removing from sendqeue. + */ +coap_queue_t *coap_peek_next( coap_context_t *context ); + +/** + * Returns the next pdu to send and removes it from the sendqeue. + */ +coap_queue_t *coap_pop_next( coap_context_t *context ); + +/** + * Creates a new coap_context_t object that will hold the CoAP stack status. + */ +coap_context_t *coap_new_context(const coap_address_t *listen_addr); + +/** + * Set the context's default PSK hint and/or key for a server. + * + * @param context The current coap_context_t object. + * @param hint The default PSK server hint sent to a client. If @p NULL, PSK + * authentication is disabled. Empty string is a valid hint. + * @param key The default PSK key. If @p NULL, PSK authentication will fail. + * @param key_len The default PSK key's length. If @p 0, PSK authentication will + * fail. + * + * @return @c 1 if successful, else @c 0. + */ +int coap_context_set_psk( coap_context_t *context, const char *hint, + const uint8_t *key, size_t key_len ); + +/** + * Set the context's default PKI information for a server. + * + * @param context The current coap_context_t object. + * @param setup_data If @p NULL, PKI authentication will fail. Certificate + * information required. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki(coap_context_t *context, + coap_dtls_pki_t *setup_data); + +/** + * Set the context's default Root CA information for a client or server. + * + * @param context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki_root_cas(coap_context_t *context, + const char *ca_file, + const char *ca_dir); + +/** + * Set the context keepalive timer for sessions. + * A keepalive message will be sent after if a session has been inactive, + * i.e. no packet sent or received, for the given number of seconds. + * For reliable protocols, a PING message will be sent. If a PONG has not + * been received before the next PING is due to be sent, the session will + * considered as disconnected. + * + * @param context The coap_context_t object. + * @param seconds Number of seconds for the inactivity timer, or zero + * to disable CoAP-level keepalive messages. + * + * @return 1 if successful, else 0 + */ +void coap_context_set_keepalive(coap_context_t *context, unsigned int seconds); + +/** + * Returns a new message id and updates @p session->tx_mid accordingly. The + * message id is returned in network byte order to make it easier to read in + * tracing tools. + * + * @param session The current coap_session_t object. + * + * @return Incremented message id in network byte order. + */ +COAP_STATIC_INLINE uint16_t +coap_new_message_id(coap_session_t *session) { + return ++session->tx_mid; +} + +/** + * CoAP stack context must be released with coap_free_context(). This function + * clears all entries from the receive queue and send queue and deletes the + * resources that have been registered with @p context, and frees the attached + * endpoints. + * + * @param context The current coap_context_t object to free off. + */ +void coap_free_context(coap_context_t *context); + +/** + * Stores @p data with the given CoAP context. This function + * overwrites any value that has previously been stored with @p + * context. + * + * @param context The CoAP context. + * @param data The data to store with wih the context. Note that this data + * must be valid during the lifetime of @p context. + */ +void coap_set_app_data(coap_context_t *context, void *data); + +/** + * Returns any application-specific data that has been stored with @p + * context using the function coap_set_app_data(). This function will + * return @c NULL if no data has been stored. + * + * @param context The CoAP context. + * + * @return The data previously stored or @c NULL if not data stored. + */ +void *coap_get_app_data(const coap_context_t *context); + +/** + * Creates a new ACK PDU with specified error @p code. The options specified by + * the filter expression @p opts will be copied from the original request + * contained in @p request. Unless @c SHORT_ERROR_RESPONSE was defined at build + * time, the textual reason phrase for @p code will be added as payload, with + * Content-Type @c 0. + * This function returns a pointer to the new response message, or @c NULL on + * error. The storage allocated for the new message must be relased with + * coap_free(). + * + * @param request Specification of the received (confirmable) request. + * @param code The error code to set. + * @param opts An option filter that specifies which options to copy from + * the original request in @p node. + * + * @return A pointer to the new message or @c NULL on error. + */ +coap_pdu_t *coap_new_error_response(coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Sends an error response with code @p code for request @p request to @p dst. + * @p opts will be passed to coap_new_error_response() to copy marked options + * from the request. This function returns the transaction id if the message was + * sent, or @c COAP_INVALID_TID otherwise. + * + * @param session The CoAP session. + * @param request The original request to respond to. + * @param code The response code. + * @param opts A filter that specifies the options to copy from the + * @p request. + * + * @return The transaction id if the message was sent, or @c + * COAP_INVALID_TID otherwise. + */ +coap_tid_t coap_send_error(coap_session_t *session, + coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Helper funktion to create and send a message with @p type (usually ACK or + * RST). This function returns @c COAP_INVALID_TID when the message was not + * sent, a valid transaction id otherwise. + * + * @param session The CoAP session. + * @param request The request that should be responded to. + * @param type Which type to set. + * @return transaction id on success or @c COAP_INVALID_TID + * otherwise. + */ +coap_tid_t +coap_send_message_type(coap_session_t *session, coap_pdu_t *request, unsigned char type); + +/** + * Sends an ACK message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be acknowledged. + * + * @return The transaction id if ACK was sent or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_ack(coap_session_t *session, coap_pdu_t *request); + +/** + * Sends an RST message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be reset. + * + * @return The transaction id if RST was sent or @c + * COAP_INVALID_TID on error. + */ +COAP_STATIC_INLINE coap_tid_t +coap_send_rst(coap_session_t *session, coap_pdu_t *request) { + return coap_send_message_type(session, request, COAP_MESSAGE_RST); +} + +/** +* Sends a CoAP message to given peer. The memory that is +* allocated by pdu will be released by coap_send(). +* The caller must not use the pdu after calling coap_send(). +* +* @param session The CoAP session. +* @param pdu The CoAP PDU to send. +* +* @return The message id of the sent message or @c +* COAP_INVALID_TID on error. +*/ +coap_tid_t coap_send( coap_session_t *session, coap_pdu_t *pdu ); + +/** + * Handles retransmissions of confirmable messages + * + * @param context The CoAP context. + * @param node The node to retransmit. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); + +/** +* For applications with their own message loop, send all pending retransmits and +* return the list of sockets with events to wait for and the next timeout +* The application should call coap_read, then coap_write again when any condition below is true: +* - data is available on any of the sockets with the COAP_SOCKET_WANT_READ +* - an incoming connection is pending in the listen queue and the COAP_SOCKET_WANT_ACCEPT flag is set +* - at least some data can be written without blocking on any of the sockets with the COAP_SOCKET_WANT_WRITE flag set +* - a connection event occured (success or failure) and the COAP_SOCKET_WANT_CONNECT flag is set +* - the timeout has expired +* Before calling coap_read or coap_write again, the application should position COAP_SOCKET_CAN_READ and COAP_SOCKET_CAN_WRITE flags as applicable. +* +* @param ctx The CoAP context +* @param sockets array of socket descriptors, filled on output +* @param max_sockets size of socket array. +* @param num_sockets pointer to the number of valid entries in the socket arrays on output +* @param now Current time. +* +* @return timeout as maxmimum number of milliseconds that the application should wait for network events or 0 if the application should wait forever. +*/ + +unsigned int +coap_write(coap_context_t *ctx, + coap_socket_t *sockets[], + unsigned int max_sockets, + unsigned int *num_sockets, + coap_tick_t now +); + +/** + * For applications with their own message loop, reads all data from the network. + * + * @param ctx The CoAP context + * @param now Current time + */ +void coap_read(coap_context_t *ctx, coap_tick_t now); + +/** + * The main message processing loop. + * + * @param ctx The CoAP context + * @param timeout_ms Minimum number of milliseconds to wait for new messages before returning. If zero the call will block until at least one packet is sent or received. + * + * @return number of milliseconds spent or @c -1 if there was an error + */ + +int coap_run_once( coap_context_t *ctx, unsigned int timeout_ms ); + +/** + * Parses and interprets a CoAP datagram with context @p ctx. This function + * returns @c 0 if the datagram was handled, or a value less than zero on + * error. + * + * @param ctx The current CoAP context. + * @param session The current CoAP session. + * @param data The received packet'd data. + * @param data_len The received packet'd data length. + * + * @return @c 0 if message was handled successfully, or less than zero on + * error. + */ +int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len); + +/** + * Invokes the event handler of @p context for the given @p event and + * @p data. + * + * @param context The CoAP context whose event handler is to be called. + * @param event The event to deliver. + * @param session The session related to @p event. + * @return The result from the associated event handler or 0 if none was + * registered. + */ +int coap_handle_event(coap_context_t *context, + coap_event_t event, + coap_session_t *session); +/** + * This function removes the element with given @p id from the list given list. + * If @p id was found, @p node is updated to point to the removed element. Note + * that the storage allocated by @p node is @b not released. The caller must do + * this manually using coap_delete_node(). This function returns @c 1 if the + * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, + * the contents of @p node is undefined. + * + * @param queue The queue to search for @p id. + * @param session The session to look for. + * @param id The transaction id to look for. + * @param node If found, @p node is updated to point to the removed node. You + * must release the storage pointed to by @p node manually. + * + * @return @c 1 if @p id was found, @c 0 otherwise. + */ +int coap_remove_from_queue(coap_queue_t **queue, + coap_session_t *session, + coap_tid_t id, + coap_queue_t **node); + +coap_tid_t +coap_wait_ack( coap_context_t *context, coap_session_t *session, + coap_queue_t *node); + +/** + * Retrieves transaction from the queue. + * + * @param queue The transaction queue to be searched. + * @param session The session to find. + * @param id The transaction id to find. + * + * @return A pointer to the transaction object or @c NULL if not found. + */ +coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_session_t *session, coap_tid_t id); + +/** + * Cancels all outstanding messages for session @p session that have the specified + * token. + * + * @param context The context in use. + * @param session Session of the messages to remove. + * @param token Message token. + * @param token_length Actual length of @p token. + */ +void coap_cancel_all_messages(coap_context_t *context, + coap_session_t *session, + const uint8_t *token, + size_t token_length); + +/** +* Cancels all outstanding messages for session @p session. +* +* @param context The context in use. +* @param session Session of the messages to remove. +* @param reason The reasion for the session cancellation +*/ +void +coap_cancel_session_messages(coap_context_t *context, + coap_session_t *session, + coap_nack_reason_t reason); + +/** + * Dispatches the PDUs from the receive queue in given context. + */ +void coap_dispatch(coap_context_t *context, coap_session_t *session, + coap_pdu_t *pdu); + +/** + * Returns 1 if there are no messages to send or to dispatch in the context's + * queues. */ +int coap_can_exit(coap_context_t *context); + +/** + * Returns the current value of an internal tick counter. The counter counts \c + * COAP_TICKS_PER_SECOND ticks every second. + */ +void coap_ticks(coap_tick_t *); + +/** + * Verifies that @p pdu contains no unknown critical options. Options must be + * registered at @p ctx, using the function coap_register_option(). A basic set + * of options is registered automatically by coap_new_context(). This function + * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p + * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT + * options can be signalled this way, remaining options must be examined + * manually. + * + * @code + coap_opt_filter_t f = COAP_OPT_NONE; + coap_opt_iterator_t opt_iter; + + if (coap_option_check_critical(ctx, pdu, f) == 0) { + coap_option_iterator_init(pdu, &opt_iter, f); + + while (coap_option_next(&opt_iter)) { + if (opt_iter.type & 0x01) { + ... handle unknown critical option in opt_iter ... + } + } + } + @endcode + * + * @param ctx The context where all known options are registered. + * @param pdu The PDU to check. + * @param unknown The output filter that will be updated to indicate the + * unknown critical options found in @p pdu. + * + * @return @c 1 if everything was ok, @c 0 otherwise. + */ +int coap_option_check_critical(coap_context_t *ctx, + coap_pdu_t *pdu, + coap_opt_filter_t unknown); + +/** + * Creates a new response for given @p request with the contents of @c + * .well-known/core. The result is NULL on error or a newly allocated PDU that + * must be either sent with coap_sent() or released by coap_delete_pdu(). + * + * @param context The current coap context to use. + * @param session The CoAP session. + * @param request The request for @c .well-known/core . + * + * @return A new 2.05 response for @c .well-known/core or NULL on error. + */ +coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request); + +/** + * Calculates the initial timeout based on the session CoAP transmission + * parameters 'ack_timeout', 'ack_random_factor', and COAP_TICKS_PER_SECOND. + * The calculation requires 'ack_timeout' and 'ack_random_factor' to be in + * Qx.FRAC_BITS fixed point notation, whereas the passed parameter @p r + * is interpreted as the fractional part of a Q0.MAX_BITS random value. + * + * @param session session timeout is associated with + * @param r random value as fractional part of a Q0.MAX_BITS fixed point + * value + * @return COAP_TICKS_PER_SECOND * 'ack_timeout' * + * (1 + ('ack_random_factor' - 1) * r) + */ +unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r); + +/** + * Function interface for joining a multicast group for listening + * + * @param ctx The current context + * @param groupname The name of the group that is to be joined for listening + * + * @return 0 on success, -1 on error + */ +int +coap_join_mcast_group(coap_context_t *ctx, const char *groupname); + +#endif /* COAP_NET_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/option.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/option.h new file mode 100644 index 00000000000..3af9e71e706 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/option.h @@ -0,0 +1,461 @@ +/* + * option.h -- helpers for handling options in CoAP PDUs + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file option.h + * @brief Helpers for handling options in CoAP PDUs + */ + +#ifndef COAP_OPTION_H_ +#define COAP_OPTION_H_ + +#include "bits.h" +#include "pdu.h" + +/** + * Use byte-oriented access methods here because sliding a complex struct + * coap_opt_t over the data buffer may cause bus error on certain platforms. + */ +typedef uint8_t coap_opt_t; +#define PCHAR(p) ((coap_opt_t *)(p)) + +/** + * Representation of CoAP options. + */ +typedef struct { + uint16_t delta; + size_t length; + const uint8_t *value; +} coap_option_t; + +/** + * Parses the option pointed to by @p opt into @p result. This function returns + * the number of bytes that have been parsed, or @c 0 on error. An error is + * signaled when illegal delta or length values are encountered or when option + * parsing would result in reading past the option (i.e. beyond opt + length). + * + * @param opt The beginning of the option to parse. + * @param length The maximum length of @p opt. + * @param result A pointer to the coap_option_t structure that is filled with + * actual values iff coap_opt_parse() > 0. + * @return The number of bytes parsed or @c 0 on error. + */ +size_t coap_opt_parse(const coap_opt_t *opt, + size_t length, + coap_option_t *result); + +/** + * Returns the size of the given option, taking into account a possible option + * jump. + * + * @param opt An option jump or the beginning of the option. + * @return The number of bytes between @p opt and the end of the option + * starting at @p opt. In case of an error, this function returns + * @c 0 as options need at least one byte storage space. + */ +size_t coap_opt_size(const coap_opt_t *opt); + +/** + * @defgroup opt_filter Option Filters + * API functions for access option filters + * @{ + */ + +/** + * The number of option types below 256 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_SHORT 6 + +/** + * The number of option types above 255 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * COAP_OPT_FILTER_LONG * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_LONG 2 + +/* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set + * correctly. */ +#if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) +#error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16 +#endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */ + +/** The number of elements in coap_opt_filter_t. */ +#define COAP_OPT_FILTER_SIZE \ + (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1 + +/** + * Fixed-size vector we use for option filtering. It is large enough + * to hold COAP_OPT_FILTER_SHORT entries with an option number between + * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number + * between 256 and 65535. Its internal structure is + * + * @code +struct { + uint16_t mask; + uint16_t long_opts[COAP_OPT_FILTER_LONG]; + uint8_t short_opts[COAP_OPT_FILTER_SHORT]; +} + * @endcode + * + * The first element contains a bit vector that indicates which fields + * in the remaining array are used. The first COAP_OPT_FILTER_LONG + * bits correspond to the long option types that are stored in the + * elements from index 1 to COAP_OPT_FILTER_LONG. The next + * COAP_OPT_FILTER_SHORT bits correspond to the short option types + * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1 + * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter + * elements are treated as bytes. + */ +typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE]; + +/** Pre-defined filter that includes all options. */ +#define COAP_OPT_ALL NULL + +/** + * Clears filter @p f. + * + * @param f The filter to clear. + */ +COAP_STATIC_INLINE void +coap_option_filter_clear(coap_opt_filter_t f) { + memset(f, 0, sizeof(coap_opt_filter_t)); +} + +/** + * Sets the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_set(coap_opt_filter_t filter, uint16_t type); + +/** + * Clears the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type that should be cleared from the filter. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_unset(coap_opt_filter_t filter, uint16_t type); + +/** + * Checks if @p type is contained in @p filter. This function returns + * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given + * type does not fit in the filter). + * + * @param filter The filter object to search. + * @param type The type to search for. + * + * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error. + */ +int coap_option_filter_get(coap_opt_filter_t filter, uint16_t type); + +/** + * Sets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in + * the filter). + * + * @deprecated Use coap_option_filter_set() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_setb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_set(filter, type) ? 1 : -1; +} + +/** + * Clears the corresponding bit for @p type in @p filter. This function returns + * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not + * fit in the filter). + * + * @deprecated Use coap_option_filter_unset() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be cleared. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_clrb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_unset(filter, type) ? 1 : -1; +} + +/** + * Gets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type + * does not fit in the filter). + * + * @deprecated Use coap_option_filter_get() instead. + * + * @param filter The filter object to read bit from. + * @param type The type for which the bit should be read. + * + * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. + */ +COAP_STATIC_INLINE int +coap_option_getb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_get(filter, type); +} + +/** + * Iterator to run through PDU options. This object must be + * initialized with coap_option_iterator_init(). Call + * coap_option_next() to walk through the list of options until + * coap_option_next() returns @c NULL. + * + * @code + * coap_opt_t *option; + * coap_opt_iterator_t opt_iter; + * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + * + * while ((option = coap_option_next(&opt_iter))) { + * ... do something with option ... + * } + * @endcode + */ +typedef struct { + size_t length; /**< remaining length of PDU */ + uint16_t type; /**< decoded option type */ + unsigned int bad:1; /**< iterator object is ok if not set */ + unsigned int filtered:1; /**< denotes whether or not filter is used */ + coap_opt_t *next_option; /**< pointer to the unparsed next option */ + coap_opt_filter_t filter; /**< option filter */ +} coap_opt_iterator_t; + +/** + * Initializes the given option iterator @p oi to point to the beginning of the + * @p pdu's option list. This function returns @p oi on success, @c NULL + * otherwise (i.e. when no options exist). Note that a length check on the + * option list must be performed before coap_option_iterator_init() is called. + * + * @param pdu The PDU the options of which should be walked through. + * @param oi An iterator object that will be initilized. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. + * Fence-post options @c 14, @c 28, @c 42, ... are always + * skipped. + * + * @return The iterator object @p oi on success, @c NULL otherwise. + */ +coap_opt_iterator_t *coap_option_iterator_init(const coap_pdu_t *pdu, + coap_opt_iterator_t *oi, + const coap_opt_filter_t filter); + +/** + * Updates the iterator @p oi to point to the next option. This function returns + * a pointer to that option or @c NULL if no more options exist. The contents of + * @p oi will be updated. In particular, @c oi->n specifies the current option's + * ordinal number (counted from @c 1), @c oi->type is the option's type code, + * and @c oi->option points to the beginning of the current option itself. When + * advanced past the last option, @c oi->option will be @c NULL. + * + * Note that options are skipped whose corresponding bits in the filter + * specified with coap_option_iterator_init() are @c 0. Options with type codes + * that do not fit in this filter hence will always be returned. + * + * @param oi The option iterator to update. + * + * @return The next option or @c NULL if no more options exist. + */ +coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); + +/** + * Retrieves the first option of type @p type from @p pdu. @p oi must point to a + * coap_opt_iterator_t object that will be initialized by this function to + * filter only options with code @p type. This function returns the first option + * with this type, or @c NULL if not found. + * + * @param pdu The PDU to parse for options. + * @param type The option type code to search for. + * @param oi An iterator object to use. + * + * @return A pointer to the first option of type @p type, or @c NULL if + * not found. + */ +coap_opt_t *coap_check_option(coap_pdu_t *pdu, + uint16_t type, + coap_opt_iterator_t *oi); + +/** + * Encodes the given delta and length values into @p opt. This function returns + * the number of bytes that were required to encode @p delta and @p length or @c + * 0 on error. Note that the result indicates by how many bytes @p opt must be + * advanced to encode the option value. + * + * @param opt The option buffer space where @p delta and @p length are + * written. + * @param maxlen The maximum length of @p opt. + * @param delta The actual delta value to encode. + * @param length The actual length value to encode. + * + * @return The number of bytes used or @c 0 on error. + */ +size_t coap_opt_setheader(coap_opt_t *opt, + size_t maxlen, + uint16_t delta, + size_t length); + +/** + * Compute storage bytes needed for an option with given @p delta and + * @p length + * + * @param delta The option delta. + * @param length The option length. + * + * @return The number of bytes required to encode this option. + */ +size_t coap_opt_encode_size(uint16_t delta, size_t length); + +/** + * Encodes option with given @p delta into @p opt. This function returns the + * number of bytes written to @p opt or @c 0 on error. This happens especially + * when @p opt does not provide sufficient space to store the option value, + * delta, and option jumps when required. + * + * @param opt The option buffer space where @p val is written. + * @param n Maximum length of @p opt. + * @param delta The option delta. + * @param val The option value to copy into @p opt. + * @param length The actual length of @p val. + * + * @return The number of bytes that have been written to @p opt or @c 0 on + * error. The return value will always be less than @p n. + */ +size_t coap_opt_encode(coap_opt_t *opt, + size_t n, + uint16_t delta, + const uint8_t *val, + size_t length); + +/** + * Decodes the delta value of the next option. This function returns the number + * of bytes read or @c 0 on error. The caller of this function must ensure that + * it does not read over the boundaries of @p opt (e.g. by calling + * coap_opt_check_delta(). + * + * @param opt The option to examine. + * + * @return The number of bytes read or @c 0 on error. + */ +uint16_t coap_opt_delta(const coap_opt_t *opt); + +/** + * Returns the length of the given option. @p opt must point to an option jump + * or the beginning of the option. This function returns @c 0 when @p opt is not + * an option or the actual length of @p opt (which can be @c 0 as well). + * + * @note {The rationale for using @c 0 in case of an error is that in most + * contexts, the result of this function is used to skip the next + * coap_opt_length() bytes.} + * + * @param opt The option whose length should be returned. + * + * @return The option's length or @c 0 when undefined. + */ +uint16_t coap_opt_length(const coap_opt_t *opt); + +/** + * Returns a pointer to the value of the given option. @p opt must point to an + * option jump or the beginning of the option. This function returns @c NULL if + * @p opt is not a valid option. + * + * @param opt The option whose value should be returned. + * + * @return A pointer to the option value or @c NULL on error. + */ +const uint8_t *coap_opt_value(const coap_opt_t *opt); + +/** @} */ + +/** + * Representation of chained list of CoAP options to install. + * + * @code + * coap_optlist_t *optlist_chain = NULL; + * coap_pdu_t *pdu = coap_new_pdu(session); + * + * ... other set up code ... + * coap_insert_optlist(&optlist_chain, coap_new_optlist(COAP_OPTION_OBSERVE, + * COAP_OBSERVE_ESTABLISH, NULL)); + * + * coap_add_optlist_pdu(pdu, &optlist_chain); + * ... other code ... + * coap_delete_optlist(optlist_chain); + * @endcode + */ +typedef struct coap_optlist_t { + struct coap_optlist_t *next; /**< next entry in the optlist chain */ + uint16_t number; /**< the option number (no delta coding) */ + size_t length; /**< the option value length */ + uint8_t *data; /**< the option data */ +} coap_optlist_t; + +/** + * Create a new optlist entry. + * + * @param number The option number (COAP_OPTION_*) + * @param length The option length + * @param data The option value data + * + * @return A pointer to the new optlist entry, or @c NULL if error + */ +coap_optlist_t *coap_new_optlist(uint16_t number, + size_t length, + const uint8_t *data); + +/** + * The current optlist of @p optlist_chain is first sorted (as per RFC7272 + * ordering requirements) and then added to the @p pdu. + * + * @param pdu The pdu to add the options to from the chain list + * @param optlist_chain The chained list of optlist to add to the pdu + * + * @return @c 1 if succesful or @c 0 if failure; + */ +int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t** optlist_chain); + +/** + * Adds @p optlist to the given @p optlist_chain. The optlist_chain variable + * be set to NULL before the initial call to coap_insert_optlist(). + * The optlist_chain will need to be deleted using coap_delete_optlist() + * when no longer required. + * + * @param optlist_chain The chain to add optlist to + * @param optlist The optlist to add to the queue + * + * @return @c 1 if successful, @c 0 otherwise. + */ +int coap_insert_optlist(coap_optlist_t **optlist_chain, + coap_optlist_t *optlist); + +/** + * Removes all entries from the @p optlist_chain, freeing off their + * memory usage. + * + * @param optlist_chain The optlist chain to remove all the entries from + */ +void coap_delete_optlist(coap_optlist_t *optlist_chain); + +#endif /* COAP_OPTION_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/pdu.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/pdu.h new file mode 100644 index 00000000000..206e2643543 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/pdu.h @@ -0,0 +1,543 @@ +/* + * pdu.h -- CoAP message structure + * + * Copyright (C) 2010-2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file pdu.h + * @brief Pre-defined constants that reflect defaults for CoAP + */ + +#ifndef COAP_PDU_H_ +#define COAP_PDU_H_ + +#include "uri.h" + +struct coap_session_t; + +#ifdef WITH_LWIP +#include +#endif + +#include + +#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP/TCP port */ +#define COAPS_DEFAULT_PORT 5684 /* CoAP default UDP/TCP port for secure transmission */ +#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ +#ifndef COAP_DEFAULT_MTU +#define COAP_DEFAULT_MTU 1152 +#endif /* COAP_DEFAULT_MTU */ + +/* TCP Message format constants, do not modify */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP8 13 +#define COAP_MESSAGE_SIZE_OFFSET_TCP16 269 /* 13 + 256 */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP32 65805 /* 269 + 65536 */ + +/* Derived message size limits */ +#define COAP_MAX_MESSAGE_SIZE_TCP0 (COAP_MESSAGE_SIZE_OFFSET_TCP8-1) /* 12 */ +#define COAP_MAX_MESSAGE_SIZE_TCP8 (COAP_MESSAGE_SIZE_OFFSET_TCP16-1) /* 268 */ +#define COAP_MAX_MESSAGE_SIZE_TCP16 (COAP_MESSAGE_SIZE_OFFSET_TCP32-1) /* 65804 */ +#define COAP_MAX_MESSAGE_SIZE_TCP32 (COAP_MESSAGE_SIZE_OFFSET_TCP32+0xFFFFFFFF) + +#ifndef COAP_DEFAULT_MAX_PDU_RX_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4) +#else +/* 8 MiB max-message-size plus some space for options */ +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (8*1024*1024+256) +#endif +#endif /* COAP_DEFAULT_MAX_PDU_RX_SIZE */ + +#ifndef COAP_DEBUG_BUF_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEBUG_BUF_SIZE 128 +#else /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +/* 1024 derived from RFC7252 4.6. Message Size max payload */ +#define COAP_DEBUG_BUF_SIZE (8 + 1024 * 2) +#endif /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +#endif /* COAP_DEBUG_BUF_SIZE */ + +#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ +#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ + +/** well-known resources URI */ +#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" + +/* CoAP message types */ + +#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */ +#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */ +#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */ +#define COAP_MESSAGE_RST 3 /* indicates error in received messages */ + +/* CoAP request methods */ + +#define COAP_REQUEST_GET 1 +#define COAP_REQUEST_POST 2 +#define COAP_REQUEST_PUT 3 +#define COAP_REQUEST_DELETE 4 +#define COAP_REQUEST_FETCH 5 /* RFC 8132 */ +#define COAP_REQUEST_PATCH 6 /* RFC 8132 */ +#define COAP_REQUEST_IPATCH 7 /* RFC 8132 */ + +/* + * CoAP option types (be sure to update coap_option_check_critical() when + * adding options + */ + +#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */ +#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */ +#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */ +#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */ +#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */ +#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */ +#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */ +#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ +#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */ +#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */ +#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */ +#define COAP_OPTION_SIZE2 28 /* E, uint, 0-4 B, (none) */ +#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */ +#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */ + +/* option types from RFC 7641 */ + +#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */ +#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE + +/* selected option types from RFC 7959 */ + +#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */ +#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */ + +/* selected option types from RFC 7967 */ + +#define COAP_OPTION_NORESPONSE 258 /* N, uint, 0--1 B, 0 */ + +#define COAP_MAX_OPT 65535 /**< the highest option number we know */ + +/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */ + +/* As of draft-ietf-core-coap-04, response codes are encoded to base + * 32, i.e. the three upper bits determine the response class while + * the remaining five fine-grained information specific to that class. + */ +#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100) + +/* Determines the class of response code C */ +#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) + +#ifndef SHORT_ERROR_RESPONSE +/** + * Returns a human-readable response phrase for the specified CoAP response @p + * code. This function returns @c NULL if not found. + * + * @param code The response code for which the literal phrase should be + * retrieved. + * + * @return A zero-terminated string describing the error, or @c NULL if not + * found. + */ +const char *coap_response_phrase(unsigned char code); + +#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */ + +#else +#define coap_response_phrase(x) ((char *)NULL) + +#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */ +#endif /* SHORT_ERROR_RESPONSE */ + +/* The following definitions exist for backwards compatibility */ +#if 0 /* this does not exist any more */ +#define COAP_RESPONSE_100 40 /* 100 Continue */ +#endif +#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */ +#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */ +#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */ +#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */ +#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */ +#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */ +#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */ +#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */ +#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */ +#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */ +#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */ +#if 0 /* these response codes do not have a valid code any more */ +# define COAP_RESPONSE_X_240 240 /* Token Option required by server */ +# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */ +#endif +#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */ + +#define COAP_SIGNALING_CODE(N) (((N)/100 << 5) | (N)%100) +#define COAP_SIGNALING_CSM COAP_SIGNALING_CODE(701) +#define COAP_SIGNALING_PING COAP_SIGNALING_CODE(702) +#define COAP_SIGNALING_PONG COAP_SIGNALING_CODE(703) +#define COAP_SIGNALING_RELEASE COAP_SIGNALING_CODE(704) +#define COAP_SIGNALING_ABORT COAP_SIGNALING_CODE(705) + +/* Applies to COAP_SIGNALING_CSM */ +#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE 2 +#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER 4 +/* Applies to COAP_SIGNALING_PING / COAP_SIGNALING_PONG */ +#define COAP_SIGNALING_OPTION_CUSTODY 2 +/* Applies to COAP_SIGNALING_RELEASE */ +#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS 2 +#define COAP_SIGNALING_OPTION_HOLD_OFF 4 +/* Applies to COAP_SIGNALING_ABORT */ +#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION 2 + +/* CoAP media type encoding */ + +#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */ +#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */ +#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */ +#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */ +#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */ +#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */ +#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */ +#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */ + +/* Content formats from RFC 8152 */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN 98 /* application/cose; cose-type="cose-sign" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1 18 /* application/cose; cose-type="cose-sign1" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT 96 /* application/cose; cose-type="cose-encrypt" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0 16 /* application/cose; cose-type="cose-encrypt0" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC 97 /* application/cose; cose-type="cose-mac" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0 17 /* application/cose; cose-type="cose-mac0" */ + +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY 101 /* application/cose-key */ +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET 102 /* application/cose-key-set */ + +/* Content formats from RFC 8428 */ +#define COAP_MEDIATYPE_APPLICATION_SENML_JSON 110 /* application/senml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON 111 /* application/sensml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR 112 /* application/senml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR 113 /* application/sensml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENML_EXI 114 /* application/senml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI 115 /* application/sensml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENML_XML 310 /* application/senml+xml */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_XML 311 /* application/sensml+xml */ + +/* Note that identifiers for registered media types are in the range 0-65535. We + * use an unallocated type here and hope for the best. */ +#define COAP_MEDIATYPE_ANY 0xff /* any media type */ + +/** + * coap_tid_t is used to store CoAP transaction id, i.e. a hash value + * built from the remote transport address and the message id of a + * CoAP PDU. Valid transaction ids are greater or equal zero. + */ +typedef int coap_tid_t; + +/** Indicates an invalid transaction id. */ +#define COAP_INVALID_TID -1 + +/** + * Indicates that a response is suppressed. This will occur for error + * responses if the request was received via IP multicast. + */ +#define COAP_DROPPED_RESPONSE -2 + +#define COAP_PDU_DELAYED -3 + +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list + * in a CoAP message is limited by 0b11110000 + * marker */ + +#define COAP_OPT_END 0xF0 /* end marker */ + +#define COAP_PAYLOAD_START 0xFF /* payload marker */ + +/** + * @deprecated Use coap_optlist_t instead. + * + * Structures for more convenient handling of options. (To be used with ordered + * coap_list_t.) The option's data will be added to the end of the coap_option + * structure (see macro COAP_OPTION_DATA). + */ +COAP_DEPRECATED typedef struct { + uint16_t key; /* the option key (no delta coding) */ + unsigned int length; +} coap_option; + +#define COAP_OPTION_KEY(option) (option).key +#define COAP_OPTION_LENGTH(option) (option).length +#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option)) + +/** + * structure for CoAP PDUs + * token, if any, follows the fixed size header, then options until + * payload marker (0xff), then the payload if stored inline. + * Memory layout is: + * <---header--->|<---token---><---options--->0xff<---payload---> + * header is addressed with a negative offset to token, its maximum size is + * max_hdr_size. + * options starts at token + token_length + * payload starts at data, its length is used_size - (data - token) + */ + +typedef struct coap_pdu_t { + uint8_t type; /**< message type */ + uint8_t code; /**< request method (value 1--10) or response code (value 40-255) */ + uint8_t max_hdr_size; /**< space reserved for protocol-specific header */ + uint8_t hdr_size; /**< actaul size used for protocol-specific header */ + uint8_t token_length; /**< length of Token */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + uint16_t max_delta; /**< highest option number */ + size_t alloc_size; /**< allocated storage for token, options and payload */ + size_t used_size; /**< used bytes of storage for token, options and payload */ + size_t max_size; /**< maximum size for token, options and payload, or zero for variable size pdu */ + uint8_t *token; /**< first byte of token, if any, or options */ + uint8_t *data; /**< first byte of payload, if any */ +#ifdef WITH_LWIP + struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside + * inside the pbuf's payload, but this pointer + * has to be kept because no exact offset can be + * given. This field must not be accessed from + * outside, because the pbuf's reference count + * is checked to be 1 when the pbuf is assigned + * to the pdu, and the pbuf stays exclusive to + * this pdu. */ +#endif +} coap_pdu_t; + +#define COAP_PDU_IS_EMPTY(pdu) ((pdu)->code == 0) +#define COAP_PDU_IS_REQUEST(pdu) (!COAP_PDU_IS_EMPTY(pdu) && (pdu)->code < 32) +#define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 224) +#define COAP_PDU_IS_SIGNALING(pdu) ((pdu)->code >= 224) + +#define COAP_PDU_MAX_UDP_HEADER_SIZE 4 +#define COAP_PDU_MAX_TCP_HEADER_SIZE 6 + +#ifdef WITH_LWIP +/** + * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this + * function. + * + * The pbuf is checked for being contiguous, and for having only one reference. + * The reference is stored in the PDU and will be freed when the PDU is freed. + * + * (For now, these are fatal errors; in future, a new pbuf might be allocated, + * the data copied and the passed pbuf freed). + * + * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards + * copying the contents of the pbuf to the pdu. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); +#endif + +typedef uint8_t coap_proto_t; +/** +* coap_proto_t values +*/ +#define COAP_PROTO_NONE 0 +#define COAP_PROTO_UDP 1 +#define COAP_PROTO_DTLS 2 +#define COAP_PROTO_TCP 3 +#define COAP_PROTO_TLS 4 + +/** + * Creates a new CoAP PDU with at least enough storage space for the given + * @p size maximum message size. The function returns a pointer to the + * node coap_pdu_t object on success, or @c NULL on error. The storage allocated + * for the result must be released with coap_delete_pdu() if coap_send() is not + * called. + * + * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON, + * COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * @param code The message code. + * @param tid The transcation id to set or 0 if unknown / not applicable. + * @param size The maximum allowed number of byte for the message. + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * +coap_pdu_init(uint8_t type, uint8_t code, uint16_t tid, size_t size); + +/** + * Dynamically grows the size of @p pdu to @p new_size. The new size + * must not exceed the PDU's configure maximum size. On success, this + * function returns 1, otherwise 0. + * + * @param pdu The PDU to resize. + * @param new_size The new size in bytes. + * @return 1 if the operation succeeded, 0 otherwise. + */ +int coap_pdu_resize(coap_pdu_t *pdu, size_t new_size); + +/** + * Clears any contents from @p pdu and resets @c used_size, + * and @c data pointers. @c max_size is set to @p size, any + * other field is set to @c 0. Note that @p pdu must be a valid + * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). + */ +void coap_pdu_clear(coap_pdu_t *pdu, size_t size); + +/** + * Creates a new CoAP PDU. + */ +coap_pdu_t *coap_new_pdu(const struct coap_session_t *session); + +/** + * Dispose of an CoAP PDU and frees associated storage. + * Not that in general you should not call this function directly. + * When a PDU is sent with coap_send(), coap_delete_pdu() will be + * called automatically for you. + */ + +void coap_delete_pdu(coap_pdu_t *); + +/** +* Interprets @p data to determine the number of bytes in the header. +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The first byte of raw data to parse as CoAP PDU. +* +* @return A value greater than zero on success or @c 0 on error. +*/ +size_t coap_pdu_parse_header_size(coap_proto_t proto, + const uint8_t *data); + +/** + * Parses @p data to extract the message size. + * @p length must be at least coap_pdu_parse_header_size(proto, data). + * This function returns @c 0 on error or a number greater than zero on success. + * + * @param proto Session's protocol + * @param data The raw data to parse as CoAP PDU. + * @param length The actual size of @p data. + * + * @return A value greater than zero on success or @c 0 on error. + */ +size_t coap_pdu_parse_size(coap_proto_t proto, + const uint8_t *data, + size_t length); + +/** + * Decode the protocol specific header for the specified PDU. + * @param pdu A newly received PDU. + * @param proto The target wire protocol. + * @return 1 for success or 0 on error. + */ + +int coap_pdu_parse_header(coap_pdu_t *pdu, coap_proto_t proto); + +/** + * Verify consistency in the given CoAP PDU structure and locate the data. + * This function returns @c 0 on error or a number greater than zero on + * success. + * This function only parses the token and options, up to the payload start + * marker. + * + * @param pdu The PDU structure to. + * + * @return 1 on success or @c 0 on error. + */ +int coap_pdu_parse_opt(coap_pdu_t *pdu); + +/** +* Parses @p data into the CoAP PDU structure given in @p result. +* The target pdu must be large enough to +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The raw data to parse as CoAP PDU. +* @param length The actual size of @p data. +* @param pdu The PDU structure to fill. Note that the structure must +* provide space to hold at least the token and options +* part of the message. +* +* @return 1 on success or @c 0 on error. +*/ +int coap_pdu_parse(coap_proto_t proto, + const uint8_t *data, + size_t length, + coap_pdu_t *pdu); +/** + * Adds token of length @p len to @p pdu. + * Adding the token destroys any following contents of the pdu. Hence options + * and data must be added after coap_add_token() has been called. In @p pdu, + * length is set to @p len + @c 4, and max_delta is set to @c 0. This function + * returns @c 0 on error or a value greater than zero on success. + * + * @param pdu The PDU where the token is to be added. + * @param len The length of the new token. + * @param data The token to add. + * + * @return A value greater than zero on success, or @c 0 on error. + */ +int coap_add_token(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first + * parameter. + * coap_add_option() destroys the PDU's data, so coap_add_data() must be called + * after all options have been added. As coap_add_token() destroys the options + * following the token, the token must be added before coap_add_option() is + * called. This function returns the number of bytes written or @c 0 on error. + */ +size_t coap_add_option(coap_pdu_t *pdu, + uint16_t type, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first parameter, but does + * not write a value. It works like coap_add_option with respect to calling + * sequence (i.e. after token and before data). This function returns a memory + * address to which the option data has to be written before the PDU can be + * sent, or @c NULL on error. + */ +uint8_t *coap_add_option_later(coap_pdu_t *pdu, + uint16_t type, + size_t len); + +/** + * Adds given data to the pdu that is passed as first parameter. Note that the + * PDU's data is destroyed by coap_add_option(). coap_add_data() must be called + * only once per PDU, otherwise the result is undefined. + */ +int coap_add_data(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds given data to the pdu that is passed as first parameter but does not + * copyt it. Note that the PDU's data is destroyed by coap_add_option(). + * coap_add_data() must be have been called once for this PDU, otherwise the + * result is undefined. + * The actual data must be copied at the returned location. + */ +uint8_t *coap_add_data_after(coap_pdu_t *pdu, size_t len); + +/** + * Retrieves the length and data pointer of specified PDU. Returns 0 on error or + * 1 if *len and *data have correct values. Note that these values are destroyed + * with the pdu. + */ +int coap_get_data(const coap_pdu_t *pdu, + size_t *len, + uint8_t **data); + +/** + * Compose the protocol specific header for the specified PDU. + * @param pdu A newly composed PDU. + * @param proto The target wire protocol. + * @return Number of header bytes prepended before pdu->token or 0 on error. + */ + +size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto); + +#endif /* COAP_PDU_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/prng.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/prng.h new file mode 100644 index 00000000000..c9510bf5602 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/prng.h @@ -0,0 +1,127 @@ +/* + * prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef COAP_PRNG_H_ +#define COAP_PRNG_H_ + +/** + * @defgroup prng Pseudo Random Numbers + * API functions for gerating pseudo random numbers + * @{ + */ + +#if defined(WITH_CONTIKI) +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +contiki_prng_impl(unsigned char *buf, size_t len) { + uint16_t v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) contiki_prng_impl((Buf), (Length)) +#define prng_init(Value) random_init((uint16_t)(Value)) +#elif defined(WITH_LWIP) && defined(LWIP_RAND) +COAP_STATIC_INLINE int +lwip_prng_impl(unsigned char *buf, size_t len) { + u32_t v = LWIP_RAND(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = LWIP_RAND(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) lwip_prng_impl((Buf), (Length)) +#define prng_init(Value) +#elif defined(_WIN32) +#define prng_init(Value) +errno_t __cdecl rand_s( _Out_ unsigned int* _RandomValue ); + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len != 0 ) { + uint32_t r = 0; + size_t i; + if ( rand_s( &r ) != 0 ) + return 0; + for ( i = 0; i < len && i < 4; i++ ) { + *buf++ = (uint8_t)r; + r >>= 8; + } + len -= i; + } + return 1; +} + +#else +#include + + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len-- ) + *buf++ = rand() & 0xFF; + return 1; +} +#endif + + +#ifndef prng +/** + * Fills \p Buf with \p Length bytes of random data. + * + * @hideinitializer + */ +#define prng(Buf,Length) coap_prng_impl((Buf), (Length)) +#endif + +#ifndef prng_init +/** + * Called to set the PRNG seed. You may want to re-define this to allow for a + * better PRNG. + * + * @hideinitializer + */ +#define prng_init(Value) srand((unsigned long)(Value)) +#endif + +/** @} */ + +#endif /* COAP_PRNG_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/resource.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/resource.h new file mode 100644 index 00000000000..58018720e4e --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/resource.h @@ -0,0 +1,524 @@ +/* + * resource.h -- generic resource handling + * + * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file resource.h + * @brief Generic resource handling + */ + +#ifndef COAP_RESOURCE_H_ +#define COAP_RESOURCE_H_ + +# include + +#ifndef COAP_RESOURCE_CHECK_TIME +/** The interval in seconds to check if resources have changed. */ +#define COAP_RESOURCE_CHECK_TIME 2 +#endif /* COAP_RESOURCE_CHECK_TIME */ + +#include "uthash.h" +#include "async.h" +#include "str.h" +#include "pdu.h" +#include "net.h" +#include "subscribe.h" + +/** + * Definition of message handler function (@sa coap_resource_t). + */ +typedef void (*coap_method_handler_t) + (coap_context_t *, + struct coap_resource_t *, + coap_session_t *, + coap_pdu_t *, + coap_binary_t * /* token */, + coap_string_t * /* query string */, + coap_pdu_t * /* response */); + +#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1 +#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2 + +typedef struct coap_attr_t { + struct coap_attr_t *next; + coap_str_const_t *name; + coap_str_const_t *value; + int flags; +} coap_attr_t; + +/** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ +#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1 + +/** + * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0 + +/** + * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2 + +typedef struct coap_resource_t { + unsigned int dirty:1; /**< set to 1 if resource has changed */ + unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet + * been notified of the last change */ + unsigned int observable:1; /**< can be observed */ + unsigned int cacheable:1; /**< can be cached */ + unsigned int is_unknown:1; /**< resource created for unknown handler */ + + /** + * Used to store handlers for the seven coap methods @c GET, @c POST, @c PUT, + * @c DELETE, @c FETCH, @c PATCH and @c IPATCH. + * coap_dispatch() will pass incoming requests to the handler + * that corresponds to its request method or generate a 4.05 response if no + * handler is available. + */ + coap_method_handler_t handler[7]; + + UT_hash_handle hh; + + coap_attr_t *link_attr; /**< attributes to be included with the link format */ + coap_subscription_t *subscribers; /**< list of observers for this resource */ + + /** + * Request URI Path for this resource. This field will point into static + * or allocated memory which must remain there for the duration of the + * resource. + */ + coap_str_const_t *uri_path; /**< the key used for hash lookup for this resource */ + int flags; + + /** + * The next value for the Observe option. This field must be increased each + * time the resource changes. Only the lower 24 bits are sent. + */ + unsigned int observe; + + /** + * This pointer is under user control. It can be used to store context for + * the coap handler. + */ + void *user_data; + +} coap_resource_t; + +/** + * Creates a new resource object and initializes the link field to the string + * @p uri_path. This function returns the new coap_resource_t object. + * + * If the string is going to be freed off by coap_delete_resource() when + * COAP_RESOURCE_FLAGS_RELEASE_URI is set in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param uri_path The string URI path of the new resource. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_RESOURCE_FLAGS_RELEASE_URI + * If this flag is set, the URI passed to + * coap_resource_init() is free'd by + * coap_delete_resource()@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_CON + * If this flag is set, coap-observe notifications + * will be sent confirmable by default.@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_NON (default) + * If this flag is set, coap-observe notifications + * will be sent non-confirmable by default.@n + * + * If flags is set to 0 then the + * COAP_RESOURCE_FLAGS_NOTIFY_NON is considered. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, + int flags); + + +/** + * Creates a new resource object for the unknown resource handler with support + * for PUT. + * + * In the same way that additional handlers can be added to the resource + * created by coap_resource_init() by using coap_register_handler(), POST, + * GET, DELETE etc. handlers can be added to this resource. It is the + * responsibility of the application to manage the unknown resources by either + * creating new resources with coap_resource_init() (which should have a + * DELETE handler specified for the resource removal) or by maintaining an + * active resource list. + * + * Note: There can only be one unknown resource handler per context - attaching + * a new one overrides the previous definition. + * + * Note: It is not possible to observe the unknown resource with a GET request + * - a separate resource needs to be reated by the PUT (or POST) handler, + * and make that resource observable. + * + * This function returns the new coap_resource_t object. + * + * @param put_handler The PUT handler to register with @p resource for + * unknown Uri-Path. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_unknown_init(coap_method_handler_t put_handler); + +/** + * Sets the notification message type of resource @p resource to given + * @p mode + + * @param resource The resource to update. + * @param mode Must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON + * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. + */ +COAP_STATIC_INLINE void +coap_resource_set_mode(coap_resource_t *resource, int mode) { + resource->flags = (resource->flags & + ~(COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)) | + (mode & (COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)); +} + +/** + * Sets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to attach the data to + * @param data Data to attach to the user_data field. This pointer is only used for + * storage, the data remains under user control + */ +COAP_STATIC_INLINE void +coap_resource_set_userdata(coap_resource_t *r, void *data) { + r->user_data = data; +} + +/** + * Gets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to retrieve the user_darta from + * + * @return The user_data pointer + */ +COAP_STATIC_INLINE void * +coap_resource_get_userdata(coap_resource_t *r) { + return r->user_data; +} + +/** + * Registers the given @p resource for @p context. The resource must have been + * created by coap_resource_init() or coap_resource_unknown_init(), the + * storage allocated for the resource will be released by coap_delete_resource(). + * + * @param context The context to use. + * @param resource The resource to store. + */ +void coap_add_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes a resource identified by @p resource. The storage allocated for that + * resource is freed, and removed from the context. + * + * @param context The context where the resources are stored. + * @param resource The resource to delete. + * + * @return @c 1 if the resource was found (and destroyed), + * @c 0 otherwise. + */ +int coap_delete_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes all resources from given @p context and frees their storage. + * + * @param context The CoAP context with the resources to be deleted. + */ +void coap_delete_all_resources(coap_context_t *context); + +/** + * Registers a new attribute with the given @p resource. As the + * attribute's coap_str_const_ fields will point to @p name and @p value the + * caller must ensure that these pointers are valid during the + * attribute's lifetime. + + * If the @p name and/or @p value string is going to be freed off at attribute + * removal time by the setting of COAP_ATTR_FLAGS_RELEASE_NAME or + * COAP_ATTR_FLAGS_RELEASE_VALUE in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param resource The resource to register the attribute with. + * @param name The attribute's name as a string. + * @param value The attribute's value as a string or @c NULL if none. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_ATTR_FLAGS_RELEASE_NAME + * If this flag is set, the name passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * COAP_ATTR_FLAGS_RELEASE_VALUE + * If this flag is set, the value passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * @return A pointer to the new attribute or @c NULL on error. + */ +coap_attr_t *coap_add_attr(coap_resource_t *resource, + coap_str_const_t *name, + coap_str_const_t *value, + int flags); + +/** + * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL + * otherwise. + * + * @param resource The resource to search for attribute @p name. + * @param name Name of the requested attribute as a string. + * @return The first attribute with specified @p name or @c NULL if none + * was found. + */ +coap_attr_t *coap_find_attr(coap_resource_t *resource, + coap_str_const_t *name); + +/** + * Deletes an attribute. + * Note: This is for internal use only, as it is not deleted from its chain. + * + * @param attr Pointer to a previously created attribute. + * + */ +void coap_delete_attr(coap_attr_t *attr); + +/** + * Status word to encode the result of conditional print or copy operations such + * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to + * encode the number of characters that has actually been printed, bits 28 to 31 + * encode the status. When COAP_PRINT_STATUS_ERROR is set, an error occurred + * during output. In this case, the other bits are undefined. + * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the + * printing would have exceeded the current buffer. + */ +typedef unsigned int coap_print_status_t; + +#define COAP_PRINT_STATUS_MASK 0xF0000000u +#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK) +#define COAP_PRINT_STATUS_ERROR 0x80000000u +#define COAP_PRINT_STATUS_TRUNC 0x40000000u + +/** + * Writes a description of this resource in link-format to given text buffer. @p + * len must be initialized to the maximum length of @p buf and will be set to + * the number of characters actually written if successful. This function + * returns @c 1 on success or @c 0 on error. + * + * @param resource The resource to describe. + * @param buf The output buffer to write the description to. + * @param len Must be initialized to the length of @p buf and + * will be set to the length of the printed link description. + * @param offset The offset within the resource description where to + * start writing into @p buf. This is useful for dealing + * with the Block2 option. @p offset is updated during + * output as it is consumed. + * + * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, + * the lower 28 bits will indicate the number of characters that + * have actually been output into @p buffer. The flag + * COAP_PRINT_STATUS_TRUNC indicates that the output has been + * truncated. + */ +coap_print_status_t coap_print_link(const coap_resource_t *resource, + unsigned char *buf, + size_t *len, + size_t *offset); + +/** + * Registers the specified @p handler as message handler for the request type @p + * method + * + * @param resource The resource for which the handler shall be registered. + * @param method The CoAP request method to handle. + * @param handler The handler to register with @p resource. + */ +void coap_register_handler(coap_resource_t *resource, + unsigned char method, + coap_method_handler_t handler); + +/** + * Returns the resource identified by the unique string @p uri_path. If no + * resource was found, this function returns @c NULL. + * + * @param context The context to look for this resource. + * @param uri_path The unique string uri of the resource. + * + * @return A pointer to the resource or @c NULL if not found. + */ +coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context, + coap_str_const_t *uri_path); + +/** + * @addtogroup observe + */ + +/** + * Adds the specified peer as observer for @p resource. The subscription is + * identified by the given @p token. This function returns the registered + * subscription information if the @p observer has been added, or @c NULL on + * error. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription. + * @param query The query string, if any. subscription will + take ownership of the string. + * @param has_block2 If Option Block2 defined. + * @param block2 Contents of Block2 if Block 2 defined. + * @return A pointer to the added/updated subscription + * information or @c NULL on error. + */ +coap_subscription_t *coap_add_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token, + coap_string_t *query, + int has_block2, + coap_block_t block2); + +/** + * Returns a subscription object for given @p peer. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return A valid subscription if exists or @c NULL otherwise. + */ +coap_subscription_t *coap_find_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Marks an observer as alive. + * + * @param context The CoAP context to use. + * @param session The observer's session + * @param token The corresponding token that has been used for the + * subscription. + */ +void coap_touch_observer(coap_context_t *context, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p observer from @p resource and releases the + * allocated storage. The result is @c 1 if an observation relationship with @p + * observer and @p token existed, @c 0 otherwise. + * + * @param resource The observed resource. + * @param session The observer's session. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return @c 1 if the observer has been deleted, @c 0 otherwise. + */ +int coap_delete_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p session and releases the allocated storage. + * + * @param context The CoAP context to use. + * @param session The observer's session. + */ +void coap_delete_observers(coap_context_t *context, coap_session_t *session); + +/** + * Checks for all known resources, if they are dirty and notifies subscribed + * observers. + */ +void coap_check_notify(coap_context_t *context); + +#define RESOURCES_ADD(r, obj) \ + HASH_ADD(hh, (r), uri_path->s[0], (obj)->uri_path->length, (obj)) + +#define RESOURCES_DELETE(r, obj) \ + HASH_DELETE(hh, (r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp, *rtmp; \ + HASH_ITER(hh, (r), tmp, rtmp) + +#define RESOURCES_FIND(r, k, res) { \ + HASH_FIND(hh, (r), (k)->s, (k)->length, (res)); \ + } + +/** @} */ + +coap_print_status_t coap_print_wellknown(coap_context_t *, + unsigned char *, + size_t *, size_t, + coap_opt_t *); + +void +coap_handle_failed_notify(coap_context_t *, + coap_session_t *, + const coap_binary_t *); + +/** + * Set whether a @p resource is observable. If the resource is observable + * and the client has set the COAP_OPTION_OBSERVE in a request packet, then + * whenever the state of the resource changes (a call to + * coap_resource_trigger_observe()), an Observer response will get sent. + * + * @param resource The CoAP resource to use. + * @param mode @c 1 if Observable is to be set, @c 0 otherwise. + * + */ +COAP_STATIC_INLINE void +coap_resource_set_get_observable(coap_resource_t *resource, int mode) { + resource->observable = mode ? 1 : 0; +} + +/** + * Initiate the sending of an Observe packet for all observers of @p resource, + * optionally matching @p query if not NULL + * + * @param resource The CoAP resource to use. + * @param query The Query to match against or NULL + * + * @return @c 1 if the Observe has been triggered, @c 0 otherwise. + */ +int +coap_resource_notify_observers(coap_resource_t *resource, + const coap_string_t *query); + +/** + * Get the UriPath from a @p resource. + * + * @param resource The CoAP resource to check. + * + * @return The UriPath if it exists or @c NULL otherwise. + */ +COAP_STATIC_INLINE coap_str_const_t* +coap_resource_get_uri_path(coap_resource_t *resource) { + if (resource) + return resource->uri_path; + return NULL; +} + +/** + * @deprecated use coap_resource_notify_observers() instead. + */ +COAP_DEPRECATED int +coap_resource_set_dirty(coap_resource_t *r, + const coap_string_t *query); + +#endif /* COAP_RESOURCE_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/str.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/str.h new file mode 100644 index 00000000000..6c1488c982d --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/str.h @@ -0,0 +1,121 @@ +/* + * str.h -- strings to be used in the CoAP library + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_STR_H_ +#define COAP_STR_H_ + +#include + + +/** + * @defgroup string String handling support + * API functions for handling strings + * @{ + */ + +/** + * Coap string data definition + */ +typedef struct coap_string_t { + size_t length; /**< length of string */ + uint8_t *s; /**< string data */ +} coap_string_t; + +/** + * Coap string data definition with const data + */ +typedef struct coap_str_const_t { + size_t length; /**< length of string */ + const uint8_t *s; /**< string data */ +} coap_str_const_t; + +#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); } + +/** + * Coap binary data definition + */ +typedef struct coap_binary_t { + size_t length; /**< length of binary data */ + uint8_t *s; /**< binary data */ +} coap_binary_t; + +/** + * Returns a new string object with at least size+1 bytes storage allocated. + * The string must be released using coap_delete_string(). + * + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_string_t *coap_new_string(size_t size); + +/** + * Deletes the given string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_string(coap_string_t *string); + +/** + * Returns a new const string object with at least size+1 bytes storage + * allocated, and the provided data copied into the string object. + * The string must be released using coap_delete_str_const(). + * + * @param data The data to put in the new string object. + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_str_const_t *coap_new_str_const(const uint8_t *data, size_t size); + +/** + * Deletes the given const string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_str_const(coap_str_const_t *string); + +/** + * Take the specified byte array (text) and create a coap_str_const_t * + * + * WARNING: The byte array must be in the local scope and not a + * parameter in the function call as sizeof() will return the size of the + * pointer, not the size of the byte array, leading to unxepected results. + * + * @param string The const byte array to convert to a coap_str_const_t * + */ +#ifdef __cplusplus +namespace libcoap { + struct CoAPStrConst : coap_str_const_t { + operator coap_str_const_t *() { return this; } + }; +} +#define coap_make_str_const(CStr) \ + libcoap::CoAPStrConst{sizeof(CStr)-1, reinterpret_cast(CStr)} +#else /* __cplusplus */ +#define coap_make_str_const(string) \ + (&(coap_str_const_t){sizeof(string)-1,(const uint8_t *)(string)}) +#endif /* __cplusplus */ + +/** + * Compares the two strings for equality + * + * @param string1 The first string. + * @param string2 The second string. + * + * @return @c 1 if the strings are equal + * @c 0 otherwise. + */ +#define coap_string_equal(string1,string2) \ + ((string1)->length == (string2)->length && ((string1)->length == 0 || \ + memcmp((string1)->s, (string2)->s, (string1)->length) == 0)) + +/** @} */ + +#endif /* COAP_STR_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/subscribe.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/subscribe.h new file mode 100644 index 00000000000..ed635a6182a --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/subscribe.h @@ -0,0 +1,77 @@ +/* + * subscribe.h -- subscription handling for CoAP + * see RFC7641 + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + + +#ifndef COAP_SUBSCRIBE_H_ +#define COAP_SUBSCRIBE_H_ + +#include "address.h" +#include "coap_io.h" +#include "block.h" + +/** + * @defgroup observe Resource observation + * API functions for interfacing with the observe handling (RFC7641) + * @{ + */ + +/** + * The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe + * relationship for (sender address, token) is requested. + */ +#define COAP_OBSERVE_ESTABLISH 0 + +/** + * The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe + * relationship for (sender address, token) must be cancelled. + */ +#define COAP_OBSERVE_CANCEL 1 + +#ifndef COAP_OBS_MAX_NON +/** + * Number of notifications that may be sent non-confirmable before a confirmable + * message is sent to detect if observers are alive. The maximum allowed value + * here is @c 15. + */ +#define COAP_OBS_MAX_NON 5 +#endif /* COAP_OBS_MAX_NON */ + +#ifndef COAP_OBS_MAX_FAIL +/** + * Number of confirmable notifications that may fail (i.e. time out without + * being ACKed) before an observer is removed. The maximum value for + * COAP_OBS_MAX_FAIL is @c 3. + */ +#define COAP_OBS_MAX_FAIL 3 +#endif /* COAP_OBS_MAX_FAIL */ + +/** Subscriber information */ +typedef struct coap_subscription_t { + struct coap_subscription_t *next; /**< next element in linked list */ + coap_session_t *session; /**< subscriber session */ + + unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */ + unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */ + unsigned int dirty:1; /**< set if the notification temporarily could not be + * sent (in that case, the resource's partially + * dirty flag is set too) */ + unsigned int has_block2:1; /**< GET request had Block2 definition */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + coap_block_t block2; /**< GET request Block2 definition */ + size_t token_length; /**< actual length of token */ + unsigned char token[8]; /**< token used for subscription */ + coap_string_t *query; /**< query string used for subscription, if any */ +} coap_subscription_t; + +void coap_subscription_init(coap_subscription_t *); + +/** @} */ + +#endif /* COAP_SUBSCRIBE_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/uri.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/uri.h new file mode 100644 index 00000000000..4d1670115eb --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/uri.h @@ -0,0 +1,147 @@ +/* + * uri.h -- helper functions for URI treatment + * + * Copyright (C) 2010-2011,2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_URI_H_ +#define COAP_URI_H_ + +#include + +#include "str.h" +struct coap_pdu_t; + +/** + * The scheme specifiers. Secure schemes have an odd numeric value, + * others are even. + */ +enum coap_uri_scheme_t { + COAP_URI_SCHEME_COAP=0, + COAP_URI_SCHEME_COAPS=1, + COAP_URI_SCHEME_COAP_TCP=2, + COAP_URI_SCHEME_COAPS_TCP=3 +}; + +/** This mask can be used to check if a parsed URI scheme is secure. */ +#define COAP_URI_SCHEME_SECURE_MASK 0x01 + +/** + * Representation of parsed URI. Components may be filled from a string with + * coap_split_uri() and can be used as input for option-creation functions. + */ +typedef struct { + coap_str_const_t host; /**< host part of the URI */ + uint16_t port; /**< The port in host byte order */ + coap_str_const_t path; /**< Beginning of the first path segment. + Use coap_split_path() to create Uri-Path options */ + coap_str_const_t query; /**< The query part if present */ + + /** The parsed scheme specifier. */ + enum coap_uri_scheme_t scheme; +} coap_uri_t; + +static inline int +coap_uri_scheme_is_secure(const coap_uri_t *uri) { + return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0); +} + +/** + * Creates a new coap_uri_t object from the specified URI. Returns the new + * object or NULL on error. The memory allocated by the new coap_uri_t + * must be released using coap_free(). + * + * @param uri The URI path to copy. + * @param length The length of uri. + * + * @return New URI object or NULL on error. + */ +coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length); + +/** + * Clones the specified coap_uri_t object. Thie function allocates sufficient + * memory to hold the coap_uri_t structure and its contents. The object must + * be released with coap_free(). */ +coap_uri_t *coap_clone_uri(const coap_uri_t *uri); + +/** + * @defgroup uri_parse URI Parsing Functions + * + * CoAP PDUs contain normalized URIs with their path and query split into + * multiple segments. The functions in this module help splitting strings. + * @{ + */ + +/** + * Parses a given string into URI components. The identified syntactic + * components are stored in the result parameter @p uri. Optional URI + * components that are not specified will be set to { 0, 0 }, except for the + * port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if + * parsing succeeded, a value less than zero otherwise. + * + * @param str_var The string to split up. + * @param len The actual length of @p str_var + * @param uri The coap_uri_t object to store the result. + * @return @c 0 on success, or < 0 on error. + * + */ +int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); + +/** + * Splits the given URI path into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective segment after percent-decoding. + * + * @param s The path string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + */ +int coap_split_path(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Splits the given URI query into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective query term. + * + * @param s The query string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + * + * @bug This function does not reserve additional space for delta > 12. + */ +int coap_split_query(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Extract query string from request PDU according to escape rules in 6.5.8. + * @param request Request PDU. + * @return Reconstructed and escaped query string part. + */ +coap_string_t *coap_get_query(const struct coap_pdu_t *request); + +/** + * Extract uri_path string from request PDU + * @param request Request PDU. + * @return Reconstructed and escaped uri path string part. + */ +coap_string_t *coap_get_uri_path(const struct coap_pdu_t *request); + +/** @} */ + +#endif /* COAP_URI_H_ */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/uthash.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/uthash.h new file mode 100644 index 00000000000..156eb8210c1 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/uthash.h @@ -0,0 +1,1108 @@ +/* +Copyright (c) 2003-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.0.2 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_memcmp +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + if (!(head)->hh.tbl->buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (const void *) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE"); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + default: ; /* does not happen */ \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch ((keylen) & 3U) { \ + case 0: break; \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / (tbl)->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], _dst_hh); \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + const void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap2/utlist.h b/tools/sdk/esp32/include/coap/libcoap/include/coap2/utlist.h new file mode 100644 index 00000000000..2f4c08406f4 --- /dev/null +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap2/utlist.h @@ -0,0 +1,1073 @@ +/* +Copyright (c) 2007-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 2.0.2 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define IF_NO_DECLTYPE(x) x +#define LDECLTYPE(x) char* +#define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) +#define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define UTLIST_PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define IF_NO_DECLTYPE(x) +#define UTLIST_SV(elt,list) +#define UTLIST_NEXT(elt,list,next) ((elt)->next) +#define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define UTLIST_PREV(elt,list,prev) ((elt)->prev) */ +#define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define UTLIST_RS(list) +#define UTLIST_CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if ((_ls_qsize == 0) || (!_ls_q)) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev, _ls_tail); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + UTLIST_CASTASGN(_ls_oldhead,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); \ + if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = UTLIST_NEXT(_ls_q,list,next); \ + } \ + UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev,_ls_tail); \ + UTLIST_CASTASGN(_tmp,list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = (head); \ + (head) = (add); \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = (head1); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = (head); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_INSERT_INORDER(head,add,cmp) \ + LL_INSERT_INORDER2(head,add,cmp,next) + +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + LL_LOWER_BOUND(head, _tmp, add, cmp); \ + LL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define LL_LOWER_BOUND(head,elt,like,cmp) \ + LL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ + do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if (cmp((elt)->next, like) >= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (del)->next; \ + } \ + } \ +} while (0) + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + LL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_REPLACE_ELEM(head, el, add) \ + LL_REPLACE_ELEM2(head, el, add, next) + +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_PREPEND_ELEM(head, el, add) \ + LL_PREPEND_ELEM2(head, el, add, next) + +#define LL_APPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (el)->next = (add); \ + } else { \ + LL_PREPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_APPEND_ELEM(head, el, add) \ + LL_APPEND_ELEM2(head, el, add, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef LL_CONCAT2 +#define LL_CONCAT2(head1,head2,next) \ +do { \ + char *_tmp; \ + if (head1) { \ + _tmp = (char*)(head1); \ + while ((head1)->next) { (head1) = (head1)->next; } \ + (head1)->next = (head2); \ + UTLIST_RS(head1); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#undef LL_APPEND2 +#define LL_APPEND2(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#undef LL_INSERT_INORDER2 +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, add)) >= 0) { \ + (add)->next = (head); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_DELETE2 +#define LL_DELETE2(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + (head) = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_REPLACE_ELEM2 +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = head; \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el)->next; \ +} while (0) + +#undef LL_PREPEND_ELEM2 +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = (head); \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el); \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = (head); \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_INSERT_INORDER(head,add,cmp) \ + DL_INSERT_INORDER2(head,add,cmp,next) + +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + DL_LOWER_BOUND(head, _tmp, add, cmp); \ + DL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_LOWER_BOUND(head,elt,like,cmp) \ + DL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + UTLIST_CASTASGN(_tmp, (head2)->prev); \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + UTLIST_CASTASGN((head1)->prev, _tmp); \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((head) != NULL); \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + DL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_REPLACE_ELEM(head, el, add) \ + DL_REPLACE_ELEM2(head, el, add, prev, next) + +#define DL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ + } else { \ + DL_APPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_PREPEND_ELEM(head, el, add) \ + DL_PREPEND_ELEM2(head, el, add, prev, next) + +#define DL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } else { \ + DL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_APPEND_ELEM(head, el, add) \ + DL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef DL_INSERT_INORDER2 +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = NULL; \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_APPEND(head,add) \ + CDL_APPEND2(head,add,prev,next) + +#define CDL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } \ +} while (0) + +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define CDL_INSERT_INORDER(head,add,cmp) \ + CDL_INSERT_INORDER2(head,add,cmp,next) + +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + CDL_LOWER_BOUND(head, _tmp, add, cmp); \ + CDL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = (head); \ + (head)->prev = (head); \ + } \ +} while (0) + +#define CDL_LOWER_BOUND(head,elt,like,cmp) \ + CDL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if (((head)==(del)) && ((head)->next == (head))) { \ + (head) = NULL; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +do { \ + (counter) = 0; \ + CDL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ + (el) && ((tmp2) = (el)->next, 1); \ + (el) = ((el) == (tmp1) ? NULL : (tmp2))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM(head, el, add) \ + CDL_REPLACE_ELEM2(head, el, add, prev, next) + +#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } else { \ + CDL_APPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ + CDL_PREPEND_ELEM2(head, el, add, prev, next) + +#define CDL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + (add)->next->prev = (add); \ + } else { \ + CDL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_APPEND_ELEM(head, el, add) \ + CDL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef CDL_INSERT_INORDER2 +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (add)->prev->next = (add); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (add)->next->prev = (add); \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +#endif /* UTLIST_H */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_block_internal.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_block_internal.h index 9abe81557fa..b7ad0a554cc 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_block_internal.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_block_internal.h @@ -191,6 +191,9 @@ int coap_handle_response_get_block(coap_context_t *context, void coap_block_delete_lg_xmit(coap_session_t *session, coap_lg_xmit_t *lg_xmit); +coap_tick_t coap_block_check_lg_xmit_timeouts(coap_session_t *session, + coap_tick_t now); + /** * The function that does all the work for the coap_add_data_large*() * functions. diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_dtls.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_dtls.h index cbd369dfce6..fc30445431d 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_dtls.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_dtls.h @@ -27,6 +27,12 @@ typedef struct coap_dtls_pki_t coap_dtls_pki_t; #ifndef COAP_DTLS_HINT_LENGTH #define COAP_DTLS_HINT_LENGTH 128 #endif +#ifndef COAP_DTLS_MAX_PSK_IDENTITY +#define COAP_DTLS_MAX_PSK_IDENTITY 64 +#endif +#ifndef COAP_DTLS_MAX_PSK +#define COAP_DTLS_MAX_PSK 64 +#endif typedef enum coap_dtls_role_t { COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_event.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_event.h index 89b2a63967c..b6ea60524a2 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_event.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_event.h @@ -24,34 +24,34 @@ * Scalar type to represent different events, e.g. DTLS events or * retransmission timeouts. */ - typedef unsigned int coap_event_t; - +typedef enum coap_event_t { /** * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS */ -#define COAP_EVENT_DTLS_CLOSED 0x0000 -#define COAP_EVENT_DTLS_CONNECTED 0x01DE -#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF -#define COAP_EVENT_DTLS_ERROR 0x0200 + COAP_EVENT_DTLS_CLOSED = 0x0000, + COAP_EVENT_DTLS_CONNECTED = 0x01DE, + COAP_EVENT_DTLS_RENEGOTIATE = 0x01DF, + COAP_EVENT_DTLS_ERROR = 0x0200, /** * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS */ -#define COAP_EVENT_TCP_CONNECTED 0x1001 -#define COAP_EVENT_TCP_CLOSED 0x1002 -#define COAP_EVENT_TCP_FAILED 0x1003 + COAP_EVENT_TCP_CONNECTED = 0x1001, + COAP_EVENT_TCP_CLOSED = 0x1002, + COAP_EVENT_TCP_FAILED = 0x1003, /** * CSM exchange events for reliable protocols only */ -#define COAP_EVENT_SESSION_CONNECTED 0x2001 -#define COAP_EVENT_SESSION_CLOSED 0x2002 -#define COAP_EVENT_SESSION_FAILED 0x2003 + COAP_EVENT_SESSION_CONNECTED = 0x2001, + COAP_EVENT_SESSION_CLOSED = 0x2002, + COAP_EVENT_SESSION_FAILED = 0x2003, /** - * BLOCK2 receive errors + * (Q-)BLOCK receive errors */ -#define COAP_EVENT_PARTIAL_BLOCK 0x3001 + COAP_EVENT_PARTIAL_BLOCK = 0x3001 +} coap_event_t; /** * Type for event handler functions that can be registered with a CoAP diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_time.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_time.h index baa8650eaff..99d117a4eb7 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_time.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/coap_time.h @@ -88,7 +88,11 @@ COAP_STATIC_INLINE uint64_t coap_ticks_to_rt_us(coap_tick_t t) { #elif defined(RIOT_VERSION) #include +#ifdef XTIMER_HZ #define COAP_TICKS_PER_SECOND (XTIMER_HZ) +#else /* XTIMER_HZ */ +#define COAP_TICKS_PER_SECOND (XTIMER_HZ_BASE) +#endif /* XTIMER_HZ */ typedef uint64_t coap_tick_t; typedef int64_t coap_tick_diff_t; diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/net.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/net.h index 577a0b5d5a5..ea5a2cba1bb 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/net.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/net.h @@ -15,6 +15,7 @@ #include #include #ifndef _WIN32 +#include #include #endif #include diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/pdu.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/pdu.h index a22869b69ed..8031a1c2c40 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/pdu.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/pdu.h @@ -299,7 +299,6 @@ typedef enum coap_pdu_code_t { COAP_REQUEST_CODE_PATCH = COAP_REQUEST_PATCH, COAP_REQUEST_CODE_IPATCH = COAP_REQUEST_IPATCH, - COAP_RESPONSE_CODE_OK = COAP_RESPONSE_CODE(200), COAP_RESPONSE_CODE_CREATED = COAP_RESPONSE_CODE(201), COAP_RESPONSE_CODE_DELETED = COAP_RESPONSE_CODE(202), COAP_RESPONSE_CODE_VALID = COAP_RESPONSE_CODE(203), diff --git a/tools/sdk/esp32/include/coap/libcoap/include/coap3/resource.h b/tools/sdk/esp32/include/coap/libcoap/include/coap3/resource.h index 2cd9aea48fa..5cf7751f67e 100644 --- a/tools/sdk/esp32/include/coap/libcoap/include/coap3/resource.h +++ b/tools/sdk/esp32/include/coap/libcoap/include/coap3/resource.h @@ -83,7 +83,8 @@ typedef void (*coap_method_handler_t) * variable of coap_str_const_t has to point to constant text, or point to data * within the allocated coap_str_const_t parameter. * - * @param uri_path The string URI path of the new resource. + * @param uri_path The string URI path of the new resource. The leading '/' is + * not normally required - e.g. just "full/path/for/resource". * @param flags Flags for memory management (in particular release of * memory). Possible values:@n * diff --git a/tools/sdk/esp32/include/coap/port/include/coap/coap.h b/tools/sdk/esp32/include/coap/port/include/coap/coap.h new file mode 100644 index 00000000000..f048ca85714 --- /dev/null +++ b/tools/sdk/esp32/include/coap/port/include/coap/coap.h @@ -0,0 +1,50 @@ +/* Modify head file implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * define operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_H_ +#define _COAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libcoap.h" + +#include "address.h" +#include "async.h" +#include "bits.h" +#include "block.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_io.h" +#include "coap_time.h" +#include "coap_debug.h" +#include "encode.h" +#include "mem.h" +#include "net.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "resource.h" +#include "str.h" +#include "subscribe.h" +#include "uri.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COAP_H_ */ diff --git a/tools/sdk/esp32/include/coap/port/include/coap/coap_dtls.h b/tools/sdk/esp32/include/coap/port/include/coap/coap_dtls.h new file mode 100644 index 00000000000..2dd0e88d2e5 --- /dev/null +++ b/tools/sdk/esp32/include/coap/port/include/coap/coap_dtls.h @@ -0,0 +1,631 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" +#include "str.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +typedef enum coap_tls_library_t { + COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */ + COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */ + COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */ + COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */ + COAP_TLS_LIBRARY_MBEDTLS, /**< Using MbedTLS library */ +} coap_tls_library_t; + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ + COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI PEM buffer definitions. + */ +typedef struct coap_pki_key_pem_buf_t { + const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */ + const uint8_t *public_cert; /**< PEM buffer Public Cert */ + const uint8_t *private_key; /**< PEM buffer Private Key */ + size_t ca_cert_len; /**< PEM buffer CA Cert length */ + size_t public_cert_len; /**< PEM buffer Public Cert length */ + size_t private_key_len; /**< PEM buffer Private Key length */ +} coap_pki_key_pem_buf_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM file keys */ + coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) file keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t allow_bad_md_hash; /**< 1 if expired certs are allowed */ + uint8_t allow_short_rsa_length; /**< 1 if expired certs are allowed */ + uint8_t reserved[4]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 4 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32/include/config/sdkconfig.h b/tools/sdk/esp32/include/config/sdkconfig.h index b57d1022057..51fa42b7a07 100644 --- a/tools/sdk/esp32/include/config/sdkconfig.h +++ b/tools/sdk/esp32/include/config/sdkconfig.h @@ -26,6 +26,7 @@ #define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1 #define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 #define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1 +#define CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR 1 #define CONFIG_ESPTOOLPY_FLASHMODE "dio" #define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1 #define CONFIG_ESPTOOLPY_FLASHFREQ "40m" @@ -75,7 +76,7 @@ #define CONFIG_ARDUHAL_ESP_LOG 1 #define CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT 1 #define CONFIG_ARDUHAL_PARTITION_SCHEME "default" -#define CONFIG_COMPILER_OPTIMIZATION_PERF 1 +#define CONFIG_COMPILER_OPTIMIZATION_SIZE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL 2 #define CONFIG_COMPILER_HIDE_PATHS_MACROS 1 @@ -168,8 +169,9 @@ #define CONFIG_SPIRAM_SPEED_40M 1 #define CONFIG_SPIRAM 1 #define CONFIG_SPIRAM_USE_MALLOC 1 -#define CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL 16384 -#define CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL 32768 +#define CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL 8192 +#define CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP 1 +#define CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL 0 #define CONFIG_SPIRAM_CACHE_WORKAROUND 1 #define CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW 1 #define CONFIG_SPIRAM_CACHE_LIBJMP_IN_IRAM 1 @@ -358,7 +360,7 @@ #define CONFIG_LWIP_LOCAL_HOSTNAME "espressif" #define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1 #define CONFIG_LWIP_TIMERS_ONDEMAND 1 -#define CONFIG_LWIP_MAX_SOCKETS 10 +#define CONFIG_LWIP_MAX_SOCKETS 16 #define CONFIG_LWIP_SO_REUSE 1 #define CONFIG_LWIP_SO_REUSE_RXTOALL 1 #define CONFIG_LWIP_SO_RCVBUF 1 @@ -369,6 +371,7 @@ #define CONFIG_LWIP_GARP_TMR_INTERVAL 60 #define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 #define CONFIG_LWIP_DHCP_RESTORE_LAST_IP 1 +#define CONFIG_LWIP_DHCP_OPTIONS_LEN 68 #define CONFIG_LWIP_DHCPS 1 #define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 #define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 @@ -396,14 +399,8 @@ #define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 2560 #define CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 1 #define CONFIG_LWIP_TCPIP_TASK_AFFINITY 0x0 -#define CONFIG_LWIP_PPP_SUPPORT 1 -#define CONFIG_LWIP_PPP_ENABLE_IPV6 1 #define CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE 3 #define CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS 5 -#define CONFIG_LWIP_PPP_PAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_CHAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_MSCHAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_MPPE_SUPPORT 1 #define CONFIG_LWIP_ICMP 1 #define CONFIG_LWIP_MAX_RAW_PCBS 16 #define CONFIG_LWIP_SNTP_MAX_SERVERS 1 @@ -480,6 +477,7 @@ #define CONFIG_MDNS_TASK_AFFINITY 0x0 #define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 2000 #define CONFIG_MDNS_TIMER_PERIOD_MS 100 +#define CONFIG_MDNS_MULTIPLE_INSTANCE 1 #define CONFIG_MQTT_PROTOCOL_311 1 #define CONFIG_MQTT_TRANSPORT_SSL 1 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 @@ -586,6 +584,7 @@ #define CONFIG_BTDM_CONTROLLER_MODE_BTDM CONFIG_BTDM_CTRL_MODE_BTDM #define CONFIG_BTU_TASK_STACK_SIZE CONFIG_BT_BTU_TASK_STACK_SIZE #define CONFIG_CLASSIC_BT_ENABLED CONFIG_BT_CLASSIC_ENABLED +#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT #define CONFIG_CXX_EXCEPTIONS CONFIG_COMPILER_CXX_EXCEPTIONS #define CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE @@ -631,13 +630,9 @@ #define CONFIG_MB_TIMER_PORT_ENABLED CONFIG_FMB_TIMER_PORT_ENABLED #define CONFIG_MONITOR_BAUD_115200B CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B #define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE +#define CONFIG_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR #define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR -#define CONFIG_PPP_CHAP_SUPPORT CONFIG_LWIP_PPP_CHAP_SUPPORT -#define CONFIG_PPP_MPPE_SUPPORT CONFIG_LWIP_PPP_MPPE_SUPPORT -#define CONFIG_PPP_MSCHAP_SUPPORT CONFIG_LWIP_PPP_MSCHAP_SUPPORT -#define CONFIG_PPP_PAP_SUPPORT CONFIG_LWIP_PPP_PAP_SUPPORT -#define CONFIG_PPP_SUPPORT CONFIG_LWIP_PPP_SUPPORT #define CONFIG_REDUCE_PHY_TX_POWER CONFIG_ESP32_REDUCE_PHY_TX_POWER #define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE #define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN @@ -675,5 +670,6 @@ #define CONFIG_ULP_COPROC_ENABLED CONFIG_ESP32_ULP_COPROC_ENABLED #define CONFIG_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM #define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS -#define CONFIG_ARDUINO_IDF_COMMIT "3e370c4296" +#define CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP +#define CONFIG_ARDUINO_IDF_COMMIT "b86fe0c66c" #define CONFIG_ARDUINO_IDF_BRANCH "master" diff --git a/tools/sdk/esp32/include/driver/include/driver/rmt.h b/tools/sdk/esp32/include/driver/include/driver/rmt.h index a7e2aad5f24..bc07954a080 100644 --- a/tools/sdk/esp32/include/driver/include/driver/rmt.h +++ b/tools/sdk/esp32/include/driver/include/driver/rmt.h @@ -856,16 +856,35 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT /** - * @brief Set loop count for RMT TX channel + * @brief Set loop count threshold value for RMT TX channel + * + * When tx loop count reaches this value, an ISR callback will notify user * * @param channel RMT channel - * @param count loop count + * @param count loop count, 1 ~ 1023 * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count); -#endif + +/** + * @brief Enable or disable the feature that when loop count reaches the threshold, RMT will stop transmitting. + * + * - When the loop auto-stop feature is enabled will halt RMT transmission after the loop count reaches a certain threshold + * - When disabled, the RMT transmission continue indefinitely until halted by the users + * + * @note The auto-stop feature is implemented in hardware on particular targets (i.e. those with SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP defined). + * Otherwise, the auto-stop feature is implemented in software via the interrupt. + * + * @param channel RMT channel + * @param en enable bit + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + */ +esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en); +#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT /** * @brief Reset RMT TX/RX memory index. diff --git a/tools/sdk/esp32/include/esp-face/face_detection/include/fd_forward.h b/tools/sdk/esp32/include/esp-face/face_detection/include/fd_forward.h new file mode 100644 index 00000000000..878c8c481c8 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/face_detection/include/fd_forward.h @@ -0,0 +1,103 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "mtmn.h" + + typedef enum + { + FAST = 0, /*!< fast resize type */ + NORMAL = 1, /*!< normal resize type */ + } mtmn_resize_type; + + typedef struct + { + float score; /*!< score threshold for filter candidates by score */ + float nms; /*!< nms threshold for nms process */ + int candidate_number; /*!< candidate number limitation for each net */ + } threshold_config_t; + + typedef struct + { + int w; /*!< net width */ + int h; /*!< net height */ + threshold_config_t threshold; /*!< threshold of net */ + } net_config_t; + + typedef struct + { + float min_face; /*!< The minimum size of a detectable face */ + float pyramid; /*!< The scale of the gradient scaling for the input images */ + int pyramid_times; /*!< The pyramid resizing times */ + threshold_config_t p_threshold; /*!< The thresholds for P-Net. For details, see the definition of threshold_config_t */ + threshold_config_t r_threshold; /*!< The thresholds for R-Net. For details, see the definition of threshold_config_t */ + threshold_config_t o_threshold; /*!< The thresholds for O-Net. For details, see the definition of threshold_config_t */ + mtmn_resize_type type; /*!< The image resize type. 'pyramid' will lose efficacy, when 'type'==FAST. */ + } mtmn_config_t; + + /** + * @brief Get the initial MTMN model configuration + * + * @return mtmn_config_t MTMN configuration + */ + static inline mtmn_config_t mtmn_init_config() + { + mtmn_config_t mtmn_config; + mtmn_config.type = FAST; + mtmn_config.min_face = 80; + mtmn_config.pyramid = 0.707; + mtmn_config.pyramid_times = 4; + mtmn_config.p_threshold.score = 0.6; + mtmn_config.p_threshold.nms = 0.7; + mtmn_config.p_threshold.candidate_number = 20; + mtmn_config.r_threshold.score = 0.7; + mtmn_config.r_threshold.nms = 0.7; + mtmn_config.r_threshold.candidate_number = 10; + mtmn_config.o_threshold.score = 0.7; + mtmn_config.o_threshold.nms = 0.7; + mtmn_config.o_threshold.candidate_number = 1; + + return mtmn_config; + } + + /** + * @brief Do MTMN face detection, return box and landmark infomation. + * + * @param image_matrix Image matrix, rgb888 format + * @param config Configuration of MTMN i.e. score threshold, nms threshold, candidate number threshold, pyramid, min face size + * @return box_array_t* A list of boxes and score. + */ + box_array_t *face_detect(dl_matrix3du_t *image_matrix, + mtmn_config_t *config); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_flash.h b/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_flash.h new file mode 100644 index 00000000000..5da0ddcc182 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_flash.h @@ -0,0 +1,82 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "fr_forward.h" + +#define FR_FLASH_TYPE 32 +#define FR_FLASH_SUBTYPE 32 +#define FR_FLASH_PARTITION_NAME "fr" +#define FR_FLASH_INFO_FLAG 12138 + + /** + * @brief Produce face id according to the input aligned face, and save it to dest_id and flash. + * + * @param l Face id list + * @param aligned_face An aligned face + * @return -2 Flash partition not found + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face_id_to_flash(face_id_list *l, + dl_matrix3du_t *aligned_face); + + /** + * @brief Produce face id according to the input aligned face, and save the id-name pairs to dest_id and flash. + * + * @param l Face id list + * @param new_id An aligned face + * @param name name corresponding to face id + * @return -2 Flash partition not found + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face_id_to_flash_with_name(face_id_name_list *l, + dl_matrix3d_t *new_id, + char *name); + /** + * @brief Read the enrolled face IDs from the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t read_face_id_from_flash(face_id_list *l); + + /** + * @brief Read the enrolled face IDs and their corresponding names from the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t read_face_id_from_flash_with_name(face_id_name_list *l); + + /** + * @brief Delete the enrolled face IDs in the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t delete_face_id_in_flash(face_id_list *l); + + /** + * @brief Delete the enrolled face ID corresponding to the name in the flash. + * + * @param l Face id list + * @param name The name that needs to be deleted + * @return int8_t The number of IDs remaining in flash + */ + int8_t delete_face_id_in_flash_with_name(face_id_name_list *l, char *name); + + /** + * @brief Delete all the enrolled face IDs and names paris in the flash. + * + * @param l Face id list + */ + void delete_face_all_in_flash_with_name(face_id_name_list *l); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_forward.h b/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_forward.h new file mode 100644 index 00000000000..32c55168eb6 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/face_recognition/include/fr_forward.h @@ -0,0 +1,194 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "frmn.h" + +#define FACE_WIDTH 56 +#define FACE_HEIGHT 56 +#define FACE_ID_SIZE 512 +#define FACE_REC_THRESHOLD 0.55 + +#define LEFT_EYE_X 0 +#define LEFT_EYE_Y 1 +#define RIGHT_EYE_X 6 +#define RIGHT_EYE_Y 7 +#define NOSE_X 4 +#define NOSE_Y 5 +#define LEFT_MOUTH_X 2 +#define LEFT_MOUTH_Y 3 +#define RIGHT_MOUTH_X 8 +#define RIGHT_MOUTH_Y 9 + +#define EYE_DIST_SET 16.5f +#define NOSE_EYE_RATIO_THRES_MIN 0.49f +#define NOSE_EYE_RATIO_THRES_MAX 2.04f + + +#define ENROLL_NAME_LEN 16 + typedef struct tag_face_id_node + { + struct tag_face_id_node *next; /*!< next face id node */ + char id_name[ENROLL_NAME_LEN]; /*!< name corresponding to the face id */ + dl_matrix3d_t *id_vec; /*!< face id */ + } face_id_node; + + typedef struct + { + face_id_node *head; /*!< head pointer of the id list */ + face_id_node *tail; /*!< tail pointer of the id list */ + uint8_t count; /*!< number of enrolled ids */ + uint8_t confirm_times; /*!< images needed for one enrolling */ + } face_id_name_list; + + typedef struct + { + uint8_t head; /*!< head index of the id list */ + uint8_t tail; /*!< tail index of the id list */ + uint8_t count; /*!< number of enrolled ids */ + uint8_t size; /*!< max len of id list */ + uint8_t confirm_times; /*!< images needed for one enrolling */ + dl_matrix3d_t **id_list; /*!< stores face id vectors */ + } face_id_list; + + /** + * @brief Initialize face id list. + * + * @param l Face id list + * @param size Size of list, one list contains one vector + * @param confirm_times Enroll times for one id + */ + void face_id_init(face_id_list *l, uint8_t size, uint8_t confirm_times); + + /** + * @brief Initialize face id list with name. + * + * @param l Face id list + * @param size Size of list, one list contains one vector + * @param confirm_times Enroll times for one id + */ + void face_id_name_init(face_id_name_list *l, uint8_t size, uint8_t confirm_times); + + /** + * @brief Alloc memory for aligned face. + * + * @return dl_matrix3du_t* Size: 1xFACE_WIDTHxFACE_HEIGHTx3 + */ + dl_matrix3du_t *aligned_face_alloc(); + + /**@{*/ + /** + * @brief Align detected face to average face according to landmark. + * + * @param onet_boxes Output of MTMN with box and landmark + * @param src Image matrix, rgb888 format + * @param dest Output image + * @return ESP_OK Input face is good for recognition + * @return ESP_FAIL Input face is not good for recognition + */ + int8_t align_face_rot(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest); + + int8_t align_face_sim(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest); + + inline int8_t align_face(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest) + { + return align_face_sim(onet_boxes, src, dest); + } + /**@}*/ + + /** + * @brief Run the face recognition model to get the face feature + * + * @param aligned_face A 56x56x3 image, the variable need to do align_face first + * @return face_id A 512 vector, size (1, 1, 1, 512) + */ + dl_matrix3d_t *get_face_id(dl_matrix3du_t *aligned_face); + + /** + * @brief Add src_id to dest_id + * + * @param dest_id Face id after accumulation + * @param src_id Face id to be added + */ + void add_face_id(dl_matrix3d_t *dest_id, + dl_matrix3d_t *src_id); + + /** + * @brief Match face with the id_list, and return matched_id. + * + * @param l An ID list + * @param algined_face An aligned face + * @return int8_t Matched face id + */ + int8_t recognize_face(face_id_list *l, dl_matrix3du_t *algined_face); + + /** + * @brief Match face id with the id_list, and return matched face id node. + * + * @param l + * @param face_id + * @return face_id_node* + */ + face_id_node *recognize_face_with_name(face_id_name_list *l, dl_matrix3d_t *face_id); + + /** + * @brief Produce face id according to the input aligned face, and save it to dest_id. + * + * @param l Face id list + * @param aligned_face An aligned face + * @param enroll_confirm_times Confirm times for each face id enrollment + * @return -1 Wrong input enroll_confirm_times + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face(face_id_list *l, dl_matrix3du_t *aligned_face); + + /** + * @brief Produce face id according to the input aligned face, and save the id-name pairs to dest_id + * + * @param l Face id list with name + * @param new_id A face id that need to be enrolled + * @param name name corresponding to the face id + * @return int8_t The left piece of aligned faces should be input + */ + int8_t enroll_face_with_name(face_id_name_list *l, + dl_matrix3d_t *new_id, + char *name); + + /** + * @brief Delete the enrolled face IDs + * + * @param l Face id list + * @return uint8_t The number of IDs remaining in face id list + */ + uint8_t delete_face(face_id_list *l); + + /** + * @brief Delete the enrolled face IDs and associated names + * + * @param l Face id list + * @param name The name that needs to be deleted + * @return int8_t The number of IDs remaining in face id list + */ + int8_t delete_face_with_name(face_id_name_list *l, char *name); + + /** + * @brief Delete all the enrolled face IDs and names paris + * + * @param l Face id list with names + */ + void delete_face_all_with_name(face_id_name_list *l); +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/image_util/include/esp_image.hpp b/tools/sdk/esp32/include/esp-face/image_util/include/esp_image.hpp new file mode 100644 index 00000000000..f5f924d6b6a --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/image_util/include/esp_image.hpp @@ -0,0 +1,344 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +typedef enum +{ + IMAGE_RESIZE_BILINEAR = 0, /* +class Image +{ +public: + /** + * @brief Convert a RGB565 pixel to RGB888 + * + * @param input Pixel value in RGB565 + * @param output Pixel value in RGB888 + */ + static inline void pixel_rgb565_to_rgb888(uint16_t input, T *output) + { + output[2] = (input & 0x1F00) >> 5; //blue + output[1] = ((input & 0x7) << 5) | ((input & 0xE000) >> 11); //green + output[0] = input & 0xF8; //red + }; + + /** + * @brief Resize a RGB565 image to a RGB88 image + * + * @param dst_image The destination image + * @param y_start The start y index of where resized image located + * @param y_end The end y index of where resized image located + * @param x_start The start x index of where resized image located + * @param x_end The end x index of where resized image located + * @param channel The channel number of image + * @param src_image The source image + * @param src_h The height of source image + * @param src_w The width of source image + * @param dst_w The width of destination image + * @param shift_left The bit number of left shifting + * @param type The resize type + */ + static void resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + + /** + * @brief Resize a RGB888 image to a RGB88 image + * + * @param dst_image The destination image + * @param y_start The start y index of where resized image located + * @param y_end The end y index of where resized image located + * @param x_start The start x index of where resized image located + * @param x_end The end x index of where resized image located + * @param channel The channel number of image + * @param src_image The source image + * @param src_h The height of source image + * @param src_w The width of source image + * @param dst_w The width of destination image + * @param shift_left The bit number of left shifting + * @param type The resize type + */ + static void resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + // static void resize_to_rgb565(uint16_t *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + // static void resize_to_rgb565(uint16_t *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); +}; + +template +void Image::resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type) +{ + assert(channel == 3); + float scale_y = (float)src_h / (y_end - y_start); + float scale_x = (float)src_w / (x_end - x_start); + int temp[13]; + + switch (type) + { + case IMAGE_RESIZE_BILINEAR: + for (size_t y = y_start; y < y_end; y++) + { + float ratio_y[2]; + ratio_y[0] = (float)((y + 0.5) * scale_y - 0.5); // y + int src_y = (int)ratio_y[0]; // y1 + ratio_y[0] -= src_y; // y - y1 + + if (src_y < 0) + { + ratio_y[0] = 0; + src_y = 0; + } + if (src_y > src_h - 2) + { + ratio_y[0] = 0; + src_y = src_h - 2; + } + ratio_y[1] = 1 - ratio_y[0]; // y2 - y + + int _dst_i = y * dst_w; + + int _src_row_0 = src_y * src_w; + int _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + float ratio_x[2]; + ratio_x[0] = (float)((x + 0.5) * scale_x - 0.5); // x + int src_x = (int)ratio_x[0]; // x1 + ratio_x[0] -= src_x; // x - x1 + + if (src_x < 0) + { + ratio_x[0] = 0; + src_x = 0; + } + if (src_x > src_w - 2) + { + ratio_x[0] = 0; + src_x = src_w - 2; + } + ratio_x[1] = 1 - ratio_x[0]; // x2 - x + + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = _src_row_0 + src_x; + int src_row_1 = _src_row_1 + src_x; + + Image::pixel_rgb565_to_rgb888(src_image[src_row_0], temp); + Image::pixel_rgb565_to_rgb888(src_image[src_row_0 + 1], temp + 3); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1], temp + 6); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1 + 1], temp + 9); + + for (int c = 0; c < channel; c++) + { + temp[12] = round(temp[c] * ratio_x[1] * ratio_y[1] + temp[channel + c] * ratio_x[0] * ratio_y[1] + temp[channel + channel + c] * ratio_x[1] * ratio_y[0] + src_image[channel + channel + channel + c] * ratio_x[0] * ratio_y[0]); + dst_image[dst_i + c] = (shift_left > 0) ? (temp[12] << shift_left) : (temp[12] >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_MEAN: + shift_left -= 2; + for (int y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + + float _src_row_0 = rintf(y * scale_y) * src_w; + float _src_row_1 = _src_row_0 + src_w; + + for (int x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + rintf(x * scale_x)); + int src_row_1 = (_src_row_1 + rintf(x * scale_x)); + + Image::pixel_rgb565_to_rgb888(src_image[src_row_0], temp); + Image::pixel_rgb565_to_rgb888(src_image[src_row_0 + 1], temp + 3); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1], temp + 6); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1 + 1], temp + 9); + + dst_image[dst_i] = (shift_left > 0) ? ((temp[0] + temp[3] + temp[6] + temp[9]) << shift_left) : ((temp[0] + temp[3] + temp[6] + temp[9]) >> -shift_left); + dst_image[dst_i + 1] = (shift_left > 0) ? ((temp[1] + temp[4] + temp[7] + temp[10]) << shift_left) : ((temp[1] + temp[4] + temp[7] + temp[10]) >> -shift_left); + dst_image[dst_i + 2] = (shift_left > 0) ? ((temp[2] + temp[5] + temp[8] + temp[11]) << shift_left) : ((temp[1] + temp[4] + temp[7] + temp[10]) >> -shift_left); + } + } + + break; + + case IMAGE_RESIZE_NEAREST: + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + float _src_i = rintf(y * scale_y) * src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + int src_i = _src_i + rintf(x * scale_x); + + Image::pixel_rgb565_to_rgb888(src_image[src_i], temp); + + dst_image[dst_i] = (shift_left > 0) ? (temp[0] << shift_left) : (temp[0] >> -shift_left); + dst_image[dst_i + 1] = (shift_left > 0) ? (temp[1] << shift_left) : (temp[1] >> -shift_left); + dst_image[dst_i + 2] = (shift_left > 0) ? (temp[2] << shift_left) : (temp[2] >> -shift_left); + } + } + break; + + default: + break; + } +} + +template +void Image::resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type) +{ + float scale_y = (float)src_h / (y_end - y_start); + float scale_x = (float)src_w / (x_end - x_start); + int temp; + + switch (type) + { + case IMAGE_RESIZE_BILINEAR: + for (size_t y = y_start; y < y_end; y++) + { + float ratio_y[2]; + ratio_y[0] = (float)((y + 0.5) * scale_y - 0.5); // y + int src_y = (int)ratio_y[0]; // y1 + ratio_y[0] -= src_y; // y - y1 + + if (src_y < 0) + { + ratio_y[0] = 0; + src_y = 0; + } + if (src_y > src_h - 2) + { + ratio_y[0] = 0; + src_y = src_h - 2; + } + ratio_y[1] = 1 - ratio_y[0]; // y2 - y + + int _dst_i = y * dst_w; + + int _src_row_0 = src_y * src_w; + int _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + float ratio_x[2]; + ratio_x[0] = (float)((x + 0.5) * scale_x - 0.5); // x + int src_x = (int)ratio_x[0]; // x1 + ratio_x[0] -= src_x; // x - x1 + + if (src_x < 0) + { + ratio_x[0] = 0; + src_x = 0; + } + if (src_x > src_w - 2) + { + ratio_x[0] = 0; + src_x = src_w - 2; + } + ratio_x[1] = 1 - ratio_x[0]; // x2 - x + + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + src_x) * channel; + int src_row_1 = (_src_row_1 + src_x) * channel; + + for (int c = 0; c < channel; c++) + { + temp = round(src_image[src_row_0 + c] * ratio_x[1] * ratio_y[1] + src_image[src_row_0 + channel + c] * ratio_x[0] * ratio_y[1] + src_image[src_row_1 + c] * ratio_x[1] * ratio_y[0] + src_image[src_row_1 + channel + c] * ratio_x[0] * ratio_y[0]); + dst_image[dst_i + c] = (shift_left > 0) ? (temp << shift_left) : (temp >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_MEAN: + shift_left -= 2; + + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + + float _src_row_0 = rintf(y * scale_y) * src_w; + float _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + rintf(x * scale_x)) * channel; + int src_row_1 = (_src_row_1 + rintf(x * scale_x)) * channel; + + for (size_t c = 0; c < channel; c++) + { + temp = (int)src_image[src_row_0 + c] + (int)src_image[src_row_0 + channel + c] + (int)src_image[src_row_1 + c] + (int)src_image[src_row_1 + channel + c]; + dst_image[dst_i + c] = (shift_left > 0) ? (temp << shift_left) : (temp >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_NEAREST: + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + float _src_i = rintf(y * scale_y) * src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + int src_i = (_src_i + rintf(x * scale_x)) * channel; + + for (size_t c = 0; c < channel; c++) + { + dst_image[dst_i + c] = (shift_left > 0) ? ((T)src_image[src_i + c] << shift_left) : ((T)src_image[src_i + c] >> -shift_left); + } + } + } + break; + + default: + break; + } +} \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/image_util/include/image_util.h b/tools/sdk/esp32/include/esp-face/image_util/include/image_util.h new file mode 100644 index 00000000000..f997b34154b --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/image_util/include/image_util.h @@ -0,0 +1,548 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include +#include "mtmn.h" + +#define LANDMARKS_NUM (10) + +#define MAX_VALID_COUNT_PER_IMAGE (30) + +#define DL_IMAGE_MIN(A, B) ((A) < (B) ? (A) : (B)) +#define DL_IMAGE_MAX(A, B) ((A) < (B) ? (B) : (A)) + +#define RGB565_MASK_RED 0xF800 +#define RGB565_MASK_GREEN 0x07E0 +#define RGB565_MASK_BLUE 0x001F + + typedef enum + { + BINARY, /*!< binary */ + } en_threshold_mode; + + typedef struct + { + fptp_t landmark_p[LANDMARKS_NUM]; /*!< landmark struct */ + } landmark_t; + + typedef struct + { + fptp_t box_p[4]; /*!< box struct */ + } box_t; + + typedef struct tag_box_list + { + uint8_t *category; /*!< The category of the corresponding box */ + fptp_t *score; /*!< The confidence score of the class corresponding to the box */ + box_t *box; /*!< Anchor boxes or predicted boxes*/ + landmark_t *landmark; /*!< The landmarks corresponding to the box */ + int len; /*!< The num of the boxes */ + } box_array_t; + + typedef struct tag_image_box + { + struct tag_image_box *next; /*!< Next image_box_t */ + uint8_t category; + fptp_t score; /*!< The confidence score of the class corresponding to the box */ + box_t box; /*!< Anchor boxes or predicted boxes */ + box_t offset; /*!< The predicted anchor-based offset */ + landmark_t landmark; /*!< The landmarks corresponding to the box */ + } image_box_t; + + typedef struct tag_image_list + { + image_box_t *head; /*!< The current head of the image_list */ + image_box_t *origin_head; /*!< The original head of the image_list */ + int len; /*!< Length of the image_list */ + } image_list_t; + + /** + * @brief Get the width and height of the box. + * + * @param box Input box + * @param w Resulting width of the box + * @param h Resulting height of the box + */ + static inline void image_get_width_and_height(box_t *box, float *w, float *h) + { + *w = box->box_p[2] - box->box_p[0] + 1; + *h = box->box_p[3] - box->box_p[1] + 1; + } + + /** + * @brief Get the area of the box. + * + * @param box Input box + * @param area Resulting area of the box + */ + static inline void image_get_area(box_t *box, float *area) + { + float w, h; + image_get_width_and_height(box, &w, &h); + *area = w * h; + } + + /** + * @brief calibrate the boxes by offset + * + * @param image_list Input boxes + * @param image_height Height of the original image + * @param image_width Width of the original image + */ + static inline void image_calibrate_by_offset(image_list_t *image_list, int image_height, int image_width) + { + for (image_box_t *head = image_list->head; head; head = head->next) + { + float w, h; + image_get_width_and_height(&(head->box), &w, &h); + head->box.box_p[0] = DL_IMAGE_MAX(0, head->box.box_p[0] + head->offset.box_p[0] * w); + head->box.box_p[1] = DL_IMAGE_MAX(0, head->box.box_p[1] + head->offset.box_p[1] * w); + head->box.box_p[2] += head->offset.box_p[2] * w; + if (head->box.box_p[2] > image_width) + { + head->box.box_p[2] = image_width - 1; + head->box.box_p[0] = image_width - w; + } + head->box.box_p[3] += head->offset.box_p[3] * h; + if (head->box.box_p[3] > image_height) + { + head->box.box_p[3] = image_height - 1; + head->box.box_p[1] = image_height - h; + } + } + } + + /** + * @brief calibrate the landmarks + * + * @param image_list Input landmarks + */ + static inline void image_landmark_calibrate(image_list_t *image_list) + { + for (image_box_t *head = image_list->head; head; head = head->next) + { + float w, h; + image_get_width_and_height(&(head->box), &w, &h); + head->landmark.landmark_p[0] = head->box.box_p[0] + head->landmark.landmark_p[0] * w; + head->landmark.landmark_p[1] = head->box.box_p[1] + head->landmark.landmark_p[1] * h; + + head->landmark.landmark_p[2] = head->box.box_p[0] + head->landmark.landmark_p[2] * w; + head->landmark.landmark_p[3] = head->box.box_p[1] + head->landmark.landmark_p[3] * h; + + head->landmark.landmark_p[4] = head->box.box_p[0] + head->landmark.landmark_p[4] * w; + head->landmark.landmark_p[5] = head->box.box_p[1] + head->landmark.landmark_p[5] * h; + + head->landmark.landmark_p[6] = head->box.box_p[0] + head->landmark.landmark_p[6] * w; + head->landmark.landmark_p[7] = head->box.box_p[1] + head->landmark.landmark_p[7] * h; + + head->landmark.landmark_p[8] = head->box.box_p[0] + head->landmark.landmark_p[8] * w; + head->landmark.landmark_p[9] = head->box.box_p[1] + head->landmark.landmark_p[9] * h; + } + } + + /** + * @brief Convert a rectangular box into a square box + * + * @param boxes Input box + * @param width Width of the orignal image + * @param height height of the orignal image + */ + static inline void image_rect2sqr(box_array_t *boxes, int width, int height) + { + for (int i = 0; i < boxes->len; i++) + { + box_t *box = &(boxes->box[i]); + + int x1 = round(box->box_p[0]); + int y1 = round(box->box_p[1]); + int x2 = round(box->box_p[2]); + int y2 = round(box->box_p[3]); + + int w = x2 - x1 + 1; + int h = y2 - y1 + 1; + int l = DL_IMAGE_MAX(w, h); + + box->box_p[0] = DL_IMAGE_MAX(round(DL_IMAGE_MAX(0, x1) + 0.5 * (w - l)), 0); + box->box_p[1] = DL_IMAGE_MAX(round(DL_IMAGE_MAX(0, y1) + 0.5 * (h - l)), 0); + + box->box_p[2] = box->box_p[0] + l - 1; + if (box->box_p[2] > width) + { + box->box_p[2] = width - 1; + box->box_p[0] = width - l; + } + box->box_p[3] = box->box_p[1] + l - 1; + if (box->box_p[3] > height) + { + box->box_p[3] = height - 1; + box->box_p[1] = height - l; + } + } + } + + /**@{*/ + /** + * @brief Convert RGB565 image to RGB888 image + * + * @param in Input RGB565 image + * @param dst Resulting RGB888 image + */ + static inline void rgb565_to_888(uint16_t in, uint8_t *dst) + { /*{{{*/ + in = (in & 0xFF) << 8 | (in & 0xFF00) >> 8; + dst[2] = (in & RGB565_MASK_BLUE) << 3; // blue + dst[1] = (in & RGB565_MASK_GREEN) >> 3; // green + dst[0] = (in & RGB565_MASK_RED) >> 8; // red + + // dst[0] = (in & 0x1F00) >> 5; + // dst[1] = ((in & 0x7) << 5) | ((in & 0xE000) >> 11); + // dst[2] = in & 0xF8; + } /*}}}*/ + + static inline void rgb565_to_888_q16(uint16_t in, int16_t *dst) + { /*{{{*/ + in = (in & 0xFF) << 8 | (in & 0xFF00) >> 8; + dst[2] = (in & RGB565_MASK_BLUE) << 3; // blue + dst[1] = (in & RGB565_MASK_GREEN) >> 3; // green + dst[0] = (in & RGB565_MASK_RED) >> 8; // red + + // dst[0] = (in & 0x1F00) >> 5; + // dst[1] = ((in & 0x7) << 5) | ((in & 0xE000) >> 11); + // dst[2] = in & 0xF8; + } /*}}}*/ + /**@}*/ + + /** + * @brief Convert RGB888 image to RGB565 image + * + * @param in Resulting RGB565 image + * @param r The red channel of the Input RGB888 image + * @param g The green channel of the Input RGB888 image + * @param b The blue channel of the Input RGB888 image + */ + static inline void rgb888_to_565(uint16_t *in, uint8_t r, uint8_t g, uint8_t b) + { /*{{{*/ + uint16_t rgb565 = 0; + rgb565 = ((r >> 3) << 11); + rgb565 |= ((g >> 2) << 5); + rgb565 |= (b >> 3); + rgb565 = (rgb565 & 0xFF) << 8 | (rgb565 & 0xFF00) >> 8; + *in = rgb565; + } /*}}}*/ + + /** + * @brief Filter out the resulting boxes whose confidence score is lower than the threshold and convert the boxes to the actual boxes on the original image.((x, y, w, h) -> (x1, y1, x2, y2)) + * + * @param score Confidence score of the boxes + * @param offset The predicted anchor-based offset + * @param landmark The landmarks corresponding to the box + * @param width Height of the original image + * @param height Width of the original image + * @param anchor_number Anchor number of the detection output feature map + * @param anchors_size The anchor size + * @param score_threshold Threshold of the confidence score + * @param stride + * @param resized_height_scale + * @param resized_width_scale + * @param do_regression + * @return image_list_t* + */ + image_list_t *image_get_valid_boxes(fptp_t *score, + fptp_t *offset, + fptp_t *landmark, + int width, + int height, + int anchor_number, + int *anchors_size, + fptp_t score_threshold, + int stride, + fptp_t resized_height_scale, + fptp_t resized_width_scale, + bool do_regression); + /** + * @brief Sort the resulting box lists by their confidence score. + * + * @param image_sorted_list The sorted box list. + * @param insert_list The box list that have not been sorted. + */ + void image_sort_insert_by_score(image_list_t *image_sorted_list, const image_list_t *insert_list); + + /** + * @brief Run NMS algorithm + * + * @param image_list The input boxes list + * @param nms_threshold NMS threshold + * @param same_area The flag of boxes with same area + */ + void image_nms_process(image_list_t *image_list, fptp_t nms_threshold, int same_area); + + /** + * @brief Resize an image to half size + * + * @param dimage The output image + * @param dw Width of the output image + * @param dh Height of the output image + * @param dc Channel of the output image + * @param simage Source image + * @param sw Width of the source image + * @param sc Channel of the source image + */ + void image_zoom_in_twice(uint8_t *dimage, + int dw, + int dh, + int dc, + uint8_t *simage, + int sw, + int sc); + + /** + * @brief Resize the image in RGB888 format via bilinear interpolation + * + * @param dst_image The output image + * @param src_image Source image + * @param dst_w Width of the output image + * @param dst_h Height of the output image + * @param dst_c Channel of the output image + * @param src_w Width of the source image + * @param src_h Height of the source image + */ + void image_resize_linear(uint8_t *dst_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h); + + /** + * @brief Crop, rotate and zoom the image in RGB888 format, + * + * @param corp_image The output image + * @param src_image Source image + * @param rotate_angle Rotate angle + * @param ratio scaling ratio + * @param center Center of rotation + */ + void image_cropper(uint8_t *corp_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h, float rotate_angle, float ratio, float *center); + + /** + * @brief Convert the rgb565 image to the rgb888 image + * + * @param m The output rgb888 image + * @param bmp The input rgb565 image + * @param count Total pixels of the rgb565 image + */ + void image_rgb565_to_888(uint8_t *m, uint16_t *bmp, int count); + + /** + * @brief Convert the rgb888 image to the rgb565 image + * + * @param bmp The output rgb565 image + * @param m The input rgb888 image + * @param count Total pixels of the rgb565 image + */ + void image_rgb888_to_565(uint16_t *bmp, uint8_t *m, int count); + + /** + * @brief draw rectangle on the rgb565 image + * + * @param buf Input image + * @param boxes Rectangle Boxes + * @param width Width of the input image + */ + void draw_rectangle_rgb565(uint16_t *buf, box_array_t *boxes, int width); + + /** + * @brief draw rectangle on the rgb888 image + * + * @param buf Input image + * @param boxes Rectangle Boxes + * @param width Width of the input image + */ + void draw_rectangle_rgb888(uint8_t *buf, box_array_t *boxes, int width); + + /** + * @brief Get the pixel difference of two images + * + * @param dst The output pixel difference + * @param src1 Input image 1 + * @param src2 Input image 2 + * @param count Total pixels of the input image + */ + void image_abs_diff(uint8_t *dst, uint8_t *src1, uint8_t *src2, int count); + + /** + * @brief Binarize an image to 0 and value. + * + * @param dst The output image + * @param src Source image + * @param threshold Threshold of binarization + * @param value The value of binarization + * @param count Total pixels of the input image + * @param mode Threshold mode + */ + void image_threshold(uint8_t *dst, uint8_t *src, int threshold, int value, int count, en_threshold_mode mode); + + /** + * @brief Erode the image + * + * @param dst The output image + * @param src Source image + * @param src_w Width of the source image + * @param src_h Height of the source image + * @param src_c Channel of the source image + */ + void image_erode(uint8_t *dst, uint8_t *src, int src_w, int src_h, int src_c); + + typedef float matrixType; + typedef struct + { + int w; /*!< width */ + int h; /*!< height */ + matrixType **array; /*!< array */ + } Matrix; + + /** + * @brief Allocate a 2d matrix + * + * @param h Height of matrix + * @param w Width of matrix + * @return Matrix* 2d matrix + */ + Matrix *matrix_alloc(int h, int w); + + /** + * @brief Free a 2d matrix + * + * @param m 2d matrix + */ + void matrix_free(Matrix *m); + + /** + * @brief Get the similarity matrix of similarity transformation + * + * @param srcx Source x coordinates + * @param srcy Source y coordinates + * @param dstx Destination x coordinates + * @param dsty Destination y coordinates + * @param num The number of the coordinates + * @return Matrix* The resulting transformation matrix + */ + Matrix *get_similarity_matrix(float *srcx, float *srcy, float *dstx, float *dsty, int num); + + /** + * @brief Get the affine transformation matrix + * + * @param srcx Source x coordinates + * @param srcy Source y coordinates + * @param dstx Destination x coordinates + * @param dsty Destination y coordinates + * @return Matrix* The resulting transformation matrix + */ + Matrix *get_affine_transform(float *srcx, float *srcy, float *dstx, float *dsty); + + /** + * @brief Applies an affine transformation to an image + * + * @param img Input image + * @param crop Dst output image that has the size dsize and the same type as src + * @param M Affine transformation matrix + */ + void warp_affine(dl_matrix3du_t *img, dl_matrix3du_t *crop, Matrix *M); + + /** + * @brief Resize the image in RGB888 format via bilinear interpolation, and quantify the output image + * + * @param dst_image Quantized output image + * @param src_image Input image + * @param dst_w Width of the output image + * @param dst_h Height of the output image + * @param dst_c Channel of the output image + * @param src_w Width of the input image + * @param src_h Height of the input image + * @param shift Shift parameter of quantization. + */ + void image_resize_linear_q(qtp_t *dst_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h, int shift); + + /** + * @brief Preprocess the input image of object detection model. The process is like this: resize -> normalize -> quantify + * + * @param image Input image, RGB888 format. + * @param input_w Width of the input image. + * @param input_h Height of the input image. + * @param target_size Target size of the model input image. + * @param exponent Exponent of the quantized model input image. + * @param process_mode Process mode. 0: resize with padding to keep height == width. 1: resize without padding, height != width. + * @return dl_matrix3dq_t* The resulting preprocessed image. + */ + dl_matrix3dq_t *image_resize_normalize_quantize(uint8_t *image, int input_w, int input_h, int target_size, int exponent, int process_mode); + + /** + * @brief Resize the image in RGB565 format via mean neighbour interpolation, and quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Width of the allocated output image memory. + * @param dc Channel of the allocated output image memory. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param tw Target width of the output image. + * @param th Target height of the output image. + * @param shift Shift parameter of quantization. + */ + void image_resize_shift_fast(qtp_t *dimage, uint16_t *simage, int dw, int dc, int sw, int sh, int tw, int th, int shift); + + /** + * @brief Resize the image in RGB565 format via nearest neighbour interpolation, and quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Width of the allocated output image memory. + * @param dc Channel of the allocated output image memory. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param tw Target width of the output image. + * @param th Target height of the output image. + * @param shift Shift parameter of quantization. + */ + void image_resize_nearest_shift(qtp_t *dimage, uint16_t *simage, int dw, int dc, int sw, int sh, int tw, int th, int shift); + + /** + * @brief Crop the image in RGB565 format and resize it to target size, then quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Target size of the output image. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param x1 The x coordinate of the upper left corner of the cropped area + * @param y1 The y coordinate of the upper left corner of the cropped area + * @param x2 The x coordinate of the lower right corner of the cropped area + * @param y2 The y coordinate of the lower right corner of the cropped area + * @param shift Shift parameter of quantization. + */ + void image_crop_shift_fast(qtp_t *dimage, uint16_t *simage, int dw, int sw, int sh, int x1, int y1, int x2, int y2, int shift); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/include/dl_define.hpp b/tools/sdk/esp32/include/esp-face/include/dl_define.hpp index 16eb0881562..7809768a5bc 100644 --- a/tools/sdk/esp32/include/esp-face/include/dl_define.hpp +++ b/tools/sdk/esp32/include/esp-face/include/dl_define.hpp @@ -10,7 +10,7 @@ #define DL_LOG_LAYER_LATENCY 0 /**/ - PADDING_SAME, /**/ - PADDING_SAME_MXNET /**/ + PADDING_NOT_SET, + PADDING_VALID, /**/ + PADDING_SAME_BEGIN, /**/ + PADDING_SAME_END, /**/ } padding_type_t; -} // namespace dl \ No newline at end of file + + typedef enum + { + CONSTANT, + EDGE, + REFLECT, + SYMMETRIC, + } padding_mode_t; +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/image/dl_image.hpp b/tools/sdk/esp32/include/esp-face/include/image/dl_image.hpp index c7fecdc49cc..4a974df063a 100644 --- a/tools/sdk/esp32/include/esp-face/include/image/dl_image.hpp +++ b/tools/sdk/esp32/include/esp-face/include/image/dl_image.hpp @@ -370,11 +370,70 @@ namespace dl */ uint32_t get_moving_point_number(uint8_t *f1, uint8_t *f2, const uint32_t height, const uint32_t width, const uint32_t stride, const uint32_t threshold = 5); - + /** + * @brief Apply an affine transformation to an image. + * + * @tparam T + * @param input the input image. + * @param output the output image. + * @param M_inv the inverse transformation matrix. + */ template void warp_affine(dl::Tensor *input, dl::Tensor *output, dl::math::Matrix *M_inv); + + /** + * @brief Apply an affine transformation to an image. + * + * @tparam T + * @param input the pointer of the input image. + * @param shape the shape of the input image. + * @param output the output image. + * @param M_inv the inverse transformation matrix. + */ template void warp_affine(uint16_t *input, std::vector shape, dl::Tensor *output, dl::math::Matrix *M_inv); + /** + * @brief Get the otsu thresh object. + * + * @param image the gray image. + * @return uint8_t the otsu thresh. + */ + uint8_t get_otsu_thresh(Tensor &image); + + /** + * @brief Convert RGB image to gray image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @return Tensor* output image in gray format + */ + Tensor *rgb2gray(Tensor &image, bool bgr = false); + + /** + * @brief Convert RGB image to LAB image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @param fast true: use the fast alogrithm, but the accuracy will be reduced + * false: do not use the fast alogrithm + * @return Tensor* output image in LAB foramt + */ + Tensor *rgb2lab(Tensor &image, bool bgr = false, bool fast = true); + + /** + * @brief Convert RGB image to HSV image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @param fast true: use the fast alogrithm, but the accuracy will be reduced + * false: do not use the fast alogrithm + * @return Tensor* output image in HSV format + */ + Tensor *rgb2hsv(Tensor &image, bool bgr = false, bool fast = true); + } // namespace image } // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_add2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_add2d.hpp index f0c5964b3d1..c43282b42de 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_add2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_add2d.hpp @@ -25,7 +25,8 @@ namespace dl const int output_exponent; /**/ Tensor *output; /**/ bool inplace; /**/ + false: the output will store to a separate memory >*/ + std::vector output_shape; /**/ public: /** @@ -35,19 +36,21 @@ namespace dl * @param activation activation of add2d, if you don't specify anything, no activation is applied * @param name name of add2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Add2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), activation(activation), output_exponent(output_exponent), output(NULL) - { - this->inplace = inplace; - } + Add2D(const int output_exponent, const Activation *activation = NULL, const char *name = "Add2D", bool inplace = false) : Layer(name), + activation(activation), + output_exponent(output_exponent), + output(NULL), + inplace(inplace), + output_shape({}) {} /** * @brief Destroy the Add2D object */ ~Add2D() { - if((!this->inplace) && (this->output != NULL)) + if ((!this->inplace) && (this->output != NULL)) { delete this->output; } @@ -59,10 +62,12 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { @@ -78,6 +83,11 @@ namespace dl { this->output = &input0; } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -105,7 +115,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -116,6 +130,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::add2d(*this->output, input0, input1, this->activation, assign_core, this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "add2d"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp index f78b262beb9..8a9aaa8dfbe 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp @@ -24,23 +24,26 @@ namespace dl std::vector filter_shape; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ + const padding_type_t padding_type; /**/ std::vector padding; /**/ - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new AvgPool2D object. * * @param output_exponent exponent of output * @param filter_shape filter shape in [filter_height, filter_width] - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer @@ -48,16 +51,23 @@ namespace dl AvgPool2D(const int output_exponent, const std::vector filter_shape, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter_shape(filter_shape), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type) + const char *name = "AvgPool2D") : Layer(name), + output_exponent(output_exponent), + filter_shape(filter_shape), + padding_type(padding_type), + padding(padding), + stride_y(stride_y), + stride_x(stride_x), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** @@ -66,7 +76,7 @@ namespace dl */ ~AvgPool2D() { - if(this->output != NULL) + if (this->output != NULL) { delete this->output; } @@ -76,20 +86,31 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); - std::vector output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + assert(input.shape.size() == 3); + + this->output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); - this->padding = nn::get_pad_size(output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); + } + this->output->free_element(); - } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } /** * @brief Get the output @@ -108,7 +129,6 @@ namespace dl * @param autoload_enable one of true or false, * - true: load input and output from PSRAM to CACHE automatically * - false: do not - * @param assign_core not effective yet * @return AvgPool2D result */ Tensor &call(Tensor &input, uint8_t autoload_enable = 0) @@ -116,7 +136,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_base.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_base.hpp index 5c7d28d52b1..b265b454538 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_base.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_base.hpp @@ -1,6 +1,7 @@ #pragma once #include "dl_tool.hpp" #include "dl_tool_cache.hpp" +#include namespace dl { diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_concat.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_concat.hpp new file mode 100644 index 00000000000..35ebe652e53 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_concat.hpp @@ -0,0 +1,139 @@ +#pragma once + +#include +#include + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" +#include "dl_nn_concat.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Concat(input1, input2, input3, ...). + * + * @tparam feature_t support all kinds of integer and float data type + */ + template + class Concat : Layer + { + private: + int output_exponent; /**/ + int axis; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Concat object. + * + * @param name name of layer + * @param axis The axis along which the Tensor will be concatenated. + */ + Concat(int axis, const char *name = "Concat") : Layer(name), axis(axis), output_shape({}) + { + this->output = new Tensor; + } + + /** + * @brief Destroy the Concat object + */ + ~Concat() + { + if (this->output != NULL) + { + delete this->output; + } + } + + /** + * @brief Collect inputs' channel and memory offset, called in Model.build(). + * + * @param args pointers of concatenated Tensor + * @param print_shape whether to print the output shape. + */ + void build(std::vector *> args, bool print_shape = false) + { + assert(args.size() > 1); + int shape_size = args[0]->shape.size(); + + if (this->axis < 0) + { + this->axis = shape_size + this->axis; + } + assert((this->axis < shape_size) && (this->axis > -1)); + + int output_shape_axis = args[0]->shape[this->axis]; + + for (int i = 1; i < args.size(); i++) + { + assert(shape_size == args[i]->shape.size()); + assert(args[i]->exponent == args[i - 1]->exponent); + output_shape_axis += args[i]->shape[this->axis]; + + for (int j = 0; j < shape_size; j++) + { + if (j != this->axis) + { + assert(args[i]->shape[j] == args[i - 1]->shape[j]); + } + } + } + + this->output_exponent = args[0]->exponent; + this->output_shape = args[0]->shape; + this->output_shape[this->axis] = output_shape_axis; + + this->output->set_shape(this->output_shape); + this->output->set_exponent(this->output_exponent); + this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Call Concat operation + * + * @param inputs the pointers of inputs + * @param free_inputs true: free the inputs after call + * false: do not free inputs + * @return Tensor& concat result + */ + Tensor &call(std::vector *> inputs, bool free_inputs = false) + { + DL_LOG_LAYER_LATENCY_INIT(); + + DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); + this->output->set_exponent(this->output_exponent); + DL_LOG_LAYER_LATENCY_END(this->name, "apply"); + + DL_LOG_LAYER_LATENCY_START(); + nn::concat(*this->output, inputs, this->axis, free_inputs); + DL_LOG_LAYER_LATENCY_END(this->name, "concat"); + return *this->output; + } + + /** + * @brief Get the output + * + * @return Tensor& Concat result + */ + Tensor &get_output() + { + return *this->output; + } + }; + } // namespace layer +} // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_conv2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_conv2d.hpp index a7c2229db09..038dd6cd79f 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_conv2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_conv2d.hpp @@ -13,8 +13,11 @@ namespace dl * @tparam feature_t supports int16_t and int8_t, * - int16_t: stands for operation in int16_t quantize * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization */ - template + template class Conv2D : public Layer { private: @@ -22,14 +25,14 @@ namespace dl const Filter *filter; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ - const Bias *bias; /**/ + const padding_type_t padding_type; /**/ + const Bias *bias; /**/ const Activation *activation; /**/ std::vector padding; /**/ - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Conv2D object. * @@ -37,33 +40,43 @@ namespace dl * @param filter filter of Conv2D * @param bias bias of Conv2D, if you don't specify anything, no bias is added * @param activation activation of Conv2D, if you don't specify anything, no activation is applied - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer */ Conv2D(const int output_exponent, const Filter *filter, - const Bias *bias = NULL, + const Bias *bias = NULL, const Activation *activation = NULL, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter(filter), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type), - bias(bias), - activation(activation) + const char *name = "Conv2D") : Layer(name), + output_exponent(output_exponent), + filter(filter), + stride_y(stride_y), + stride_x(stride_x), + padding_type(padding_type), + bias(bias), + activation(activation), + padding(padding), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** @@ -82,19 +95,30 @@ namespace dl * @brief Update output padding and input padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + assert(this->filter->shape.size() == 4); + assert(input.shape[2] == this->filter->shape[2]); - std::vector output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, true); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, true, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); this->output->free_element(); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); + } - this->padding = nn::get_pad_size(output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -122,7 +146,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -153,5 +181,6 @@ namespace dl dl::tool::cache::preload_func((uint32_t)(this->filter->element), size); } }; + } // namespace layer } // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp index 37475353209..30b2c2a6c77 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp @@ -13,8 +13,11 @@ namespace dl * @tparam feature_t supports int16_t and int8_t, * - int16_t: stands for operation in int16_t quantize * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization */ - template + template class DepthwiseConv2D : public Layer { private: @@ -22,14 +25,14 @@ namespace dl const Filter *filter; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ - const Bias *bias; /**/ + const padding_type_t padding_type; /**/ + const Bias *bias; /**/ const Activation *activation; /**/ std::vector padding; /**/ Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new DepthwiseConv2D object. * @@ -37,40 +40,50 @@ namespace dl * @param filter filter of DepthwiseConv2D * @param bias bias of DepthwiseConv2D, if you don't specify anything, no bias is added * @param activation activation of DepthwiseConv2D, if you don't specify anything, no activation is applied - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input - * such that output has the same height/width dimension as the input - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input + * such that output has the same height/width dimension as the input, + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y - stride in height * @param stride_x - stride in width * @param name name of layer */ DepthwiseConv2D(const int output_exponent, const Filter *filter, - const Bias *bias = NULL, + const Bias *bias = NULL, const Activation *activation = NULL, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter(filter), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type), - bias(bias), - activation(activation) + const char *name = "DepthwiseConv2D") : Layer(name), + output_exponent(output_exponent), + filter(filter), + stride_y(stride_y), + stride_x(stride_x), + padding_type(padding_type), + bias(bias), + activation(activation), + padding(padding), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** * @brief Destroy the DepthwiseConv2D object. * */ - ~DepthwiseConv2D() + ~DepthwiseConv2D() { if (this->output != NULL) { @@ -82,19 +95,31 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + assert(this->filter->shape.size() == 4); + assert(input.shape[2] == this->filter->shape[2]); - std::vector output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); - this->padding = nn::get_pad_size(output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); + } this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -122,7 +147,12 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_expand_dims.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_expand_dims.hpp new file mode 100644 index 00000000000..a59bed183fb --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_expand_dims.hpp @@ -0,0 +1,128 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class ExpandDims : public Layer + { + private: + std::vector output_shape; /**/ + std::vector axis; /**/ + Tensor *output; /**/ + bool inplace; /**/ + + public: + int output_exponent; + + /** + * @brief Construct a new ExpandDims object + * + * @param axis position where the new axis is placed. + * @param name name of layer + * @param inplace true: the output will store to input + * false: the output will store to a separate memory + */ + ExpandDims(std::vector axis, const char *name = "ExpandDims", bool inplace = false) : Layer(name), + axis(axis), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the ExpandDims object + * + */ + ~ExpandDims() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape. + * + * @param input as an input. + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->expand_dims(this->axis); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + this->output->expand_dims(this->axis); + } + this->output_shape = this->output->shape; + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& ExpandDims result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief call ExpandDims opeartion + * + * @param input + * @return Tensor& ExpandDims result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->set_shape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "ExpandDims"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_shape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "ExpandDims"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_flatten.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_flatten.hpp new file mode 100644 index 00000000000..70ae483a07f --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_flatten.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Flatten : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + + public: + /** + * @brief Construct a new Flatten object + * + * @param name name of layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Flatten(const char *name = "Flatten", bool inplace = false) : Layer(name), inplace(inplace), output_shape({}) + {} + + /** + * @brief Destroy the Flatten object + * + */ + ~Flatten() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape. + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + this->output_shape = {input.get_size()}; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Flatten result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Flatten operation. + * + * @param input as an input + * @return Tensor& Flatten result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->flatten(); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "flatten"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->flatten(); + DL_LOG_LAYER_LATENCY_END(this->name, "flatten"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_fullyconnected.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_fullyconnected.hpp new file mode 100644 index 00000000000..afa7e5befba --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_fullyconnected.hpp @@ -0,0 +1,167 @@ +#pragma once + +#include "dl_nn_fully_connected.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Activation(FullyConnected(input, filter) + bias). + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization + */ + template + class FullyConnected : public Layer + { + private: + const int output_exponent; /**/ + const bool flatten; /**/ + const Filter *filter; /**/ + const Bias *bias; /**/ + const Activation *activation; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ + + public: + /** + * @brief Construct a new FullyConnected object. + * + * @param output_exponent exponent of output + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param name name of layer + */ + FullyConnected(const int output_exponent, + const Filter *filter, + const Bias *bias = NULL, + const Activation *activation = NULL, + const bool flatten = true, + const char *name = "FullyConnected") : Layer(name), + output_exponent(output_exponent), + flatten(flatten), + filter(filter), + bias(bias), + activation(activation), + output_shape({}) + { + this->output = new Tensor; + } + + /** + * @brief Destroy the FullyConnected object. + * + */ + ~FullyConnected() + { + if (this->output != NULL) + { + delete this->output; + } + } + + /** + * @brief Update output padding and input padding. + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + assert(this->filter->shape.size() == 4); + assert(this->filter->shape[0] == 1); + assert(this->filter->shape[1] == 1); + if (this->flatten) + { + assert(input.get_size() == this->filter->shape[2]); + this->output_shape = {this->filter->shape[3]}; + } + else + { + assert(input.shape.back() == this->filter->shape[2]); + this->output_shape = input.shape; + this->output_shape[this->output_shape.size() - 1] = this->filter->shape[3]; + } + this->output->set_shape(this->output_shape); + this->output->set_exponent(this->output_exponent); + this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& FullyConnected result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call FullyConnected operation + * + * @param input as an input. + * @param autoload_enable one of true or false, + * - true: load input and output from PSRAM to CACHE automatically + * - false: do not + * @param assign_core not effective yet + * @return FullyConnected result + */ + Tensor &call(Tensor &input, bool autoload_enable = false, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) + { + DL_LOG_LAYER_LATENCY_INIT(); + + DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); + this->output->set_exponent(this->output_exponent); + DL_LOG_LAYER_LATENCY_END(this->name, "apply"); + + if (autoload_enable) + { + dl::tool::cache::autoload_func((uint32_t)(this->output->element), this->output->get_size() * sizeof(feature_t), + (uint32_t)(input.element), input.get_size() * sizeof(feature_t)); + } + + DL_LOG_LAYER_LATENCY_START(); + nn::fully_connected(*this->output, input, *(this->filter), this->bias, this->activation, this->flatten, assign_core); + DL_LOG_LAYER_LATENCY_END(this->name, "fully_connected"); + return *this->output; + } + + /** + * @brief Preload the filter to Cache. + * NOTE: Call this layer's preload() before previous layer's call() such that filter could be loaded while previous layer is doing calculation. + */ + void preload() + { + size_t size = sizeof(feature_t); + int shape_size = this->filter->shape.size(); + for (int i = 0; i < shape_size; ++i) + { + size *= filter->shape[i]; + } + dl::tool::cache::preload_func((uint32_t)(this->filter->element), size); + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp index 044c5f61847..93f2d30ac89 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp @@ -20,8 +20,9 @@ namespace dl class GlobalAveragePool2D : public Layer { private: - const int output_exponent; /**/ - Tensor *output; /**/ + const int output_exponent; /**/ + std::vector output_shape; /**/ + Tensor *output; /**/ public: /** * @brief Construct a new GlobalAveragePool2D object. @@ -29,8 +30,9 @@ namespace dl * @param output_exponent exponent of output * @param name name of layer */ - GlobalAveragePool2D(const int output_exponent, const char *name = NULL) : Layer(name), - output_exponent(output_exponent) + GlobalAveragePool2D(const int output_exponent, const char *name = "GlobalAveragePool2D") : Layer(name), + output_exponent(output_exponent), + output_shape({}) { this->output = new Tensor; @@ -52,17 +54,26 @@ namespace dl * @brief Update output shape. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; - this->output->set_shape(output_shape); + this->output_shape = output_shape; + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -90,7 +101,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp index aa146823b78..f9b7f73ff8c 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp @@ -20,15 +20,15 @@ namespace dl class GlobalMaxPool2D : public Layer { private: - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new GlobalMaxPool2D object. * * @param name name of layer */ - GlobalMaxPool2D(const char *name = NULL) : Layer(name) + GlobalMaxPool2D(const char *name = "GlobalMaxPool2D") : Layer(name), output_shape({}) { this->output = new Tensor; } @@ -49,17 +49,26 @@ namespace dl * @brief Update output shape and exponent. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); this->output->set_exponent(input.exponent); std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; - this->output->set_shape(output_shape); + this->output_shape = output_shape; + this->output->set_shape(this->output_shape); this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -87,7 +96,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_leakyrelu.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_leakyrelu.hpp index f18d9b1c522..a972e135006 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_leakyrelu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_leakyrelu.hpp @@ -2,7 +2,7 @@ #include "dl_constant.hpp" #include "dl_variable.hpp" -#include "dl_nn_LeakyReLU.hpp" +#include "dl_nn_leakyrelu.hpp" #include "dl_layer_base.hpp" namespace dl @@ -20,13 +20,13 @@ namespace dl class LeakyReLU : public Layer { private: - feature_t activation_alpha; /**/ - int activation_exponent; /**/ - Tensor *output; /**/ - bool inplace; /**/ + feature_t activation_alpha; /**/ + int activation_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new LeakyReLU object * @@ -34,9 +34,9 @@ namespace dl * @param activation_exponent exponent of quantized alpha * @param name name of leakyrelu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - LeakyReLU(const int activation_alpha, const int activation_exponent, const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + LeakyReLU(const int activation_alpha, const int activation_exponent, const char *name = "LeakyReLU", bool inplace = false) : Layer(name), output(NULL), output_shape({}) { this->activation_alpha = activation_alpha; this->activation_exponent = activation_exponent; @@ -47,7 +47,7 @@ namespace dl * @brief Destroy the LeakyReLU object * */ - ~LeakyReLU() + ~LeakyReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -59,24 +59,32 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; - } - this->output->set_shape(input.shape); + } + this->output->set_shape(this->output_shape); this->output->set_exponent(input.exponent); this->output->free_element(); } else { this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); } - } /** @@ -100,10 +108,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +126,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::leakyrelu(*this->output, input, this->activation_alpha, this->activation_exponent, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max2d.hpp index 8a775a2e0f0..93bc5899443 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max2d.hpp @@ -22,28 +22,28 @@ namespace dl class Max2D : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Max2D object. * * @param name name of max2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Max2D(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + Max2D(const char *name = "Max2D", bool inplace = false) : Layer(name), + output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Max2D object * */ - ~Max2D() + ~Max2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -58,24 +58,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); + this->output_shape = input0.shape; - if(!this->inplace) + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -100,10 +110,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +128,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::max2d(*this->output, input0, input1, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "max2d"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max_pool2d.hpp index f836a983b34..629aa87f515 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_max_pool2d.hpp @@ -23,44 +23,54 @@ namespace dl std::vector filter_shape; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ + const padding_type_t padding_type; /**/ std::vector padding; /**/ Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new MaxPool2D object. * * @param filter_shape filter shape in [filter_height, filter_width] - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer */ MaxPool2D(const std::vector filter_shape, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - filter_shape(filter_shape), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type) + const char *name = "MaxPool2D") : Layer(name), + filter_shape(filter_shape), + padding_type(padding_type), + padding(padding), + stride_y(stride_y), + stride_x(stride_x), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** * @brief Destroy the MaxPool2D object. * */ - ~MaxPool2D() + ~MaxPool2D() { if (this->output != NULL) { @@ -72,18 +82,29 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + this->output->set_exponent(input.exponent); - std::vector output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); - this->padding = nn::get_pad_size(output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); + } this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -111,7 +132,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_min2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_min2d.hpp index 71d39c9b285..e38fbf3d0d2 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_min2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_min2d.hpp @@ -22,28 +22,28 @@ namespace dl class Min2D : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ - public: - + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + public: /** * @brief Construct a new Min2D object * * @param name name of min2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Min2D(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) - { - this->inplace = inplace; - } + Min2D(const char *name = "Min2D", bool inplace = false) : Layer(name), + output(NULL), + inplace(inplace), + output_shape({}) {} /** * @brief Destroy the Min2D object * */ - ~Min2D() + ~Min2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -58,25 +58,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); + this->output_shape = input0.shape; - if(!this->inplace) + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->set_exponent(input0.exponent); this->output->free_element(); } else + { this->output = &input0; - + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -101,10 +110,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -115,6 +128,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::min2d(*this->output, input0, input1, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "min2d"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_mul2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_mul2d.hpp index 0edfc9a93f0..21bcca7a81e 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_mul2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_mul2d.hpp @@ -21,14 +21,13 @@ namespace dl class Mul2D : public Layer { private: - const int output_exponent; /**/ + const int output_exponent; /**/ const Activation *activation; /**/ - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - const int output_exponent; /**/ - /** * @brief Construct a new Mul2D object. * @@ -36,18 +35,24 @@ namespace dl * @param activation activation of Mul2D, if you don't specify anything, no activation is applied * @param name name of layer * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Mul2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), - output_exponent(output_exponent),activation(activation), output(NULL) + Mul2D(const int output_exponent, + const Activation *activation = NULL, + const char *name = "Mul2D", + bool inplace = false) : Layer(name), + output_exponent(output_exponent), + activation(activation), + output(NULL), + inplace(inplace), + output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Multiply2D object. */ - ~Mul2D() + ~Mul2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -61,24 +66,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } - + else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -106,7 +121,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -117,6 +136,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::mul2d(*this->output, input0, input1, this->activation, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "mul2d"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_prelu.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_prelu.hpp index 4781a669130..96168a783b1 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_prelu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_prelu.hpp @@ -24,9 +24,9 @@ namespace dl int activation_exponent; /**/ Tensor *output; /**/ bool inplace; /**/ + false: the output will store to a separate memory >*/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new PReLU object * @@ -34,20 +34,25 @@ namespace dl * @param activation_exponent exponent of quantized alpha elements * @param name name of prelu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - PReLU(const feature_t *activation_element, const int activation_exponent = 0, const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + PReLU(const feature_t *activation_element, + const int activation_exponent = 0, + const char *name = NULL, + bool inplace = "PReLU") : Layer(name), + activation_element(activation_element), + activation_exponent(activation_exponent), + output(NULL), + inplace(inplace), + output_shape({}) { - this->activation_element = activation_element; - this->activation_exponent = activation_exponent; - this->inplace = inplace; } /** * @brief Destroy the PReLU object * */ - ~PReLU() + ~PReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -59,23 +64,31 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(input.exponent); - this->output->set_shape(input.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else { this->output = &input; } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -99,11 +112,15 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } this->output->set_exponent(input.exponent); - this->output->apply_element(); + this->output->malloc_element(); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); DL_LOG_LAYER_LATENCY_START(); @@ -113,6 +130,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::prelu(*this->output, input, this->activation_element, this->activation_exponent, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_relu.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_relu.hpp index e70663b798c..7dd29d4a178 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_relu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_relu.hpp @@ -21,29 +21,28 @@ namespace dl class ReLU : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - - /** * @brief Construct a new ReLU object * * @param name name of relu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - ReLU(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + ReLU(const char *name = "ReLU", bool inplace = false) : Layer(name), + output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the ReLU object * */ - ~ReLU() + ~ReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -55,23 +54,31 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(input.exponent); - this->output->set_shape(input.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else { this->output = &input; } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -95,10 +102,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -109,6 +120,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::relu(*this->output, input, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "relu"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_reshape.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_reshape.hpp new file mode 100644 index 00000000000..3f2ed72b6e0 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_reshape.hpp @@ -0,0 +1,124 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Reshape(input) + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + */ + template + class Reshape : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Reshape object + * + * @param shape the target shape + * @param name name of Reshape layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Reshape(std::vector shape, const char *name = "Reshape", bool inplace = false) : Layer(name), + output_shape(shape), inplace(inplace) + { + } + + /** + * @brief Destroy the Reshape object + * + */ + ~Reshape() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Reshape result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Reshape operation. + * + * @param input as an input + * @return Tensor& Reshape result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->reshape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "reshape"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->reshape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "reshape"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_squeeze.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_squeeze.hpp new file mode 100644 index 00000000000..cee92f22764 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_squeeze.hpp @@ -0,0 +1,127 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Squeeze : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + int axis; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Squeeze object + * + * @param axis the dim to to be remove. make sure the length of the dim is equal to 1. + * if axis == INT32_MAX, all the dims with length==1 will be removed. + * @param name name of Squeeze layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Squeeze(int axis = INT32_MAX, const char *name = "Squeeze", bool inplace = false) : Layer(name), axis(axis), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the Squeeze object + * + */ + ~Squeeze() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(input.shape); + this->output->squeeze(this->axis); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(input.shape); + this->output->squeeze(this->axis); + } + this->output_shape = this->output->shape; + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Squeeze result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Squeeze operation. + * + * @param input as an input + * @return Tensor& Squeeze result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->set_shape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "Squeeze"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_shape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "Squeeze"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_sub2d.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_sub2d.hpp index e3453c08b97..da03b4aad85 100644 --- a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_sub2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_sub2d.hpp @@ -21,13 +21,13 @@ namespace dl class Sub2D : public Layer { private: - const int output_exponent; /**/ - const Activation *activation; /**/ - Tensor *output; /**/ - bool inplace; /**/ + const int output_exponent; /**/ + const Activation *activation; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Sub2D object. * @@ -35,18 +35,17 @@ namespace dl * @param activation activation of Mul2D, if you don't specify anything, no activation is applied * @param name name of layer * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Sub2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), - output_exponent(output_exponent), activation(activation), output(NULL) + Sub2D(const int output_exponent, const Activation *activation = NULL, const char *name = "Sub2D", bool inplace = false) : Layer(name), + output_exponent(output_exponent), activation(activation), output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Sub2D object. */ - ~Sub2D() + ~Sub2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -60,22 +59,32 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); - } + } else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -103,7 +112,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output.apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output.malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +127,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::sub2d(this->output, input0, input1, this->activation, assign_core, this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "sub2d"); } diff --git a/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_transpose.hpp b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_transpose.hpp new file mode 100644 index 00000000000..d89ba8daed5 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/layer/dl_layer_transpose.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Transpose : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector perm; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Transpose object + * + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @param name name of Transpose layer + * @param inplace true: the output will store to input + * false: the output will store to a separate memory + */ + Transpose(std::vector perm = {}, const char *name = "Transpose", bool inplace = false) : Layer(name), perm(perm), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the Transpose object + * + */ + ~Transpose() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + this->output_shape = input.shape; + for (int i = 0; i < this->perm.size(); i++) + { + this->output_shape[i] = input.shape[this->perm[i]]; + } + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Transpose result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Transpose operation. + * + * @param input as an input. + * @return Tensor& Transpose result. + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->transpose(input, this->perm); + DL_LOG_LAYER_LATENCY_END(this->name, "transpose"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->transpose(this->perm); + DL_LOG_LAYER_LATENCY_END(this->name, "transpose"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/model_zoo/color_detector.hpp b/tools/sdk/esp32/include/esp-face/include/model_zoo/color_detector.hpp new file mode 100644 index 00000000000..063ab20b34a --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/model_zoo/color_detector.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "dl_image.hpp" + +typedef struct +{ + int area; /*!< Area of connected domains >*/ + std::vector center; /**/ + std::vector box; /**/ +} components_stats_t; + +class ColorDetector +{ +private: + std::vector> results; /*!< detection results >*/ + +public: + std::vector> color_thresh; /*!< threshold of colors, The threshold of each color is composed of 6 numbers >*/ + std::vector area_thresh; /*!< the area threshold of each color, + the area that is smaller than the threshold is filtered >*/ + bool bgr; /*!< true: the input image is in BGR format + false: the input image is in RGB format >*/ + + /** + * @brief get the color threshold of rectangular region in the image + * + * @param image the input image + * @param box the coordinates of the rectanglar region : [left_up_x, left_up_y, right_down_x, right_down_y] + * @return std::vector the threshold. + */ + std::vector cal_color_thresh(dl::Tensor &image, std::vector box); + + /** + * @brief detect the colors based on the color thresholds + * + * @param image the input image. + * @return std::vector>& detection result. + */ + std::vector> &detect(dl::Tensor &image); + + /** + * @brief Construct a new Color Detector object + * + * @param color_thresh threshold of colors, The threshold of each color is composed of 6 numbers + * @param area_thresh the area threshold of each color,the area that is smaller than the threshold is filtered + * @param bgr true: the input image is in BGR format + * false: the input image is in RGB format + */ + ColorDetector(std::vector> color_thresh, std::vector area_thresh, bool bgr = false) : color_thresh(color_thresh), area_thresh(area_thresh), bgr(bgr) + { + } + + /** + * @brief Destroy the Color Detector object + * + */ + ~ColorDetector() {} + + /** + * @brief Get the results object + * + * @return std::vector>& the detection result. + */ + std::vector> &get_results() + { + return this->results; + } +}; \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/include/model_zoo/face_recognition_tool.hpp b/tools/sdk/esp32/include/esp-face/include/model_zoo/face_recognition_tool.hpp index 12fe8a842a2..2226d32daf9 100644 --- a/tools/sdk/esp32/include/esp-face/include/model_zoo/face_recognition_tool.hpp +++ b/tools/sdk/esp32/include/esp-face/include/model_zoo/face_recognition_tool.hpp @@ -92,7 +92,7 @@ namespace face_recognition_tool * @return dl::Tensor* */ template - dl::Tensor *transform_mfn_input(dl::Tensor &image, bool free_input = false, bool do_padding = true); + dl::Tensor *transform_mfn_input(dl::Tensor &image, bool free_input = false); /** * @brief transform the image to the input of a mfn model @@ -106,7 +106,7 @@ namespace face_recognition_tool * false: do not pad the result */ template - void transform_mfn_input(dl::Tensor &image, dl::Tensor &output, bool free_input = false, bool do_padding = true); + void transform_mfn_input(dl::Tensor &image, dl::Tensor &output, bool free_input = false); /** * @brief transform the mfn output embedding to a floating embedding diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn.hpp index 6dba8016f26..6c737c1d341 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn.hpp @@ -14,13 +14,13 @@ namespace dl * @param filter_shape filter shape with dilation * @param stride_y stride in height * @param stride_x stride in width - * @param pad_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET + * @param pad_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN * @param is_conv2d one of true or false, * - true: serve for Conv2D * - false: serve for other operations * @return std::vector */ - std::vector get_output_shape(const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t pad_type, const bool is_conv2d = false); + std::vector get_output_shape(const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t pad_type, const bool is_conv2d = false, std::vector padding = {}); /** * @brief Get the pad size object @@ -30,7 +30,7 @@ namespace dl * @param filter_shape filter shape with dilation * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN * @return padding size */ std::vector get_pad_size(const std::vector &output_shape, const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t padding_type); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_add2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_add2d.hpp index d296be5350b..4d4daaaef05 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_add2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_add2d.hpp @@ -58,20 +58,20 @@ namespace dl */ template auto add2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp index 5b298d98c44..6e7db6ed0e0 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp @@ -58,12 +58,12 @@ namespace dl * @param filter_shape filter_shape in [filter_height, filter_width] * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param assign_core not effective yet * @return avg_pool2d result */ @@ -81,19 +81,19 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter_shape, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); - input.set_padding_size(padding); + padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - avg_pool2d(output, input, input.padding, filter_shape, stride_y, stride_x, assign_core); + avg_pool2d(output, input, padding, filter_shape, stride_y, stride_x, assign_core); DL_LOG_NN_LATENCY_END("avg_pool2d"); return output; diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_concat.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_concat.hpp new file mode 100644 index 00000000000..73ed1aae905 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_concat.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include "dl_variable.hpp" +#include "dl_nn.hpp" + +namespace dl +{ + namespace nn + { + template + void concat(Tensor &output, std::vector *> &inputs, int axis, bool free_inputs = false); + + template + Tensor concat(std::vector *> &inputs, int axis, bool free_inputs = false) + { + DL_LOG_NN_LATENCY_INIT(); + + DL_LOG_NN_LATENCY_START(); + assert(inputs.size() > 1); + int shape_size = inputs[0]->shape.size(); + + if (axis < 0) + { + axis = shape_size + axis; + } + + assert((axis < shape_size) && (axis > -1)); + + int output_shape_axis = inputs[0]->shape[axis]; + + for (int i = 1; i < inputs.size(); i++) + { + assert(shape_size == inputs[i]->shape.size()); + assert(inputs[i]->exponent == inputs[i - 1]->exponent); + output_shape_axis += inputs[i]->shape[axis]; + + for (int j = 0; j < shape_size; j++) + { + if (j != axis) + { + assert(inputs[i]->shape[j] == inputs[i - 1]->shape[j]); + } + } + } + DL_LOG_NN_LATENCY_END("assert"); + + DL_LOG_NN_LATENCY_START(); + Tensor output; + std::vector output_shape = inputs[0]->shape; + output_shape[axis] = output_shape_axis; + output.set_shape(output_shape); + output.set_exponent(inputs[0]->exponent); + output.malloc_element(); + DL_LOG_NN_LATENCY_END("malloc"); + + DL_LOG_NN_LATENCY_START(); + concat(output, inputs, axis, free_inputs); + DL_LOG_NN_LATENCY_END("concat"); + return output; + } + } // namespace nn +} // namespace dl diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_conv2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_conv2d.hpp index 77e2c617d04..27ba0372730 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_conv2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_conv2d.hpp @@ -10,7 +10,6 @@ namespace dl { /** * @brief activation(conv2d(input, filter) + bias). - * NOTE: When padding_type is SAME, make sure padding is already added in input. * * @param output as an output * @param input as an input @@ -34,7 +33,6 @@ namespace dl /** * @brief activation(conv2d(input, filter) + bias). - * NOTE: When padding_type is SAME, make sure padding is already added in input. * * @param output as an output * @param input as an input @@ -56,6 +54,29 @@ namespace dl const Activation *const activation = NULL, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** + * @brief activation(conv2d(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param padding padding size needed in [top, bottom, left, right] of this operation + * @param filter filter of conv2d + * @param stride_y stride in height + * @param stride_x stride in width + * @param bias bias of conv2d, if you don't specify anything, no bias is added + * @param activation activation of conv2d, if you don't specify anything, no activation is applied + * @param assign_core not effective yet + */ + void conv2d(Tensor &output, + Tensor &input, + std::vector &padding, + const Filter &filter, + const int stride_y, + const int stride_x, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** * @brief activation(conv2d(input, filter) + bias). * @@ -67,25 +88,25 @@ namespace dl * @param filter Filter of conv2d * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param bias bias of conv2d, if you don't specify anything, no bias is added * @param activation activation of conv2d, if you don't specify anything, no activation is applied * @param assign_core not effective yet * @return conv2d result */ - template + template Tensor conv2d(const int output_exponent, Tensor &input, const Filter &filter, const int stride_y, const int stride_x, const padding_type_t padding_type, - const Bias *bias, + const Bias *bias, const Activation *activation, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) { @@ -94,20 +115,19 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type, true); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - conv2d(output, input, input.padding, filter, stride_y, stride_x, bias, activation, assign_core); + conv2d(output, input, padding, filter, stride_y, stride_x, bias, activation, assign_core); DL_LOG_NN_LATENCY_END("conv2d"); return output; diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp index 6e972bfd81b..135815a65cb 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp @@ -10,7 +10,6 @@ namespace dl { /** * @brief activate(depthwise_conv2d(input, filter) + bias) - * NOTE: When padding_type is SAME, make sure padding is already added in input * * @param output as an output * @param input as an input @@ -34,7 +33,6 @@ namespace dl /** * @brief activate(depthwise_conv2d(input, filter) + bias) - * NOTE: When padding_type is SAME, make sure padding is already added in input * * @param output as an output * @param input as an input @@ -56,6 +54,29 @@ namespace dl const Activation *activation = NULL, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** + * @brief activate(depthwise_conv2d(input, filter) + bias) + * + * @param output as an output + * @param input as an input + * @param padding padding size needed in [top, bottom, left, right] of this operation + * @param filter Filter of depthwise_conv2d + * @param stride_y stride in height + * @param stride_x stride in width + * @param bias bias of depthwise_conv2d, if you don't specify anything, no bias is added + * @param activation activation of depthwise_conv2d, if you don't specify anything, no activation is applied + * @param assign_core not effective yet + */ + void depthwise_conv2d(Tensor &output, + Tensor &input, + std::vector &padding, + const Filter &filter, + const int stride_y, + const int stride_x, + const Bias *bias = NULL, + const Activation *activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** * @brief activation(depthwise_conv2d(input, filter) + bias) * @@ -67,25 +88,25 @@ namespace dl * @param filter filter of depthwise_conv2d * @param stride_y stride in height * @param stride_x stride in width - * @param pad_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param pad_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param bias bias of depthwise_conv2d, if you don't specify anything, no bias is added * @param activation activation of depthwise_conv2d, if you don't specify anything, no activation is applied * @param assign_core not effective yet * @return depthwise_conv2d result */ - template + template Tensor depthwise_conv2d(const int output_exponent, Tensor &input, const Filter &filter, const int stride_y, const int stride_x, const padding_type_t padding_type, - const Bias *bias, + const Bias *bias, const Activation *activation, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) { @@ -94,20 +115,20 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); + DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - depthwise_conv2d(output, input, input.padding, filter, stride_y, stride_x, bias, activation, assign_core); + depthwise_conv2d(output, input, padding, filter, stride_y, stride_x, bias, activation, assign_core); DL_LOG_NN_LATENCY_END("depthwise_conv2d"); return output; diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_fully_connected.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_fully_connected.hpp new file mode 100644 index 00000000000..372c84825fd --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_fully_connected.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_nn.hpp" + +namespace dl +{ + namespace nn + { + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + * @param output_exponent exponent of output + * @param input as an input + * @param filter Filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + * @return FullyConnected result + */ + template + Tensor fully_connected(const int output_exponent, + Tensor &input, + const Filter &filter, + const Bias *bias, + const Activation *activation, + const bool flatten, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) + { + DL_LOG_NN_LATENCY_INIT(); + + DL_LOG_NN_LATENCY_START(); + assert(filter.shape.size() == 4); + assert(filter.shape[0] == 1); + assert(filter.shape[1] == 1); + + std::vector output_shape; + if (flatten) + { + assert(input.get_size() == filter.shape[2]); + output_shape = {filter.shape.back()}; + } + else + { + assert(input.shape.back() == filter->shape[2]); + output_shape = input.shape; + output_shape[output_shape.size() - 1] = filter.shape.back(); + } + Tensor output; + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); + DL_LOG_NN_LATENCY_END("apply"); + + DL_LOG_NN_LATENCY_START(); + fully_connected(output, input, filter, bias, activation, flatten, assign_core); + DL_LOG_NN_LATENCY_END("fully_connected"); + + return output; + } + } // namespace nn +} // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp index 723ca9eddc4..724d3ca0952 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp @@ -53,7 +53,7 @@ namespace dl std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp index 945645cfd55..f6f15e91bd3 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp @@ -51,7 +51,7 @@ namespace dl std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; Tensor output; - output.set_exponent(input.exponent).set_shape(output_shape).apply_element(); + output.set_exponent(input.exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_leakyrelu.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_leakyrelu.hpp index d3738fc44ca..c41728b1ad5 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_leakyrelu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_leakyrelu.hpp @@ -52,17 +52,17 @@ namespace dl * @return leakyrelu result or no return(result store to input) */ template - auto leakyrelu(Tensor &input, - const int activation_alpha, - const int activation_exponent, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto leakyrelu(Tensor &input, + const int activation_alpha, + const int activation_exponent, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max2d.hpp index 0a5e8f43221..466089bc386 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max2d.hpp @@ -48,20 +48,20 @@ namespace dl * @return max2d result or no return(result store to input0) */ template - auto max2d(Tensor &input0, - Tensor &input1, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto max2d(Tensor &input0, + Tensor &input1, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input0.exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(input0.exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max_pool2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max_pool2d.hpp index 7f95f3d4278..50d51728ce0 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max_pool2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_max_pool2d.hpp @@ -57,12 +57,12 @@ namespace dl * @param filter_shape filter shape in [filter_height, filter_width] * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param assign_core not effective yet * @return max_pool2d result */ @@ -79,20 +79,20 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter_shape, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(input.exponent).set_shape(output_shape).apply_element(); + output.set_exponent(input.exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); + DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - max_pool2d(output, input, input.padding, filter_shape, stride_y, stride_x, assign_core); + max_pool2d(output, input, padding, filter_shape, stride_y, stride_x, assign_core); DL_LOG_NN_LATENCY_END("max_pool2d"); return output; diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_min2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_min2d.hpp index 71cb87d50d5..8faddf3c228 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_min2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_min2d.hpp @@ -47,20 +47,20 @@ namespace dl * @return min2d result or no return(result store to input0) */ template - auto min2d(Tensor &input0, - Tensor &input1, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto min2d(Tensor &input0, + Tensor &input1, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input0.exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(input0.exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_mul2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_mul2d.hpp index 410528a05a3..909619a8767 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_mul2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_mul2d.hpp @@ -18,12 +18,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void mul2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void mul2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(mul2d(input0, input1)). @@ -35,12 +35,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void mul2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void mul2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(mul2d(input0, input1)). @@ -57,21 +57,21 @@ namespace dl * @return mul2d result or no return(result store to input0) */ template - auto mul2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto mul2d(const int output_exponent, + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_prelu.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_prelu.hpp index fb4315d9fc3..e83e8975604 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_prelu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_prelu.hpp @@ -52,17 +52,17 @@ namespace dl * @return prelu result or no return(result store to input) */ template - auto prelu(Tensor &input, - const feature_t *activation_element, - const int activation_exponent, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto prelu(Tensor &input, + const feature_t *activation_element, + const int activation_exponent, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); @@ -76,7 +76,7 @@ namespace dl DL_LOG_NN_LATENCY_START(); prelu(input, input, activation_element, activation_exponent, assign_core); DL_LOG_NN_LATENCY_END("prelu"); - } + } } } // namespace nn } // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_relu.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_relu.hpp index e4159fdf898..308492dfe4b 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_relu.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_relu.hpp @@ -15,9 +15,9 @@ namespace dl * @param input as an input * @param assign_core not effective yet */ - void relu(Tensor &output, - Tensor &input, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + void relu(Tensor &output, + Tensor &input, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); /** * @brief relu(input). @@ -26,9 +26,9 @@ namespace dl * @param input as an input * @param assign_core not effective yet */ - void relu(Tensor &output, - Tensor &input, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + void relu(Tensor &output, + Tensor &input, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); /** * @brief relu(input) @@ -46,11 +46,11 @@ namespace dl { DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_sub2d.hpp b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_sub2d.hpp index 385188e4ba2..5bbd4940b10 100644 --- a/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_sub2d.hpp +++ b/tools/sdk/esp32/include/esp-face/include/nn/dl_nn_sub2d.hpp @@ -18,12 +18,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void sub2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void sub2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(sub2d(input0, input1)). @@ -35,12 +35,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void sub2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void sub2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(sub2d(input0, input1)). @@ -57,20 +57,20 @@ namespace dl * @return sub2d result or no return(result store to input0) */ template - auto sub2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto sub2d(const int output_exponent, + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32/include/esp-face/include/tool/dl_tool.hpp b/tools/sdk/esp32/include/esp-face/include/tool/dl_tool.hpp index f8e0871a04f..e5490e073d1 100644 --- a/tools/sdk/esp32/include/esp-face/include/tool/dl_tool.hpp +++ b/tools/sdk/esp32/include/esp-face/include/tool/dl_tool.hpp @@ -67,62 +67,49 @@ namespace dl void copy_memory(void *dst, void *src, const int n); /** - * @brief Apply memory without initialized. Must use free_aligned() to free the memory. + * @brief Apply memory without initialized. Can use free_aligned() to free the memory. * * @param number number of elements * @param size size of element - * @param align number of aligned, e.g., 16 means 16-byte aligned + * @param align number of byte aligned, e.g., 16 means 16-byte aligned * @return pointer of allocated memory. NULL for failed */ - inline void *malloc_aligned(int number, int size, int align = 0) + inline void *malloc_aligned(int number, int size, int align = 4) { - int n = number * size; - n >>= 4; - n += 2; - n <<= 4; - int total_size = n + align + sizeof(void *) + sizeof(int); - void *res = malloc(total_size); + assert((align > 0) && (((align & (align-1)) == 0))); + int total_size = number * size; + + void *res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); #if DL_SPIRAM_SUPPORT if (NULL == res) - res = heap_caps_malloc(total_size, MALLOC_CAP_SPIRAM); + res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_SPIRAM); #endif if (NULL == res) { printf("Fail to malloc %d bytes from DRAM(%d bytyes) and PSRAM(%d bytes), PSRAM is %s.\n", total_size, - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), + heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_SPIRAM), DL_SPIRAM_SUPPORT ? "on" : "off"); return NULL; } - void **data = (void **)res + 2; // 4-byte for pointer, 4-bytes for n - void **aligned; - if (align) - aligned = (void **)(((size_t)data + (align - 1)) & -align); - else - aligned = data; - - aligned[-1] = res; - int *temp = (int *)aligned; - temp[-2] = n; - return (void *)aligned; + return (void *)res; } /** - * @brief Apply memory with zero-initialized. Must use dl_lib_free() to free the memory. + * @brief Apply memory with zero-initialized. Can use free_aligned() to free the memory. * * @param number number of elements * @param size size of element - * @param align number of aligned, e.g., 16 means 16-byte aligned + * @param align number of byte aligned, e.g., 16 means 16-byte aligned * @return pointer of allocated memory. NULL for failed */ - inline void *calloc_aligned(int number, int size, int align = 0) + inline void *calloc_aligned(int number, int size, int align = 4) { void *aligned = malloc_aligned(number, size, align); - int n = *((int *)aligned - 2); - set_zero(aligned, n); + set_zero(aligned, number * size); return (void *)aligned; } @@ -137,7 +124,70 @@ namespace dl if (NULL == address) return; - free(((void **)address)[-1]); + heap_caps_free(address); + } + + /** + * @brief Apply memory without initialized in preference order: internal aligned, internal, external aligned + * + * @param number number of elements + * @param size size of element + * @param align number of byte aligned, e.g., 16 means 16-byte aligned + * @return pointer of allocated memory. NULL for failed + */ + inline void *malloc_aligned_prefer(int number, int size, int align = 4) + { + assert((align > 0) && (((align & (align-1)) == 0))); + int total_size = number * size; + void *res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + if (NULL == res){ + res = heap_caps_malloc(total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + } +#if DL_SPIRAM_SUPPORT + if (NULL == res){ + res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_SPIRAM); + } +#endif + if (NULL == res) + { + printf("Fail to malloc %d bytes from DRAM(%d bytyes) and PSRAM(%d bytes), PSRAM is %s.\n", + total_size, + heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL), + heap_caps_get_free_size(MALLOC_CAP_SPIRAM), + DL_SPIRAM_SUPPORT ? "on" : "off"); + return NULL; + } + + return res; + } + + /** + * @brief Apply memory with zero-initialized in preference order: internal aligned, internal, external aligned + * + * @param number number of elements + * @param size size of element + * @param align number of byte aligned, e.g., 16 means 16-byte aligned + * @return pointer of allocated memory. NULL for failed + */ + inline void *calloc_aligned_prefer(int number, int size, int align = 4) + { + void *res = malloc_aligned_prefer(number, size, align); + set_zero(res, number * size); + + return (void *)res; + } + + /** + * @brief Free the calloc_aligned_prefer() and malloc_aligned_prefer() memory + * + * @param address pointer of memory to free + */ + inline void free_aligned_prefer(void *address) + { + if (NULL == address) + return; + + heap_caps_free(address); } /** diff --git a/tools/sdk/esp32/include/esp-face/include/typedef/dl_constant.hpp b/tools/sdk/esp32/include/esp-face/include/typedef/dl_constant.hpp index 73e3b0832e7..07b2dd24ee1 100644 --- a/tools/sdk/esp32/include/esp-face/include/typedef/dl_constant.hpp +++ b/tools/sdk/esp32/include/esp-face/include/typedef/dl_constant.hpp @@ -57,7 +57,8 @@ namespace dl * @param exponent exponent of element * @param shape shape of Filter, * - 1D: reserved - * - 2D: [filter_height, filter_width, input_channel, output_channel] + * - 2D: for convolution is [filter_height, filter_width, input_channel, output_channel], + * for depthwise convolution is [filter_height, filter_width, input_channel, 1] * @param dilation dilation of Filter * - 1D: reserved * - 2D: [dilation_in_height, dilation_in_width] @@ -97,6 +98,9 @@ namespace dl { public: using Constant::Constant; + std::vector channel_exponent; /**/ + + Bias(const T *element, const std::vector channel_exponent, const std::vector shape); }; /** diff --git a/tools/sdk/esp32/include/esp-face/include/typedef/dl_variable.hpp b/tools/sdk/esp32/include/esp-face/include/typedef/dl_variable.hpp index bf6e8630856..18cbe9707e9 100644 --- a/tools/sdk/esp32/include/esp-face/include/typedef/dl_variable.hpp +++ b/tools/sdk/esp32/include/esp-face/include/typedef/dl_variable.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "dl_tool.hpp" @@ -17,27 +18,20 @@ namespace dl class Tensor { private: - int size; /* axis_offset; /* shape; /* shape_with_padding; /* padding; /* shape; /*set_shape({0}); } /** * @brief Construct a new Tensor object by copying from input. @@ -49,21 +43,20 @@ namespace dl */ Tensor(Tensor &input, bool deep) : size(input.size), auto_free(input.auto_free), - exponent(input.exponent), - shape(input.shape), - shape_with_padding(input.shape_with_padding), - padding(input.padding) + exponent(input.exponent) { - if (deep) + this->set_shape(input.shape); + if (deep && (input.element != NULL)) { - int size_real = input.shape_with_padding.size() ? input.shape_with_padding[0] * input.shape_with_padding[1] * input.shape_with_padding[2] : 0; - T *new_element = (T *)tool::calloc_aligned(size_real, sizeof(T), 16); + int size_real = input.get_size(); + T *new_element = (T *)tool::calloc_aligned_prefer(size_real, sizeof(T), 16); tool::copy_memory(new_element, input.element, size_real * sizeof(T)); this->element = new_element; } else { this->element = input.element; + this->auto_free = false; } } @@ -77,6 +70,33 @@ namespace dl this->free_element(); } + /** + * @brief + * + * @param input an input Tensor + * @param deep one of true or false + * - true: apply a new memory, copy value from input.element to this new memory + * - false: take over input.element to this->element + * @return Tensor& self + */ + Tensor ©_element(Tensor &input, bool deep) + { + assert(this->get_size() == input.get_size()); + assert(input.element != NULL); + + this->malloc_element(); + if (deep) + { + tool::copy_memory(this->element, input.element, this->get_size() * sizeof(T)); + } + else + { + this->element = input.element; + this->auto_free = false; + } + return *this; + } + /** * @brief Set the auto free object. * @@ -120,190 +140,144 @@ namespace dl } /** - * @brief Set the shape of Tensor. Initial this->padding = {0}. Initial this->size = -1. + * @brief Set the shape of Tensor. * - * @param shape shape in - * - 2D: [height, width] + * @param shape the target shape + * * @return self */ - Tensor &set_shape(const std::vector shape) - { - for (int i = 0; i < shape.size(); ++i) - { - assert(shape[i] > 0); - } - this->shape = shape; - this->shape_with_padding = shape; - this->size = -1; - this->padding = std::vector(((this->shape.size() - 1) << 1), 0); - return *this; - } + Tensor &set_shape(const std::vector shape); /** - * @brief Set the padding size object. + * @brief print the shape of the Tensor * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @return self */ - Tensor &set_padding_size(std::vector &padding) + void print_shape() { - assert(this->shape.size()); // call Tensor.set_shape() first - assert(this->shape.size() == 3); // TODO: || this->shape.size() == 2 - - if (this->shape.size() == 3) + if (this->shape.size()) { - std::vector new_padding = this->padding; - bool dont_update = true; - - if (padding[0] > this->padding[0]) + printf("shape = ("); + for (int i = 0; i < this->shape.size() - 1; i++) { - new_padding[0] = padding[0]; - dont_update = false; - } - - if (padding[1] > this->padding[1]) - { - new_padding[1] = padding[1]; - dont_update = false; - } - - if (padding[2] > this->padding[2]) - { - new_padding[2] = padding[2]; - dont_update = false; - } - - if (padding[3] > this->padding[3]) - { - new_padding[3] = padding[3]; - dont_update = false; + printf("%d, ", this->shape[i]); } + printf("%d)\n", this->shape.back()); + } + else + { + printf("shape = ()\n"); + } + } - if (dont_update) - { - return *this; - } + /** + * @brief flatten the Tensor + * + * @return Tensor& self + */ + Tensor &flatten(); - std::vector new_shape_with_padding = this->shape; + /** + * @brief Change a new shape to the Tensor without changing its data. + * + * @param shape the target shape + * @return Tensor& self + */ + Tensor &reshape(std::vector shape); - new_shape_with_padding[0] += (new_padding[0] + new_padding[1]); - new_shape_with_padding[1] += (new_padding[2] + new_padding[3]); - int new_size = new_shape_with_padding[0] * new_shape_with_padding[1] * new_shape_with_padding[2]; + /** + * @brief Remove dims with length==1 from Tensor + * + * @param axis the dim to to be remove. make sure the length of the dim is equal to 1. + * if axis == INT32_MAX, all the dims with length==1 will be removed. + * @return Tensor& self + */ + Tensor &squeeze(int axis = INT32_MAX); - if (this->element) // if this->element != NULL, do padding by copy memory - { - T *new_element = (T *)tool::malloc_aligned(new_size, sizeof(T), 16); - T *dst = new_element + ((new_padding[0] * new_shape_with_padding[1]) + new_padding[2]) * new_shape_with_padding[2]; - T *src = this->get_element_ptr(); - int offset_dst_next_y = new_shape_with_padding[1] * new_shape_with_padding[2]; // width * channel - int src_copy_length = this->shape[1] * this->shape[2]; // width * channel - int offset_src_next_y = this->shape_with_padding[1] * this->shape_with_padding[2]; // width * channel - for (int y = 0; y < this->shape[0]; y++) - { - tool::copy_memory(dst, src, src_copy_length * sizeof(T)); - dst += offset_dst_next_y; - src += offset_src_next_y; - } + /** + * @brief Insert a new dim that will appear at the axis position in the expanded Tensor shape. + * + * @param axis the dim to be inserted + * @return Tensor& self + */ + Tensor &expand_dims(int axis); - if (this->auto_free) - tool::free_aligned(this->element); - this->element = new_element; - this->auto_free = true; - } - this->padding = new_padding; - this->shape_with_padding = new_shape_with_padding; - this->size = new_size; - } - else if (this->shape.size() == 2) - { - printf("Tensor.set_padding_size with this->shape.size() == 2 not implement yet.\n"); - } + /** + * @brief Insert a new dim that will appear at the axis position in the expanded Tensor shape. + * + * @param axis the dim to be inserted + * @return Tensor& self + */ + Tensor &expand_dims(std::vector axis); - return *this; - } + /** + * @brief Reverse or permute the axes of the Tensor + * + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @return Tensor& self + */ + Tensor &transpose(std::vector perm = {}); /** - * @brief Set the padding value object. + * @brief Reverse or permute the axes of the input Tensor * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @param value value to set - * @return self + * @param input the input Tensor + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @return Tensor& self */ - Tensor &set_padding_value(std::vector &padding, T value); + Tensor &transpose(Tensor &input, std::vector perm = {}); /** * @brief Get the element pointer. * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @return pointer to memory with padding + * @return pointer to memory */ - T *get_element_ptr(const std::vector padding = {0, 0, 0, 0}) + T *get_element_ptr() { - assert(this->shape.size() == 3); // TODO: || this->shape.size() == 2 - - if (this->shape.size() == 3) - { - return this->element + ((this->padding[0] - padding[0]) * this->shape_with_padding[1] + (this->padding[2] - padding[2])) * this->shape_with_padding[2]; - } - else if (this->shape.size() == 2) - { - printf("Tensor.get_element_ptr with this->shape.size() == 2 is not implemented.\n"); - } - - return NULL; + return this->element; } /** * @brief Get the element value. * - * @param index index in - * - 2D: [y, x, c] - * @param with_padding one of true or false, - * - true: make padding size in count - * - false: do not - * @return element value + * @param index the index of each dim. + * @return T element value */ - T &get_element_value(const std::vector index, const bool with_padding = false) + T get_element_value(const std::vector index) { - assert(index.size() == this->shape.size()); - assert(this->shape.size() == 3); // TODO: || this->shape() == 2 - - int i = 0; - if (this->shape.size() == 3) - { - int y = index[0]; - int x = index[1]; - int c = index[2]; - i = with_padding ? (y * this->shape_with_padding[1] + x) * this->shape_with_padding[2] + c : ((y + this->padding[0]) * this->shape_with_padding[1] + x + this->padding[2]) * this->shape_with_padding[2] + c; - } - else if (this->shape.size() == 2) - { - printf("Tensor.get_element_value with this->shape.size() == 2 is not implemented.\n"); - } + return this->element[this->get_element_index(index)]; + } - return this->element[i]; + /** + * @brief Get the element value. + * + * @param index the index of the element. + * @return T element value + */ + T get_element_value(int index) + { + return this->element[index]; } /** - * @brief Get the size of element. + * @brief Get the size of Tensor. * - * @return size of element including padding + * @return the size of Tensor. */ int get_size() { - if (this->size == -1) // didn't call Tensor.set_padding_size() before - { - this->size = 1; - for (std::vector::iterator d = this->shape.begin(); d != this->shape.end(); d++) - this->size *= *d; - } - return this->size; } + /** + * @brief Get the axis offset + * + * @return std::vector the axis offset + */ + std::vector get_axis_offset() + { + return this->axis_offset; + } + /** * @brief Apply memory with zero-initialized only if this->element is NULL. * @@ -319,7 +293,7 @@ namespace dl if (this->element != NULL) return false; - this->element = (T *)dl::tool::calloc_aligned(this->get_size(), sizeof(T), 16); + this->element = (T *)dl::tool::calloc_aligned_prefer(this->get_size(), sizeof(T), 16); this->auto_free = auto_free; return true; @@ -340,31 +314,7 @@ namespace dl if (this->element != NULL) return false; - this->element = (T *)tool::malloc_aligned(this->get_size(), sizeof(T), 16); - this->auto_free = auto_free; - - return true; - } - - /** - * @brief If this->element != NULL no memory will be applied and no value will be set in padding. - * Else apply memory without initialized and set value to padding. - * - * @param padding_value value to set in padding - * @param auto_free one of true of false - * - true: free element when object destroyed - * - false: do not - * @return - * - true: apply memory and set padding value successfully - * - false: no memory applied and no padding value set - */ - bool apply_element(const T padding_value = 0, const bool auto_free = true) - { - if (this->element != NULL) - return false; - - this->element = (T *)tool::malloc_aligned(this->get_size(), sizeof(T), 16); - this->set_padding_value(this->padding, padding_value); + this->element = (T *)tool::malloc_aligned_prefer(this->get_size(), sizeof(T), 16); this->auto_free = auto_free; return true; @@ -379,258 +329,56 @@ namespace dl { if (this->auto_free && this->element) { - tool::free_aligned(this->element); + tool::free_aligned_prefer(this->element); this->element = NULL; } } /** - * @brief Print the shape of Tensor in format "shape = ({top_padding} + {height} + {bottom_padding}, {left_padding} + {width} + {right_padding}, {channel}(channel_with_padding))\n". + * @brief print the element of the tensor + * + * @param axis_index_range the element range of each dims to be print. if axis_index_range == {}, all the element will be print. + * @param message to print */ - void print_shape() - { - printf("shape = (%d + %d + %d, %d + %d + %d, %d(%d))\n", - this->padding[0], this->shape[0], this->padding[1], - this->padding[2], this->shape[1], this->padding[3], - this->shape[2], this->shape_with_padding[2]); - } + void print(std::vector axis_index_range = {}, const char *message = ""); /** - * @brief Take numpy for example, this function print Tensor[y_start:y_end, x_start:x_end, c_start:c_end]. + * @brief print all the element of the Tensor. * - * inner box is effective value of Tensor, "0" around is padding. - * - * (with padding) - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 000000(without padding) 00000000 - * 000000 00000000 - * 000000 00000000 - * 000000 effective value 00000000 - * 000000 00000000 - * 000000 00000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * - * @param y_start start index in height - * @param y_end end index in height - * @param x_start start index in width - * @param x_end end index in width - * @param c_start start index in channel - * @param c_end end index in channel - * @param message to print - * @param axis print aligned this axis, effective only if all y_end - y_start, x_end - x_start and c_end - c_start equals to 1 + * @param message to print * @param with_padding one of true or false, - * - true: count from (with padding) in upper image - * - false: count from (without padding) in upper image + * - true: the padding element will also be ed + * - false: the padding element will not be ed */ - void print(int y_start, int y_end, - int x_start, int x_end, - int c_start, int c_end, - const char *message, int axis = 0, const bool with_padding = false) + void print_all(const char *message = "") { - assert(y_end > y_start); - assert(x_end > x_start); - assert(c_end > c_start); - - y_start = DL_MAX(y_start, 0); - x_start = DL_MAX(x_start, 0); - c_start = DL_MAX(c_start, 0); - if (with_padding) - { - y_end = DL_MIN(y_end, this->shape_with_padding[0]); - x_end = DL_MIN(x_end, this->shape_with_padding[1]); - c_end = DL_MIN(c_end, this->shape_with_padding[2]); - } - else - { - y_end = DL_MIN(y_end, this->shape[0]); - x_end = DL_MIN(x_end, this->shape[1]); - c_end = DL_MIN(c_end, this->shape[2]); - } - - printf("%s[%d:%d, %d:%d, %d:%d] | ", message, y_start, y_end, x_start, x_end, c_start, c_end); + std::cout << "\n" + << message << " | "; this->print_shape(); - if (y_end - y_start == 1) - { - if (x_end - x_start == 1) - { - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y_start, x_start, c}, with_padding)); - printf("\n"); - - return; - } - else - { - if (c_end - c_start == 1) - { - for (int x = x_start; x < x_end; x++) - printf("%7d", x); - printf("\n"); - - for (int x = x_start; x < x_end; x++) - printf("%7d", this->get_element_value({y_start, x, c_start}, with_padding)); - printf("\n"); - - return; - } - } - } - else + for (int i = 0; i < this->get_size(); i++) { - if (x_end - x_start == 1) - { - if (c_end - c_start == 1) - { - for (int y = y_start; y < y_end; y++) - printf("%7d", y); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - printf("%7d", this->get_element_value({y, x_start, c_start}, with_padding)); - printf("\n"); - - return; - } - } + std::cout << this->element[i] << " "; } - - if (y_end - y_start == 1) - axis = 0; - - if (x_end - x_start == 1) - axis = 1; - - if (c_end - c_start == 1) - axis = 2; - - if (axis == 0) - { - // ______c - // | - // | - // x - // - for (int y = y_start; y < y_end; y++) - { - printf("y = %d\n ", y); - - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int x = x_start; x < x_end; x++) - { - printf("%5d", x); - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - else if (axis == 1) - { - // ______c - // | - // | - // y - // - for (int x = x_start; x < x_end; x++) - { - printf("x = %d\n ", x); - - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - { - printf("%5d", y); - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - else - { - // ______x - // | - // | - // y - // - for (int c = c_start; c < c_end; c++) - { - printf("c = %d\n ", c); - - for (int x = x_start; x < x_end; x++) - printf("%7d", x); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - { - printf("%5d", y); - for (int x = x_start; x < x_end; x++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - + std::cout << "\n"; return; } /** - * @brief print all the element of the Tensor. + * @brief Get the index of each dims * - * @param message to print - * @param with_padding one of true or false, - * - true: the padding element will also be printed - * - false: the padding element will not be printed + * @param element_index the index of the element + * @return std::vector the index of each dims */ - void print_all(const char *message, const bool with_padding = false) - { - int y_end; - int x_end; - int c_end; - if (with_padding) - { - y_end = this->shape_with_padding[0]; - x_end = this->shape_with_padding[1]; - c_end = this->shape_with_padding[2]; - } - else - { - y_end = this->shape[0]; - x_end = this->shape[1]; - c_end = this->shape[2]; - } + std::vector get_axis_index(int element_index); - printf("\n%s | ", message); - this->print_shape(); - - for (int y = 0; y < y_end; y++) - { - for (int x = 0; x < x_end; x++) - { - for (int c = 0; c < c_end; c++) - printf("%d ", this->get_element_value({y, x, c}, with_padding)); - } - } - printf("\n"); - return; - } + /** + * @brief Get the index of element + * + * @param axis_index the index of each dims + * @return int the index of element + */ + int get_element_index(const std::vector axis_index); /** * @brief Check the element value with input ground-truth. @@ -638,35 +386,39 @@ namespace dl * @param gt_element ground-truth value of element * @param bias permissible error * @param info one of true or false - * - true: print shape and result + * - true: shape and result * - false: do not + * @param failed_number maximum number of wrong element that will be printed + * * @return * - true: in permissible error * - false: not */ - bool check_element(T *gt_element, int bias = 2, bool info = true) + bool check_element(T *gt_element, int bias = 2, bool info = true, int failed_number = 0) { + int count = 0; if (info) this->print_shape(); - int i = 0; - for (int y = 0; y < this->shape[0]; y++) + int size = this->get_size(); + for (int i = 0; i < size; i++) { - for (int x = 0; x < this->shape[1]; x++) + if (DL_ABS(this->element[i] - gt_element[i]) > bias) { - for (int c = 0; c < this->shape[2]; c++) + std::vector index = get_axis_index(i); + std::cout << "element["; + for (int j = 0; j < index.size() - 1; j++) { - int a = this->get_element_value({y, x, c}); - int b = gt_element[i]; - int offset = DL_ABS(a - b); - if (offset > bias) - { - printf("element[%d, %d, %d]: %d v.s. %d\n", y, x, c, a, b); - return false; - } - i++; + std::cout << index[j] << ", "; } + std::cout << index.back() << "]: "; + std::cout << +this->element[i] << " v.s. " << +gt_element[i] << "\n"; + count++; + if (count > failed_number) + return false; } } + if (count) + return false; if (info) printf("PASS\n"); @@ -700,35 +452,44 @@ namespace dl Tensor &operator=(const Tensor &input) { - this->size = input.size; this->auto_free = input.auto_free; this->exponent = input.exponent; - this->shape = input.shape; - this->padding = input.padding; - int size_real_tmp = this->shape_with_padding.size() ? this->shape_with_padding[0] * this->shape_with_padding[1] * this->shape_with_padding[2] : 0; - int size_input_real = input.shape_with_padding.size() ? input.shape_with_padding[0] * input.shape_with_padding[1] * input.shape_with_padding[2] : 0; - this->shape_with_padding = input.shape_with_padding; - if (this->element) + int size_real_tmp = this->size; + int size_input_real = input.size; + this->set_shape(input.shape); + if (input.element) { - if (size_real_tmp != size_input_real) + if (this->element) { - tool::free_aligned(this->element); - T *new_element = (T *)tool::calloc_aligned(size_input_real, sizeof(T), 16); - tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); - this->element = new_element; + if (size_real_tmp != size_input_real) + { + tool::free_aligned_prefer(this->element); + T *new_element = (T *)tool::malloc_aligned_prefer(size_input_real, sizeof(T), 16); + tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); + this->element = new_element; + } + else + { + tool::copy_memory(this->element, input.element, size_input_real * sizeof(T)); + } } else { - tool::copy_memory(this->element, input.element, size_input_real * sizeof(T)); + T *new_element = (T *)tool::malloc_aligned_prefer(size_input_real, sizeof(T), 16); + tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); + this->element = new_element; } + return *this; } else { - T *new_element = (T *)tool::calloc_aligned(size_input_real, sizeof(T), 16); - tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); - this->element = new_element; + if (this->element) + { + tool::free_aligned_prefer(this->element); + this->element = NULL; + } + return *this; } - return *this; } }; } // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/lib/include/cat_face_3.h b/tools/sdk/esp32/include/esp-face/lib/include/cat_face_3.h new file mode 100644 index 00000000000..42d6fa85821 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/cat_face_3.h @@ -0,0 +1,40 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is free of charge, to any person_body 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. + * + */ + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" +#include "detection.h" + + extern detection_model_t cat_face_3_model; + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/lib/include/detection.h b/tools/sdk/esp32/include/esp-face/lib/include/detection.h new file mode 100644 index 00000000000..0bba4f49b6f --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/detection.h @@ -0,0 +1,87 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" + + typedef enum + { + Anchor_Point, /* +#include +#include +#include +#include +#include + +#if CONFIG_SPIRAM_SUPPORT || CONFIG_ESP32_SPIRAM_SUPPORT +#include "freertos/FreeRTOS.h" +#define DL_SPIRAM_SUPPORT 1 +#else +#define DL_SPIRAM_SUPPORT 0 +#endif + + +#ifndef max +#define max(x, y) (((x) < (y)) ? (y) : (x)) +#endif + +#ifndef min +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +typedef float fptp_t; +typedef uint8_t uc_t; + +typedef enum +{ + DL_SUCCESS = 0, + DL_FAIL = 1, +} dl_error_type; + +typedef enum +{ + PADDING_VALID = 0, /*!< Valid padding */ + PADDING_SAME = 1, /*!< Same padding, from right to left, free input */ + PADDING_SAME_DONT_FREE_INPUT = 2, /*!< Same padding, from right to left, do not free input */ + PADDING_SAME_MXNET = 3, /*!< Same padding, from left to right */ +} dl_padding_type; + +typedef enum +{ + DL_POOLING_MAX = 0, /*!< Max pooling */ + DL_POOLING_AVG = 1, /*!< Average pooling */ +} dl_pooling_type; +/* + * Matrix for 3d + * @Warning: the sequence of variables is fixed, cannot be modified, otherwise there will be errors in esp_dsp_dot_float + */ +typedef struct +{ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + fptp_t *item; /*!< Data */ +} dl_matrix3d_t; + +typedef struct +{ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + uc_t *item; /*!< Data */ +} dl_matrix3du_t; + +typedef enum +{ + UPSAMPLE_NEAREST_NEIGHBOR = 0, /*!< Use nearest neighbor interpolation as the upsample method*/ + UPSAMPLE_BILINEAR = 1, /*!< Use nearest bilinear interpolation as the upsample method*/ +} dl_upsample_type; + +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ +} dl_matrix3d_mobilenet_config_t; + +/* + * @brief Allocate a zero-initialized space. Must use 'dl_lib_free' to free the memory. + * + * @param cnt Count of units. + * @param size Size of unit. + * @param align Align of memory. If not required, set 0. + * @return Pointer of allocated memory. Null for failed. + */ +static void *dl_lib_calloc(int cnt, int size, int align) +{ + int total_size = cnt * size + align + sizeof(void *); + void *res = malloc(total_size); + if (NULL == res) + { +#if DL_SPIRAM_SUPPORT + res = heap_caps_malloc(total_size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + } + if (NULL == res) + { + printf("Item psram alloc failed. Size: %d x %d\n", cnt, size); +#else + printf("Item alloc failed. Size: %d x %d, SPIRAM_FLAG: %d\n", cnt, size, DL_SPIRAM_SUPPORT); +#endif + return NULL; + } + bzero(res, total_size); + void **data = (void **)res + 1; + void **aligned; + if (align) + aligned = (void **)(((size_t)data + (align - 1)) & -align); + else + aligned = data; + + aligned[-1] = res; + return (void *)aligned; +} + +/** + * @brief Free the memory space allocated by 'dl_lib_calloc' + * + */ +static inline void dl_lib_free(void *d) +{ + if (NULL == d) + return; + + free(((void **)d)[-1]); +} + +/* + * @brief Allocate a 3D matrix with float items, the access sequence is NHWC + * + * @param n Number of matrix3d, for filters it is out channels, for others it is 1 + * @param w Width of matrix3d + * @param h Height of matrix3d + * @param c Channel of matrix3d + * @return 3d matrix + */ +static inline dl_matrix3d_t *dl_matrix3d_alloc(int n, int w, int h, int c) +{ + dl_matrix3d_t *r = (dl_matrix3d_t *)dl_lib_calloc(1, sizeof(dl_matrix3d_t), 0); + if (NULL == r) + { + printf("internal r failed.\n"); + return NULL; + } + fptp_t *items = (fptp_t *)dl_lib_calloc(n * w * h * c, sizeof(fptp_t), 0); + if (NULL == items) + { + printf("matrix3d item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Allocate a 3D matrix with 8-bits items, the access sequence is NHWC + * + * @param n Number of matrix3d, for filters it is out channels, for others it is 1 + * @param w Width of matrix3d + * @param h Height of matrix3d + * @param c Channel of matrix3d + * @return 3d matrix + */ +static inline dl_matrix3du_t *dl_matrix3du_alloc(int n, int w, int h, int c) +{ + dl_matrix3du_t *r = (dl_matrix3du_t *)dl_lib_calloc(1, sizeof(dl_matrix3du_t), 0); + if (NULL == r) + { + printf("internal r failed.\n"); + return NULL; + } + uc_t *items = (uc_t *)dl_lib_calloc(n * w * h * c, sizeof(uc_t), 0); + if (NULL == items) + { + printf("matrix3du item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Free a matrix3d + * + * @param m matrix3d with float items + */ +static inline void dl_matrix3d_free(dl_matrix3d_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + +/* + * @brief Free a matrix3d + * + * @param m matrix3d with 8-bits items + */ +static inline void dl_matrix3du_free(dl_matrix3du_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + + +/* + * @brief Dot product with a vector and matrix + * + * @param out Space to put the result + * @param in input vector + * @param f filter matrix + */ +void dl_matrix3dff_dot_product(dl_matrix3d_t *out, dl_matrix3d_t *in, dl_matrix3d_t *f); + +/** + * @brief Do a softmax operation on a matrix3d + * + * @param in Input matrix3d + */ +void dl_matrix3d_softmax(dl_matrix3d_t *m); + +/** + * @brief Copy a range of float items from an existing matrix to a preallocated matrix + * + * @param dst The destination slice matrix + * @param src The source matrix to slice + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3d_slice_copy(dl_matrix3d_t *dst, + dl_matrix3d_t *src, + int x, + int y, + int w, + int h); + +/** + * @brief Copy a range of 8-bits items from an existing matrix to a preallocated matrix + * + * @param dst The destination slice matrix + * @param src The source matrix to slice + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3du_slice_copy(dl_matrix3du_t *dst, + dl_matrix3du_t *src, + int x, + int y, + int w, + int h); + +/** + * @brief Transform a sliced matrix block from nhwc to nchw, the block needs to be memory continous. + * + * @param out The destination sliced matrix in nchw + * @param in The source sliced matrix in nhwc + */ +void dl_matrix3d_sliced_transform_nchw(dl_matrix3d_t *out, + dl_matrix3d_t *in); + +/** + * @brief Do a general CNN layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return dl_matrix3d_t* The result of CNN layer + */ +dl_matrix3d_t *dl_matrix3d_conv(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + int padding, + int mode); + +/** + * @brief Do a global average pooling layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * + * @return The result of global average pooling layer + */ +dl_matrix3d_t *dl_matrix3d_global_pool(dl_matrix3d_t *in); + +/** + * @brief Calculate pooling layer of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @param f_w Window width + * @param f_h Window height + * @param stride_x Stride in horizontal direction + * @param stride_y Stride in vertical direction + * @param padding Padding type: PADDING_VALID and PADDING_SAME + * @param pooling_type Pooling type: DL_POOLING_MAX and POOLING_AVG + * @return dl_matrix3d_t* Resulting matrix, size (1, w', h', c) + */ +dl_matrix3d_t *dl_matrix3d_pooling(dl_matrix3d_t *in, + int f_w, + int f_h, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_pooling_type pooling_type); +/** + * @brief Do a batch normalization operation, update the input matrix3d: input = input * scale + offset + * + * @param m Input matrix3d + * @param scale scale matrix3d, scale = gamma/((moving_variance+sigma)^(1/2)) + * @param Offset Offset matrix3d, offset = beta-(moving_mean*gamma/((moving_variance+sigma)^(1/2))) + */ +void dl_matrix3d_batch_normalize(dl_matrix3d_t *m, + dl_matrix3d_t *scale, + dl_matrix3d_t *offset); + +/** + * @brief Add a pair of matrix3d item-by-item: res=in_1+in_2 + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * + * @return dl_matrix3d_t* Added data + */ +dl_matrix3d_t *dl_matrix3d_add(dl_matrix3d_t *in_1, dl_matrix3d_t *in_2); + +/** + * @brief Concatenate the channels of two matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * + * @return dl_matrix3d_t* A newly allocated matrix3d with as avlues in_1|in_2 + */ +dl_matrix3d_t *dl_matrix3d_concat(dl_matrix3d_t *in_1, dl_matrix3d_t *in_2); + +/** + * @brief Concatenate the channels of four matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * @param in_3 Third Floating point input matrix3d + * @param in_4 Fourth Floating point input matrix3d + * + * @return A newly allocated matrix3d with as avlues in_1|in_2|in_3|in_4 + */ +dl_matrix3d_t *dl_matrix3d_concat_4(dl_matrix3d_t *in_1, + dl_matrix3d_t *in_2, + dl_matrix3d_t *in_3, + dl_matrix3d_t *in_4); + +/** + * @brief Concatenate the channels of eight matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * @param in_3 Third Floating point input matrix3d + * @param in_4 Fourth Floating point input matrix3d + * @param in_5 Fifth Floating point input matrix3d + * @param in_6 Sixth Floating point input matrix3d + * @param in_7 Seventh Floating point input matrix3d + * @param in_8 eighth Floating point input matrix3d + * + * @return A newly allocated matrix3d with as avlues in_1|in_2|in_3|in_4|in_5|in_6|in_7|in_8 + */ +dl_matrix3d_t *dl_matrix3d_concat_8(dl_matrix3d_t *in_1, + dl_matrix3d_t *in_2, + dl_matrix3d_t *in_3, + dl_matrix3d_t *in_4, + dl_matrix3d_t *in_5, + dl_matrix3d_t *in_6, + dl_matrix3d_t *in_7, + dl_matrix3d_t *in_8); + +/** + * @brief Do a mobilefacenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param pw Weights of the pointwise conv layer + * @param pw_bn_scale The scale params of the batch_normalize layer after the pointwise conv layer + * @param pw_bn_offset The offset params of the batch_normalize layer after the pointwise conv layer + * @param dw Weights of the depthwise conv layer + * @param dw_bn_scale The scale params of the batch_normalize layer after the depthwise conv layer + * @param dw_bn_offset The offset params of the batch_normalize layer after the depthwise conv layer + * @param pw_linear Weights of the pointwise linear conv layer + * @param pw_linear_bn_scale The scale params of the batch_normalize layer after the pointwise linear conv layer + * @param pw_linear_bn_offset The offset params of the batch_normalize layer after the pointwise linear conv layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of a mobilefacenet block + */ +dl_matrix3d_t *dl_matrix3d_mobilefaceblock(dl_matrix3d_t *in, + dl_matrix3d_t *pw, + dl_matrix3d_t *pw_bn_scale, + dl_matrix3d_t *pw_bn_offset, + dl_matrix3d_t *dw, + dl_matrix3d_t *dw_bn_scale, + dl_matrix3d_t *dw_bn_offset, + dl_matrix3d_t *pw_linear, + dl_matrix3d_t *pw_linear_bn_scale, + dl_matrix3d_t *pw_linear_bn_offset, + int stride_x, + int stride_y, + int padding, + int mode, + int shortcut); + +/** + * @brief Do a mobilefacenet block forward with 1x1 split conv, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param pw_1 Weights of the pointwise conv layer 1 + * @param pw_2 Weights of the pointwise conv layer 2 + * @param pw_bn_scale The scale params of the batch_normalize layer after the pointwise conv layer + * @param pw_bn_offset The offset params of the batch_normalize layer after the pointwise conv layer + * @param dw Weights of the depthwise conv layer + * @param dw_bn_scale The scale params of the batch_normalize layer after the depthwise conv layer + * @param dw_bn_offset The offset params of the batch_normalize layer after the depthwise conv layer + * @param pw_linear_1 Weights of the pointwise linear conv layer 1 + * @param pw_linear_2 Weights of the pointwise linear conv layer 2 + * @param pw_linear_bn_scale The scale params of the batch_normalize layer after the pointwise linear conv layer + * @param pw_linear_bn_offset The offset params of the batch_normalize layer after the pointwise linear conv layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of a mobilefacenet block + */ +dl_matrix3d_t *dl_matrix3d_mobilefaceblock_split(dl_matrix3d_t *in, + dl_matrix3d_t *pw_1, + dl_matrix3d_t *pw_2, + dl_matrix3d_t *pw_bn_scale, + dl_matrix3d_t *pw_bn_offset, + dl_matrix3d_t *dw, + dl_matrix3d_t *dw_bn_scale, + dl_matrix3d_t *dw_bn_offset, + dl_matrix3d_t *pw_linear_1, + dl_matrix3d_t *pw_linear_2, + dl_matrix3d_t *pw_linear_bn_scale, + dl_matrix3d_t *pw_linear_bn_offset, + int stride_x, + int stride_y, + int padding, + int mode, + int shortcut); + +/** + * @brief Initialize the matrix3d feature map to bias + * + * @param out The matrix3d feature map needs to be initialized + * @param bias The bias of a convlotion operation + */ +void dl_matrix3d_init_bias(dl_matrix3d_t *out, dl_matrix3d_t *bias); + +/** + * @brief Do a elementwise multiplication of two matrix3ds + * + * @param out Preallocated matrix3d, size (n, w, h, c) + * @param in1 Input matrix 1, size (n, w, h, c) + * @param in2 Input matrix 2, size (n, w, h, c) + */ +void dl_matrix3d_multiply(dl_matrix3d_t *out, dl_matrix3d_t *in1, dl_matrix3d_t *in2); + +// +// Activation +// + +/** + * @brief Do a standard relu operation, update the input matrix3d + * + * @param m Floating point input matrix3d + */ +void dl_matrix3d_relu(dl_matrix3d_t *m); + +/** + * @brief Do a relu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param clip If value is higher than this, it will be clipped to this value + */ +void dl_matrix3d_relu_clip(dl_matrix3d_t *m, fptp_t clip); + +/** + * @brief Do a Prelu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param alpha If value is less than zero, it will be updated by multiplying this factor + */ +void dl_matrix3d_p_relu(dl_matrix3d_t *in, dl_matrix3d_t *alpha); + +/** + * @brief Do a leaky relu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param alpha If value is less than zero, it will be updated by multiplying this factor + */ +void dl_matrix3d_leaky_relu(dl_matrix3d_t *m, fptp_t alpha); + +// +// Conv 1x1 +// +/** + * @brief Do 1x1 convolution with a matrix3d + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + */ +void dl_matrix3dff_conv_1x1(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do 1x1 convolution with a matrix3d, with bias adding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + */ +void dl_matrix3dff_conv_1x1_with_bias(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + */ +void dl_matrix3duf_conv_1x1(dl_matrix3d_t *out, + dl_matrix3du_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + */ +void dl_matrix3duf_conv_1x1_with_bias(dl_matrix3d_t *out, + dl_matrix3du_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +// +// Conv 3x3 +// + +/** + * @brief Do 3x3 convolution with a matrix3d, without padding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (n, 3, 3, c) + * @param step_x Stride of width + * @param step_y Stride of height + */ +void dl_matrix3dff_conv_3x3_op(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *f, + int step_x, + int step_y); + +/** + * @brief Do 3x3 convolution with a matrix3d, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_conv_3x3(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// Conv Common +// + +/** + * @brief Do a general convolution layer pass with an 8-bit fixed point matrix, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3duf_conv_common(dl_matrix3du_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +/** + * @brief Do a general convolution layer pass, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_conv_common(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// Depthwise 3x3 +// + +/** + * @brief Do 3x3 depthwise convolution with a float matrix3d + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @return dl_matrix3d_t* Resulting float matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_depthwise_conv_3x3(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + int padding); + +/** + * @brief Do 3x3 depthwise convolution with a 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @return dl_matrix3d_t* Resulting float matrix3d + */ +dl_matrix3d_t *dl_matrix3duf_depthwise_conv_3x3(dl_matrix3du_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + int padding); + +/** + * @brief Do 3x3 depthwise convolution with a float matrix3d, without padding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param step_x Stride of width + * @param step_y Stride of height + */ +void dl_matrix3dff_depthwise_conv_3x3_op(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *f, + int step_x, + int step_y); + +// +// Depthwise Common +// + +/** + * @brief Do a depthwise CNN layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3dff_depthwise_conv_common(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// FC +// +/** + * @brief Do a general fully connected layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d, size is (1, w, 1, 1) + * @param filter Weights of the neurons, size is (1, w, h, 1) + * @param bias Bias for the fc layer, size is (1, 1, 1, h) + * @return The result of fc layer, size is (1, 1, 1, h) + */ +void dl_matrix3dff_fc(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do fully connected layer forward, with bias adding + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param bias Bias matrix, size (1, 1, 1, h) + */ +void dl_matrix3dff_fc_with_bias(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +// +// Mobilenet +// + +/** + * @brief Do a mobilenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3dff_mobilenet(dl_matrix3d_t *in, + dl_matrix3d_t *dilate_filter, + dl_matrix3d_t *dilate_prelu, + dl_matrix3d_t *depthwise_filter, + dl_matrix3d_t *depthwise_prelu, + dl_matrix3d_t *compress_filter, + dl_matrix3d_t *bias, + dl_matrix3d_mobilenet_config_t config); + +/** + * @brief Do a mobilenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3du + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3duf_mobilenet(dl_matrix3du_t *in, + dl_matrix3d_t *dilate_filter, + dl_matrix3d_t *dilate_prelu, + dl_matrix3d_t *depthwise_filter, + dl_matrix3d_t *depthwise_prelu, + dl_matrix3d_t *compress_filter, + dl_matrix3d_t *bias, + dl_matrix3d_mobilenet_config_t config); diff --git a/tools/sdk/esp32/include/esp-face/lib/include/dl_lib_matrix3dq.h b/tools/sdk/esp32/include/esp-face/lib/include/dl_lib_matrix3dq.h new file mode 100644 index 00000000000..0d982b4a0e0 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/dl_lib_matrix3dq.h @@ -0,0 +1,1441 @@ +#pragma once +#include "dl_lib_matrix3d.h" + +typedef int16_t qtp_t; + +/** + * Matrix for input, filter, and output + * @Warning: the sequence of variables is fixed, cannot be modified, otherwise there will be errors in + * some handwrite xtensa instruction functions + */ +typedef struct +{ + /******* fix start *******/ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + int exponent; /*!< Exponent for quantization */ + qtp_t *item; /*!< Data */ + /******* fix end *******/ +} dl_matrix3dq_t; + +#ifndef DL_QTP_SHIFT +#define DL_QTP_SHIFT 15 +#define DL_ITMQ(m, x, y) m->itemq[(y) + (x)*m->stride] +#define DL_QTP_RANGE ((1 << DL_QTP_SHIFT) - 1) +#define DL_QTP_MAX 32767 +#define DL_QTP_MIN -32768 + +#define DL_QTP_EXP_NA 255 //non-applicable exponent because matrix is null + +#define DL_SHIFT_AUTO 32 +#endif + +/** + * Implementation of matrix relative operations + */ +typedef enum +{ + DL_C_IMPL = 0, /*!< ANSI C */ + DL_XTENSA_IMPL = 1 /*!< Handwrite xtensa instruction */ +} dl_conv_mode; + +/** + * Configuration of mobilenet operation + */ +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ + dl_conv_mode mode; /*!< Implementation mode */ + int dilate_exponent; /*!< Exponent of dilation filter */ + int depthwise_exponent; /*!< Exponent of depthwise filter */ + int compress_exponent; /*!< Exponent of compress filter */ +} dl_matrix3dq_mobilenet_config_t; + +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ + dl_conv_mode mode; /*!< Implementation mode */ + int dw1_exponent; /*!< Exponent of dw1 filter */ + int pw1_exponent; /*!< Exponent of pw1 filter */ + int dw2_exponent; /*!< Exponent of dw2 filter */ + int pw2_exponent; /*!< Exponent of pw2 filter */ + int shortcut; /*!< Shortcut connection flag */ + int save_input; /*!< Input save flag */ +} dl_matrix3dq_blazeblock_config_t; + +// +// Utility +// + +/* + * @brief Allocate a 3d quantised matrix + * + * @param n Number of filters, for input and output, should be 1 + * @param w Width of matrix + * @param h Height of matrix + * @param c Channel of matrix + * @param e Exponent of matrix data + * @return 3d quantized matrix + */ +static inline dl_matrix3dq_t *dl_matrix3dq_alloc(int n, int w, int h, int c, int e) +{ + dl_matrix3dq_t *r = (dl_matrix3dq_t *)dl_lib_calloc(1, sizeof(dl_matrix3dq_t), 0); + if (NULL == r) + { + printf("dl_matrix3dq alloc failed.\n"); + return NULL; + } + + qtp_t *items = (qtp_t *)dl_lib_calloc(n * w * h * c, sizeof(qtp_t), 16); + if (NULL == items) + { + printf("matrix3dq item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->exponent = e; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Free a 3d quantized matrix + * + * @param m 3d quantised matrix + */ +static inline void dl_matrix3dq_free(dl_matrix3dq_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + + +/** + * @brief Copy a range of items from an existing matrix to a preallocated matrix + * + * @param dst The resulting slice matrix + * @param src Old matrix to slice. + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3dq_slice_copy(dl_matrix3dq_t *dst, dl_matrix3dq_t *src, int x, int y, int w, int h); + +/** + * @brief Transform a sliced matrix block from nhwc to nchw, the block needs to be memory continous. + * + * @param out The destination sliced matrix in nchw + * @param in The source sliced matrix in nhwc + */ +void dl_matrix3dq_sliced_transform_nchw(dl_matrix3dq_t *out, + dl_matrix3dq_t *in); + +/** + * @brief Transform a fixed point matrix to a float point matrix + * + * @param m Quantized matrix + * @return Float point matrix + */ +dl_matrix3d_t *dl_matrix3d_from_matrixq(dl_matrix3dq_t *m); + +/** + * @brief Transform a float point matrix to a fixed point matrix with pre-defined exponent + * + * @param m Float point matrix + * @param exponent Exponent for resulting matrix + * @return Fixed point matrix + */ +dl_matrix3dq_t *dl_matrixq_from_matrix3d_qmf(dl_matrix3d_t *m, int exponent); + +/** + * @brief Transform a float point matrix to a fixed point matrix. The exponent is defined by the distribution of the input matrix. + * + * @param m Float point matrix + * @return Fixed point matrix + */ +dl_matrix3dq_t *dl_matrixq_from_matrix3d(dl_matrix3d_t *m); + +/** + * @brief Truncate the overflowed 16bit number + * + * @param value Input value + * @param location Location tag + * @return qtp_t Truncated value + */ +qtp_t dl_matrix3dq_quant_range_exceeded_checking(int64_t value, char *location); + +/** + * @brief Reform a quantized matrix with exponent + * + * @param out Preallocated resulting matrix + * @param in Input matrix + * @param exponent Exponent for resulting matrix + */ +void dl_matrix3dq_shift_exponent(dl_matrix3dq_t *out, dl_matrix3dq_t *in, int exponent); + +/** + * @brief Do batch normalization for a quantized matrix + * + * @param m Input and output quantized matrix, data will be updated + * @param scale Scale of batch-norm + * @param offset Offset of batch-norm + */ +void dl_matrix3dq_batch_normalize(dl_matrix3dq_t *m, dl_matrix3dq_t *scale, dl_matrix3dq_t *offset); + +/** + * @brief Add two quantized matrix with a pre-defined exponent + * + * @param in_1 Adder 1 + * @param in_2 Adder 2 + * @param exponent Exponent for resulting matrix + * @return dl_matrix3dq_t* Result of accumulation of two matrix + */ +dl_matrix3dq_t *dl_matrix3dq_add(dl_matrix3dq_t *in_1, dl_matrix3dq_t *in_2, int exponent); + +/** + * @brief Add two quantized matrix with different channels + * + * @param in_1 Adder 1 + * @param in_2 Adder 2 + * @param exponent Exponent for resulting matrix + * @return dl_matrix3dq_t* Result of accumulation of two matrix + */ +dl_matrix3dq_t *dl_matrix3dq_add_channel_diff(dl_matrix3dq_t *in_1, dl_matrix3dq_t *in_2, int exponent); + +// +// Activation +// +/** + * @brief Do relu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + */ +void dl_matrix3dq_relu(dl_matrix3dq_t *in); + +/** + * @brief Do relu with clips for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param clip Float point value to limit the maximum data + */ +void dl_matrix3dq_relu_clip(dl_matrix3dq_t *in, fptp_t clip); + +/** + * @brief Do leaky relu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param alpha Float point value to multiply for those less than zero + * @param clip Float point value to limit the maximum data + */ +void dl_matrix3dq_leaky_relu(dl_matrix3dq_t *in, fptp_t alpha, fptp_t clip); + +/** + * @brief Do prelu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param alpha Quantized matrix to multiply for those less than zero + */ +void dl_matrix3dq_p_relu(dl_matrix3dq_t *in, dl_matrix3dq_t *alpha); + +// +// Concat +// +/** + * @brief Concatenate two quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of in_1 and in_2, and with the sum of channel number of in_1 and in_2 + */ +dl_matrix3dq_t *dl_matrix3dq_concat(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2); + +/** + * @brief Concatenate four quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @param in_3 Quantized matrix to be concatenated + * @param in_4 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of all inputs, and with the sum of channel number of all inputs + */ +dl_matrix3dq_t *dl_matrix3dq_concat_4(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2, + dl_matrix3dq_t *in_3, + dl_matrix3dq_t *in_4); + +/** + * @brief Concatenate four quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @param in_3 Quantized matrix to be concatenated + * @param in_4 Quantized matrix to be concatenated + * @param in_5 Quantized matrix to be concatenated + * @param in_6 Quantized matrix to be concatenated + * @param in_7 Quantized matrix to be concatenated + * @param in_8 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of all inputs, and with the sum of channel number of all inputs + */ +dl_matrix3dq_t *dl_matrix3dq_concat_8(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2, + dl_matrix3dq_t *in_3, + dl_matrix3dq_t *in_4, + dl_matrix3dq_t *in_5, + dl_matrix3dq_t *in_6, + dl_matrix3dq_t *in_7, + dl_matrix3dq_t *in_8); + +// +// Conv 1x1 +// +/** + * @brief Do 1x1 convolution with a quantized matrix + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with relu activation + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_relu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_bias(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_bias_relu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with prelu activation + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_prelu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3duq_conv_1x1(dl_matrix3dq_t *out, + dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3duq_conv_1x1_with_bias(dl_matrix3dq_t *out, + dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +// +// Conv 3x3 +// + +/** + * @brief Do 3x3 convolution with a quantized matrix + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding, relu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias_relu(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_conv_3x3_with_bias(dl_matrix3du_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with an 8-bit fixed point matrix, with bias adding, prelu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param prelu prelu params, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_conv_3x3_with_bias_prelu(dl_matrix3du_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding, prelu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param prelu prelu params, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias_prelu(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); +// +// Conv common +// + +/** + * @brief Do a general convolution layer pass, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer. + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect. + * If ESP_PLATFORM is not defined, this value is not used. + * @return The result of CNN layer. + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_common(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +/** + * @brief Do a general convolution layer pass for an 8-bit fixed point matrix, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer. + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect. + * If ESP_PLATFORM is not defined, this value is not used. + * @return The result of CNN layer. + */ +dl_matrix3dq_t *dl_matrix3duq_conv_common(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +// +// Depthwise 3x3 +// +/** + * @brief Do 3x3 depthwise convolution with an 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_depthwise_conv_3x3(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param relu ReLU, 0: don't, 1: do + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int relu, + int exponent, + char *name); + +#if CONFIG_DEVELOPING_CODE +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_3(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); +#endif + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding and stride 1 + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3s1_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do global depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param filter filter, size (1, w, h, c) + * @param bias Bias, size (1, 1, 1, c) + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_global_depthwise_conv_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int exponent, + char *name); + + + +// +// Depthwise 2x2 +// +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 2x2 filter, size (1, 2, 2, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 2x2 filter, size (1, 2, 2, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 2x2 filter, size (1, 2, 2, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 2x2 filter, size (1, 2, 2, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +// +// Depthwise 5x5 +// +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 5x5 filter, size (1, 5, 5, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 5x5 filter, size (1, 5, 5, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 5x5 filter, size (1, 5, 5, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 5x5 filter, size (1, 5, 5, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +// +// Depthwise Common +// +#if CONFIG_DEVELOPING_CODE +/** + * @brief Do a general depthwise convolution layer pass with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter Weights of the neurons, size (1, k_w, k_h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param mode Implementation mode + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_common(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +/** + * @brief Do a general depthwise convolution layer pass with an 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter Weights of the neurons, size (1, k_w, k_h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param mode Implementation mode + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_depthwise_conv_common(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); +#endif + +// +// Dot Product +// + +/** + * @brief Do dot product operation with a quantized matrix + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param mode Implementation mode + */ +void dl_matrix3dqq_dot_product(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode); + +// +// FC +// +/** + * @brief Do fully connected layer forward. + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_fc(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do fully connected layer forward, with bias adding + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param bias Bias matrix, size (1, 1, 1, h) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_fc_with_bias(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +// +// Mobilefaceblock +// +/** + * @brief Do mobilefacenet process with splited pointwise 1x1 convolution, the process sequence is 1x1 pointwise->bn->relu->3x3 depthwise->bn->relu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw_1 Pointwise 1x1 filter, size (n1/2, 1, 1, c) + * @param pw_2 Pointwise 1x1 filter, size (n1/2, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw_linear_1 Pointwise 1x1 filter, size (n2/2, 1, 1, n1) + * @param pw_linear_2 Pointwise 1x1 filter, size (n2/2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_split(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->relu->3x3 depthwise->bn->relu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw_linear Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *pw_linear, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->prelu->3x3 depthwise->bn->prelu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param pw_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param dw_prelu Depthwise prelu, size(1, 1, 1, n1) + * @param pw_linear Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Depthwise Convlution Padding type + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/**@{*/ +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->prelu->3x3 depthwise->bn->prelu->1x1 pointwise->bn + * + * Compared to ‘dl_matrix3dqq_mobilefaceblock_prelu’, this family of functions 'dl_matrix3dqq_mobilefaceblock_prelu_split_x1_x2' + * split the first pointwise convlution into x1 pointwise convlutions, and split the second pointwise convlution into x2 pointwise convlutions. + * + * + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_2_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_4_4(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_3, + dl_matrix3dq_t *pw_4, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_3, + dl_matrix3dq_t *pw_linear_4, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_1_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); +/**@}*/ + +// +// blazeblock +// + +/** + * @brief Do blazeblock process, the process sequence is depthwise->bn->1x1 pointwise->bn->shortcut->relu + * + * @param in Input matrix, size (1, w, h, c) + * @param dw1_kernel Depthwise filter, size (1, k, k, c) + * @param dw1_bias Depthwise bias, size (1, 1, 1, c) + * @param pw1_kernel Pointwise 1x1 filter, size (n, 1, 1, c) + * @param pw1_bias Pointwise bias, size (1, 1, 1, n) + * @param config blazeblock configuration + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_blazeblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *dw1_kernel, + dl_matrix3dq_t *dw1_bias, + dl_matrix3dq_t *pw1_kernel, + dl_matrix3dq_t *pw1_bias, + dl_matrix3dq_blazeblock_config_t config, + char *name); + +/** + * @brief Do double blazeblock process, the process sequence is depthwise->bn->1x1 pointwise->bn->relu->depthwise->bn->1x1 pointwise->bn->shortcut->relu + * + * @param in Input matrix, size (1, w, h, c) + * @param dw1_kernel Depthwise filter, size (1, k, k, c) + * @param dw1_bias Depthwise bias, size (1, 1, 1, c) + * @param pw1_kernel Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw1_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw2_kernel Depthwise filter, size (1, k, k, n1) + * @param dw2_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw2_kernel Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw2_bias Pointwise bias, size (1, 1, 1, n2) + * @param config blazeblock configuration + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_double_blazeblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *dw1_kernel, + dl_matrix3dq_t *dw1_bias, + dl_matrix3dq_t *pw1_kernel, + dl_matrix3dq_t *pw1_bias, + dl_matrix3dq_t *dw2_kernel, + dl_matrix3dq_t *dw2_bias, + dl_matrix3dq_t *pw2_kernel, + dl_matrix3dq_t *pw2_bias, + dl_matrix3dq_blazeblock_config_t config, + char *name); +// +// Mobilenet +// + +/** + * @brief Do mobilenet process, the process sequence is 1x1 dilated->prelu->3x3 depthwise->prelu->1x1 compress->bias + * + * @param in Input matrix, size (1, w, h, c) + * @param dilate Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param dilate_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param depthwise Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param depthwise_prelu Depthwise prelu, size (1, 1, 1, n1) + * @param compress Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param bias Pointwise bias, size (1, 1, 1, n2) + * @param config Mobilenet configuration + * @param name Block name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilenet(dl_matrix3dq_t *in, + dl_matrix3dq_t *dilate, + dl_matrix3dq_t *dilate_prelu, + dl_matrix3dq_t *depthwise, + dl_matrix3dq_t *depth_prelu, + dl_matrix3dq_t *compress, + dl_matrix3dq_t *bias, + dl_matrix3dq_mobilenet_config_t config, + char *name); + +/** + * @brief Do mobilenet process, the process sequence is 1x1 dilated->prelu->3x3 depthwise->prelu->1x1 compress->bias + * + * @param in Input matrix, 8-bit fixed point, size (1, w, h, c) + * @param dilate Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param dilate_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param depthwise Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param depthwise_prelu Depthwise prelu, size (1, 1, 1, n1) + * @param compress Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param bias Pointwise bias, size (1, 1, 1, n2) + * @param config Mobilenet configuration + * @param name Block name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_mobilenet(dl_matrix3du_t *in, + dl_matrix3dq_t *dilate, + dl_matrix3dq_t *dilate_prelu, + dl_matrix3dq_t *depthwise, + dl_matrix3dq_t *depth_prelu, + dl_matrix3dq_t *compress, + dl_matrix3dq_t *bias, + dl_matrix3dq_mobilenet_config_t config, + char *name); + +// +// Padding +// + +/**@{*/ +/** + * @brief This family of functions do a padding operation before a convlution + * + * @param padded_input the padded result pointer + * @param output_height the output height pointer + * @param output_width the output width pointer + * @param input Input matrix, size (1, w, h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param kernel_size Kernel size of the next convlution + * @param padding_type Padding type + * @return dl_error_type Return DL_SUCCESS if padding successfully, else return DL_FAIL + */ +dl_error_type dl_matrix3dqq_padding(dl_matrix3dq_t **padded_input, + int *output_height, + int *output_width, + dl_matrix3dq_t *input, + int stride_x, + int stride_y, + int kernel_size, + dl_padding_type padding_type); + +dl_error_type dl_matrix3duq_padding(dl_matrix3du_t **padded_input, + int *output_height, + int *output_width, + dl_matrix3du_t *input, + int stride_x, + int stride_y, + int kernel_size, + dl_padding_type padding_type); +/**@}*/ + +// +// Upsample +// +/** + * @brief Upsample a feature map to twice the size + * + * @param in Input matrix, size (1, w, h, c) + * @param upsample upsample type + * @return dl_matrix3dq_t* Resulting matrix, size (1, 2*w, 2*h, c) + */ +dl_matrix3dq_t *dl_matrix3dqq_upsample_2x(dl_matrix3dq_t *in, + dl_upsample_type upsample); + +// +// Pooling +// +/** + * @brief Calculate average value of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @return dl_matrix3dq_t* Resulting matrix, size (1, 1, 1, c) + */ +dl_matrix3dq_t *dl_matrix3dq_global_pool(dl_matrix3dq_t *in); + +/** + * @brief Calculate pooling layer of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @param f_w Window width + * @param f_h Window height + * @param stride_x Stride in horizontal direction + * @param stride_y Stride in vertical direction + * @param padding Padding type: PADDING_VALID and PADDING_SAME + * @param pooling_type Pooling type: DL_POOLING_MAX and POOLING_AVG + * @return dl_matrix3dq_t* Resulting matrix, size (1, w', h', c) + */ +dl_matrix3dq_t *dl_matrix3dq_pooling(dl_matrix3dq_t *in, + int f_w, + int f_h, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_pooling_type pooling_type); diff --git a/tools/sdk/esp32/include/esp-face/lib/include/frmn.h b/tools/sdk/esp32/include/esp-face/lib/include/frmn.h new file mode 100644 index 00000000000..c1f08a0fadc --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/frmn.h @@ -0,0 +1,43 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * @brief Forward the face recognition process with frmn model. Calculate in float. + * + * @param in Image matrix, rgb888 format, size is 56x56, normalized + * @return dl_matrix3d_t* Face ID feature vector, size is 512 + */ + dl_matrix3d_t *frmn(dl_matrix3d_t *in); + + /**@{*/ + /** + * @brief Forward the face recognition process with specified model. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 56x56, normalized + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return Face ID feature vector, size is 512 + */ + dl_matrix3dq_t *frmn_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *frmn2p_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_42m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_72m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_112m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_156m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /**@}*/ + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/lib/include/hd_model.h b/tools/sdk/esp32/include/esp-face/lib/include/hd_model.h new file mode 100644 index 00000000000..0bc28d70ddc --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/hd_model.h @@ -0,0 +1,66 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + typedef struct + { + int num; /*!< The total number of the boxes */ + dl_matrix3d_t *cls; /*!< The class feature map corresponding to the box. size: (height, width, anchor_num, 1) */ + dl_matrix3d_t *score; /*!< The confidence score feature map of the class corresponding to the box. size: (height, width, anchor_num, 1) */ + dl_matrix3d_t *boxes; /*!< (x, y, w, h) of the boxes. x and y are the center coordinates. size:(height, width, anchor_num, 4) */ + } detection_result_t; + + /** + * @brief Forward the hand detection process with hd_nano1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its width and height must be integer multiples of 16. + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return detection_result_t** Detection results + */ + detection_result_t **hd_nano1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Forward the hand detection process with hd_lite1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its width and height must be integer multiples of 32. + * @param mode 0: C implement; 1: handwrite xtensa instruction implement. + * @return detection_result_t** Detection results. + */ + detection_result_t **hd_lite1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Free the single detection result. + * + * @param m The single detection result. + */ + void detection_result_free(detection_result_t *m); + + /** + * @brief Free the detection result group from different feature map. + * + * @param m The detection result group + * @param length The number of the detection results + */ + void detection_results_free(detection_result_t **m, int length); + + /** + * @brief Test the result of hand detection model. + * + */ + void hd_test(); + + /** + * @brief Test the forward time of hand detection model. + * + */ + void hd_time_test(); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/lib/include/hp_model.h b/tools/sdk/esp32/include/esp-face/lib/include/hp_model.h new file mode 100644 index 00000000000..ad9080c5473 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/hp_model.h @@ -0,0 +1,43 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * @brief Forward the hand pose estimation process with hp_nano1_ls16 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its size is (1, 128, 128, 3). + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return dl_matrix3d_t* The resulting hand joint point coordinates, the size is (1, 1, 21, 2) + */ + dl_matrix3d_t *hp_nano1_ls16_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Forward the hand pose estimation process with hp_lite1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its size is (1, 128, 128, 3). + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return dl_matrix3d_t* The resulting hand joint point coordinates, the size is (1, 1, 21, 2) + */ + dl_matrix3d_t *hp_lite1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Test the result of hand pose estimation model. + * + */ + void hp_test(); + + /** + * @brief Test the forward time of hand pose estimation model. + * + */ + void hp_time_test(); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/tools/sdk/esp32/include/esp-face/lib/include/lssh.h b/tools/sdk/esp32/include/esp-face/lib/include/lssh.h new file mode 100644 index 00000000000..69c661c58e5 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/lssh.h @@ -0,0 +1,91 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" + + typedef struct + { + int resized_height; + int resized_width; + fptp_t y_resize_scale; + fptp_t x_resize_scale; + int enabled_top_k; + fptp_t score_threshold; + fptp_t nms_threshold; + + dl_conv_mode mode; + } lssh_config_t; + + typedef struct + { + int *anchor_size; + int stride; + int boundary; + } lssh_module_config_t; + + typedef struct + { + lssh_module_config_t *module_config; + int number; + } lssh_modules_config_t; + + typedef struct + { + dl_matrix3d_t *category; + dl_matrix3d_t *box_offset; + dl_matrix3d_t *landmark_offset; + } lssh_module_result_t; + + /** + * @brief + * + * @param value + */ + void lssh_module_result_free(lssh_module_result_t value); + + /** + * @brief + * + * @param values + * @param length + */ + void lssh_module_results_free(lssh_module_result_t *values, int length); + + ///////////////////////// + //////sparse_mn_5_q////// + ///////////////////////// + extern lssh_modules_config_t sparse_mn_5_modules_config; + lssh_module_result_t *sparse_mn_5_q_without_landmark(dl_matrix3du_t *image, bool free_image, int enabled_top_k, dl_conv_mode mode); + lssh_module_result_t *sparse_mn_5_q_with_landmark(dl_matrix3du_t *image, bool free_image, int enabled_top_k, dl_conv_mode mode); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/lib/include/mtmn.h b/tools/sdk/esp32/include/esp-face/lib/include/mtmn.h new file mode 100644 index 00000000000..609a82ea488 --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/lib/include/mtmn.h @@ -0,0 +1,142 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * Detection results with MTMN. + * + */ + typedef struct + { + dl_matrix3d_t *category; /*!< Classification result after softmax, channel is 2 */ + dl_matrix3d_t *offset; /*!< Bounding box offset of 2 points: top-left and bottom-right, channel is 4 */ + dl_matrix3d_t *landmark; /*!< Offsets of 5 landmarks: + * - Left eye + * - Mouth leftside + * - Nose + * - Right eye + * - Mouth rightside + * + * channel is 10 + * */ + } mtmn_net_t; + + + /** + * @brief Free a mtmn_net_t + * + * @param p A mtmn_net_t pointer + * + */ + + void mtmn_net_t_free(mtmn_net_t *p); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in float. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_lite_f(dl_matrix3du_t *in); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in float. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_lite_f_with_score_verify(dl_matrix3du_t *in, float threshold); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in float. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_lite_f_with_score_verify(dl_matrix3du_t *in, float threshold); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_lite_q(dl_matrix3du_t *in, dl_conv_mode mode); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_lite_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_lite_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_heavy_q(dl_matrix3du_t *in, dl_conv_mode mode); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_heavy_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_heavy_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/object_detection/include/object_detection.h b/tools/sdk/esp32/include/esp-face/object_detection/include/object_detection.h new file mode 100644 index 00000000000..8627a24684d --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/object_detection/include/object_detection.h @@ -0,0 +1,59 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "detection.h" +// Include models +#include "cat_face_3.h" + + /** + * @brief update detection hyperparameter + * + * @param model The detection model + * @param resize_scale The resize scale of input image + * @param score_threshold Score threshold, used to filter candidates by score + * @param nms_threshold NMS threshold, used to filter out overlapping boxes + * @param image_height Input image height + * @param image_width Input image width + */ + void update_detection_model(detection_model_t *model, fptp_t resize_scale, fptp_t score_threshold, fptp_t nms_threshold, int image_height, int image_width); + + /** + * @brief + * + * @param image The input image + * @param model A 'detection_model_t' type point of detection model + * @return box_array_t* The detection result with box and corresponding score and category + */ + box_array_t *detect_object(dl_matrix3du_t *image, detection_model_t *model); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp-face/pose_estimation/include/pe_forward.h b/tools/sdk/esp32/include/esp-face/pose_estimation/include/pe_forward.h new file mode 100644 index 00000000000..0d52b1f803e --- /dev/null +++ b/tools/sdk/esp32/include/esp-face/pose_estimation/include/pe_forward.h @@ -0,0 +1,153 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "hd_model.h" +#include "hp_model.h" + +#define INPUT_EXPONENT -10 +#define SCORE_THRESHOLD 0.5 +#define NMS_THRESHOLD 0.45 + +#if CONFIG_HD_LITE1 + #define HP_TARGET_SIZE 128 +#else + #define HP_TARGET_SIZE 128 +#endif + + typedef struct + { + int target_size; /*!< The input size of hand detection network */ + fptp_t score_threshold; /*!< score threshold, used to filter candidates by score */ + fptp_t nms_threshold; /*!< nms threshold, used to filter out overlapping boxes */ + } hd_config_t; + + /** + * @brief Get the default hand detection network configuration + * + * @return hd_config_t The default configuration + */ + static inline hd_config_t hd_init_config() + { + hd_config_t hd_config; + hd_config.target_size = 96; + hd_config.score_threshold = SCORE_THRESHOLD; + hd_config.nms_threshold = NMS_THRESHOLD; + return hd_config; + } + + typedef struct tag_od_box_list + { + fptp_t *score; /*!< The confidence score of the class corresponding to the box */ + qtp_t *cls; /*!< The class corresponding to the box */ + box_t *box; /*!< (x1, y1, x2, y2) of the boxes */ + int len; /*!< The number of the boxes */ + } od_box_array_t; + + typedef struct tag_od_image_box + { + struct tag_od_image_box *next; /*!< Next od_image_box_t */ + fptp_t score; /*!< The confidence score of the class corresponding to the box */ + qtp_t cls; /*!< The class corresponding to the box */ + box_t box; /*!< (x1, y1, x2, y2) of the boxes */ + } od_image_box_t; + + typedef struct tag_od_image_list + { + od_image_box_t *head; /*!< The current head of the od_image_list */ + od_image_box_t *origin_head; /*!< The original head of the od_image_list */ + int len; /*!< Length of the od_image_list */ + } od_image_list_t; + + /** + * @brief Sort the resulting box lists by their confidence score. + * + * @param image_sorted_list The sorted box list. + * @param insert_list The box list that have not been sorted. + */ + void od_image_sort_insert_by_score(od_image_list_t *image_sorted_list, const od_image_list_t *insert_list); + + /** + * @brief Filter out the resulting boxes whose confidence score is lower than the threshold and convert the boxes to the actual boxes on the original image.((x, y, w, h) -> (x1, y1, x2, y2)) + * + * @param score Confidence score of the boxes. + * @param cls Class of the boxes. + * @param boxes (x, y, w, h) of the boxes. x and y are the center coordinates. + * @param height Height of the detection output feature map. + * @param width Width of the detection output feature map. + * @param anchor_number Anchor number of the detection output feature map. + * @param score_threshold Threshold of the confidence score. + * @param resize_scale Resize scale: target_size/orignal_size. + * @param padding_w Width padding in preporcess. + * @param padding_h Height padding in preporcess. + * @return od_image_list_t* Resulting valid boxes. + */ + od_image_list_t *od_image_get_valid_boxes(fptp_t *score, + fptp_t *cls, + fptp_t *boxes, + int height, + int width, + int anchor_number, + fptp_t score_threshold, + fptp_t resize_scale, + int padding_w, + int padding_h); + + /** + * @brief Run NMS algorithm + * + * @param image_list The input boxes list + * @param nms_threshold NMS threshold + */ + void od_image_nms_process(od_image_list_t *image_list, fptp_t nms_threshold); + + /** + * @brief Do hand detection, return box infomation. + * + * @param image Image matrix, rgb888 format + * @param hd_config Configuration of hand detection + * @return od_box_array_t* A list of boxes, score and class. + */ + od_box_array_t *hand_detection_forward(dl_matrix3du_t *image, hd_config_t hd_config); + + /** + * @brief Do hand pose estimation, return 21 landmarks of each hand. + * + * @param image Image matrix, rgb888 format + * @param od_boxes The output of the hand detection network + * @param target_size The input size of hand pose estimation network + * @return dl_matrix3d_t* The coordinates of 21 landmarks on the input image for each hand, size (n, 1, 21, 2) + */ + dl_matrix3d_t *handpose_estimation_forward(dl_matrix3du_t *image, od_box_array_t *od_boxes, int target_size); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h b/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h index cfdfbc04186..75d2f9726c3 100644 --- a/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h +++ b/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h @@ -44,6 +44,7 @@ typedef enum { #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core #endif + ESP_PD_DOMAIN_RTC8M, //!< Internal 8M oscillator ESP_PD_DOMAIN_VDDSDIO, //!< VDD_SDIO ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; diff --git a/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_io.h b/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_io.h index eebcabf42b4..330f4d9a165 100644 --- a/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_io.h +++ b/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_io.h @@ -65,6 +65,22 @@ esp_err_t esp_lcd_panel_io_tx_color(esp_lcd_panel_io_handle_t io, int lcd_cmd, c */ esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io); +/** + * @brief Type of LCD panel IO event data + */ +typedef struct { +} esp_lcd_panel_io_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] edata Panel IO event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); + /** * @brief Panel IO configuration structure, for SPI interface */ @@ -74,8 +90,8 @@ typedef struct { int spi_mode; /*!< Traditional SPI mode (0~3) */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Size of internal transaction queue */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { @@ -100,8 +116,8 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p typedef struct { uint32_t dev_addr; /*!< I2C device address */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ size_t control_phase_bytes; /*!< I2C LCD panel will encode control information (e.g. D/C seclection) into control phase, in several bytes */ unsigned int dc_bit_offset; /*!< Offset of the D/C selection bit in control phase */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ @@ -168,8 +184,8 @@ typedef struct { int cs_gpio_num; /*!< GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Transaction queue size, larger queue, higher throughput */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data was tranferred done */ - void *user_data; /*!< User private data, passed directly to on_trans_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data was tranferred done */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { diff --git a/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_rgb.h b/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_rgb.h index 2ddd2b6b9a6..1368bb787f6 100644 --- a/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_rgb.h +++ b/tools/sdk/esp32/include/esp_lcd/include/esp_lcd_panel_rgb.h @@ -18,6 +18,37 @@ extern "C" { #if SOC_LCD_RGB_SUPPORTED /** * @brief LCD RGB timing structure + * + * Total Width + * <---------------------------------------------------> + * Hsync width HBP Active Width HFP + * <---><--><--------------------------------------><---> + * ____ ____|_______________________________________|____| + * |___| | | | + * | | | + * __| | | | + * /|\ /|\ | | | | + * | VSYNC| | | | | + * |Width\|/ |__ | | | + * | /|\ | | | | + * | VBP | | | | | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | / / / / / / / / / / / / / / / / / / / | | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Total | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Heigh | | | |/ / / / / / / / / / / / / / / / / / / /| | + * |Active| | |/ / / / / / / / / / / / / / / / / / / /| | + * |Heigh | | |/ / / / / / Active Display Area / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | + * | VFP | | | + * \|/ \|/_____|______________________________________________________| + * */ typedef struct { unsigned int pclk_hz; /*!< Frequency of pixel clock */ @@ -38,6 +69,22 @@ typedef struct { } flags; } esp_lcd_rgb_timing_t; +/** + * @brief Type of RGB LCD panel event data + */ +typedef struct { +} esp_lcd_rgb_panel_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel LCD panel handle, returned from `esp_lcd_new_rgb_panel` + * @param[in] edata Panel event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_rgb_panel_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_rgb_panel_frame_trans_done_cb_t)(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx); + /** * @brief LCD RGB panel configuration structure */ @@ -51,8 +98,8 @@ typedef struct { int pclk_gpio_num; /*!< GPIO used for PCLK signal */ int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; /*!< GPIOs used for data lines */ int disp_gpio_num; /*!< GPIO used for display control signal, set to -1 if it's not used */ - bool (*on_frame_trans_done)(esp_lcd_panel_handle_t panel, void *user_data); /*!< Callback, invoked when one frame buffer has transferred done */ - void *user_data; /*!< User data which would be passed to on_frame_trans_done's user_data */ + esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; /*!< Callback invoked when one frame buffer has transferred done */ + void *user_ctx; /*!< User data which would be passed to on_frame_trans_done's user_ctx */ struct { unsigned int disp_active_low: 1; /*!< If this flag is enabled, a low level of display control signal can turn the screen on; vice versa */ unsigned int relax_on_idle: 1; /*!< If this flag is enabled, the host won't refresh the LCD if nothing changed in host's frame buffer (this is usefull for LCD with built-in GRAM) */ diff --git a/tools/sdk/esp32/include/esp_littlefs/include/esp_littlefs.h b/tools/sdk/esp32/include/esp_littlefs/include/esp_littlefs.h index dbb1028790d..7b5abe9248f 100644 --- a/tools/sdk/esp32/include/esp_littlefs/include/esp_littlefs.h +++ b/tools/sdk/esp32/include/esp_littlefs/include/esp_littlefs.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include "sdkconfig.h" diff --git a/tools/sdk/esp32/include/esp_rom/include/esp32c3/rom/newlib.h b/tools/sdk/esp32/include/esp_rom/include/esp32c3/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32/include/esp_rom/include/esp32c3/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp_rom/include/esp32h2/rom/newlib.h b/tools/sdk/esp32/include/esp_rom/include/esp32h2/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32/include/esp_rom/include/esp32h2/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/esp_wifi/include/esp_coexist.h b/tools/sdk/esp32/include/esp_wifi/include/esp_coexist.h index 1ff624d9b55..14b7c9aa506 100644 --- a/tools/sdk/esp32/include/esp_wifi/include/esp_coexist.h +++ b/tools/sdk/esp32/include/esp_wifi/include/esp_coexist.h @@ -1,16 +1,8 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_H__ #define __ESP_COEXIST_H__ @@ -32,6 +24,13 @@ typedef enum { ESP_COEX_PREFER_NUM, /*!< Prefer value numbers */ } esp_coex_prefer_t; +typedef enum { + EXTERN_COEX_WIRE_1 = 0, + EXTERN_COEX_WIRE_2, + EXTERN_COEX_WIRE_3, + EXTERN_COEX_WIRE_NUM, +} external_coex_wire_t; + /** * @brief coex status type */ @@ -41,6 +40,36 @@ typedef enum { ESP_COEX_ST_TYPE_BT, } esp_coex_status_type_t; +/** + * @brief external coex gpio pti + */ +typedef struct { + int32_t in_pin0; + int32_t in_pin1; + int32_t out_pin0; +} esp_external_coex_gpio_set_t; + +/** + * @brief external coex pti level + */ +typedef enum { + EXTERN_COEX_PTI_MID = 0, + EXTERN_COEX_PTI_HIGH, + EXTERN_COEX_PTI_NUM, +} esp_coex_pti_level_t; + +/** + * @brief external coex pti + */ +typedef struct { + uint32_t in_pti1; + uint32_t in_pti2; + uint32_t in_pti3; + uint32_t out_pti1; + uint32_t out_pti2; + uint32_t out_pti3; +} esp_external_coex_pti_set_t; + #define ESP_COEX_BLE_ST_MESH_CONFIG 0x08 #define ESP_COEX_BLE_ST_MESH_TRAFFIC 0x10 #define ESP_COEX_BLE_ST_MESH_STANDBY 0x20 @@ -84,6 +113,18 @@ esp_err_t esp_coex_status_bit_set(esp_coex_status_type_t type, uint32_t status); */ esp_err_t esp_coex_status_bit_clear(esp_coex_status_type_t type, uint32_t status); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Setup gpio pin and corresponding pti level, start external coex. + * @param wire_type : to select the whole external coex gpio number. + * @param gpio_pin : gpio pin number to choose. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, + esp_external_coex_gpio_set_t gpio_pin); + +esp_err_t esp_disable_extern_coex_gpio_pin(); +#endif #ifdef __cplusplus } diff --git a/tools/sdk/esp32/include/esp_wifi/include/esp_coexist_internal.h b/tools/sdk/esp32/include/esp_wifi/include/esp_coexist_internal.h index 3501f0da6fb..7ba06d4c690 100644 --- a/tools/sdk/esp32/include/esp_wifi/include/esp_coexist_internal.h +++ b/tools/sdk/esp32/include/esp_wifi/include/esp_coexist_internal.h @@ -1,21 +1,14 @@ -// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_INTERNAL_H__ #define __ESP_COEXIST_INTERNAL_H__ #include +#include "esp_coexist.h" #include "esp_coexist_adapter.h" #ifdef __cplusplus @@ -210,6 +203,29 @@ int coex_schm_curr_phase_idx_get(void); */ esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Set external coexistence pti level and enable it. + * + * @param level1 external coex low pti + * @param level2 external coex mid pti + * @param level3 external coex high pti + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_coex_external_set(esp_coex_pti_level_t level1, + esp_coex_pti_level_t level2, esp_coex_pti_level_t level3); + +/** + * @brief Disable external coexist + * + * @return + * - ESP_OK: succeed + */ +void esp_coex_external_stop(void); +#endif /*External Coex*/ + /** * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library * diff --git a/tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h b/tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h index 503e8d7bb05..cee23f3fafc 100644 --- a/tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h +++ b/tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_WIFI_TYPES_H__ @@ -80,6 +72,7 @@ typedef enum { WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, WIFI_REASON_IE_INVALID = 13, WIFI_REASON_MIC_FAILURE = 14, WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, @@ -250,7 +243,8 @@ typedef struct { wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. */ uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ - uint32_t reserved:30; /**< Reserved for future feature set */ + uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ + uint32_t reserved:29; /**< Reserved for future feature set */ } wifi_sta_config_t; /** @brief Configuration data for ESP32 AP or STA. diff --git a/tools/sdk/esp32/include/freertos/include/esp_additions/FreeRTOSConfig.h b/tools/sdk/esp32/include/freertos/include/esp_additions/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32/include/freertos/include/esp_additions/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h b/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h index a01a56e9fd4..675af141ebc 100644 --- a/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h +++ b/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h @@ -90,7 +90,6 @@ #define portNUM_PROCESSORS 1 #endif -#define configASSERT_2 0 #define portUSING_MPU_WRAPPERS 0 #define configUSE_MUTEX 1 @@ -206,7 +205,6 @@ #define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ #endif -#define configUSE_TRACE_FACILITY_2 0 #define configBENCHMARK 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 @@ -306,4 +304,9 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + #endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32/include/freertos/include/esp_additions/task_snapshot.h b/tools/sdk/esp32/include/freertos/include/esp_additions/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32/include/freertos/include/esp_additions/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h b/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h index 84505ddaaa0..9792296e566 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h @@ -64,7 +64,7 @@ * used to create a synchronisation point between multiple tasks (a * 'rendezvous'). * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroup EventGroup * @endcond */ @@ -78,7 +78,7 @@ * xEventGroupCreate() returns an EventGroupHandle_t variable that can then * be used as a parameter to other event group functions. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroupHandle_t EventGroupHandle_t * @endcond * \ingroup EventGroup @@ -94,7 +94,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, * 32 bits if set to 0. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventBits_t EventBits_t * @endcond * \ingroup EventGroup @@ -102,7 +102,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; typedef TickType_t EventBits_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreate( void ); @@ -152,7 +152,7 @@ typedef TickType_t EventBits_t; * // The event group was created. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupCreate xEventGroupCreate * @endcond * \ingroup EventGroup @@ -162,7 +162,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); @@ -217,7 +217,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, @@ -307,7 +307,7 @@ typedef TickType_t EventBits_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupWaitBits xEventGroupWaitBits * @endcond * \ingroup EventGroup @@ -319,7 +319,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); @@ -372,7 +372,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBits xEventGroupClearBits * @endcond * \ingroup EventGroup @@ -381,7 +381,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -432,7 +432,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * @endcond * \ingroup EventGroup @@ -446,7 +446,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -516,7 +516,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBits xEventGroupSetBits * @endcond * \ingroup EventGroup @@ -525,7 +525,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); @@ -595,7 +595,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * @endcond * \ingroup EventGroup @@ -610,7 +610,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, @@ -732,7 +732,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSync xEventGroupSync * @endcond * \ingroup EventGroup @@ -744,7 +744,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); @@ -758,7 +758,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBits() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBits xEventGroupGetBits * @endcond * \ingroup EventGroup @@ -766,7 +766,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); @@ -779,7 +779,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR * @endcond * \ingroup EventGroup @@ -787,7 +787,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); @@ -802,7 +802,7 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, diff --git a/tools/sdk/esp32/include/freertos/include/freertos/freertos_tasks_c_additions.h b/tools/sdk/esp32/include/freertos/include/freertos/freertos_tasks_c_additions.h new file mode 100644 index 00000000000..464c0b3ffb9 --- /dev/null +++ b/tools/sdk/esp32/include/freertos/include/freertos/freertos_tasks_c_additions.h @@ -0,0 +1,80 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +/** + * This file will be included in `tasks.c` file, thus, it must NOT be included + * by any (other) file. + * The functions below only consist in getters for the static variables in + * `tasks.c` file. + * The only source files that should call these functions are the ones in + * `/additions` directory. + */ + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + + UBaseType_t pxTCBGetSize ( void ) + { + return sizeof(TCB_t); + } + + ListItem_t* pxTCBGetStateListItem ( void *pxTCB ) + { + return &(((TCB_t*)pxTCB)->xStateListItem); + } + + StackType_t* pxTCBGetStartOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxStack; + } + + StackType_t* pxTCBGetTopOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxTopOfStack; + } + + StackType_t* pxTCBGetEndOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxEndOfStack; + } + + + List_t* pxListGetReadyTask ( UBaseType_t idx ) + { + return &( pxReadyTasksLists[idx] ); + } + + List_t* pxListGetReadyPendingTask ( UBaseType_t idx ) + { + return &( xPendingReadyList[idx] ); + } + + List_t* pxGetDelayedTaskList ( void ) { + return pxDelayedTaskList; + } + + List_t* pxGetOverflowDelayedTaskList ( void ) { + return pxOverflowDelayedTaskList; + } + + List_t* pxGetTasksWaitingTermination ( void ) { + return &xTasksWaitingTermination; + } + + List_t* pxGetSuspendedTaskList ( void ) { + return &xSuspendedTaskList; + } + +#endif diff --git a/tools/sdk/esp32/include/freertos/include/freertos/message_buffer.h b/tools/sdk/esp32/include/freertos/include/freertos/message_buffer.h index e57c589fbac..af5c3290b7c 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/message_buffer.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/message_buffer.h @@ -85,7 +85,7 @@ typedef void * MessageBufferHandle_t; /*-----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -139,7 +139,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreate xMessageBufferCreate * @endcond * \ingroup MessageBufferManagement @@ -148,7 +148,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -210,7 +210,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * @endcond * \ingroup MessageBufferManagement @@ -219,7 +219,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -314,7 +314,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSend xMessageBufferSend * @endcond * \ingroup MessageBufferManagement @@ -323,7 +323,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -423,7 +423,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * @endcond * \ingroup MessageBufferManagement @@ -432,7 +432,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -516,7 +516,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceive xMessageBufferReceive * @endcond * \ingroup MessageBufferManagement @@ -526,7 +526,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -622,7 +622,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * @endcond * \ingroup MessageBufferManagement @@ -631,7 +631,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -654,7 +654,7 @@ typedef void * MessageBufferHandle_t; vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); @@ -674,7 +674,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); @@ -693,7 +693,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); @@ -712,7 +712,7 @@ typedef void * MessageBufferHandle_t; * the message queue to wait for space to become available, or to wait for a * a message to be available, then pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReset xMessageBufferReset * @endcond * \ingroup MessageBufferManagement @@ -722,7 +722,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); @@ -740,7 +740,7 @@ typedef void * MessageBufferHandle_t; * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size * of the largest message that can be written to the message buffer is 6 bytes. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable * @endcond * \ingroup MessageBufferManagement @@ -751,7 +751,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); @@ -767,7 +767,7 @@ typedef void * MessageBufferHandle_t; * @return The length (in bytes) of the next message in the message buffer, or 0 * if the message buffer is empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes * @endcond * \ingroup MessageBufferManagement @@ -776,7 +776,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -811,7 +811,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -820,7 +820,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -856,7 +856,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement diff --git a/tools/sdk/esp32/include/freertos/include/freertos/queue.h b/tools/sdk/esp32/include/freertos/include/freertos/queue.h index 81cccc05df3..05ca7de4546 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/queue.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/queue.h @@ -62,7 +62,7 @@ typedef struct QueueDefinition * QueueSetHandle_t; */ typedef struct QueueDefinition * QueueSetMemberHandle_t; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ #define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) @@ -80,7 +80,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreate( @@ -146,7 +146,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreate xQueueCreate * @endcond * \ingroup QueueManagement @@ -156,7 +156,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreateStatic( @@ -235,7 +235,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreateStatic xQueueCreateStatic * @endcond * \ingroup QueueManagement @@ -245,7 +245,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToToFront( @@ -321,7 +321,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -330,7 +330,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBack( @@ -408,7 +408,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -417,7 +417,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSend( @@ -497,7 +497,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -506,7 +506,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwrite( @@ -585,7 +585,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwrite xQueueOverwrite * @endcond * \ingroup QueueManagement @@ -595,7 +595,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSend( @@ -678,7 +678,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -689,7 +689,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeek( @@ -780,7 +780,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeek xQueuePeek * @endcond * \ingroup QueueManagement @@ -790,7 +790,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeekFromISR( @@ -820,7 +820,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeekFromISR xQueuePeekFromISR * @endcond * \ingroup QueueManagement @@ -829,7 +829,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceive( @@ -917,7 +917,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceive xQueueReceive * @endcond * \ingroup QueueManagement @@ -927,7 +927,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); @@ -940,7 +940,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, * * @return The number of messages available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -948,7 +948,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ); @@ -963,7 +963,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @return The number of spaces available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -971,7 +971,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * void vQueueDelete( QueueHandle_t xQueue ); @@ -983,7 +983,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @param xQueue A handle to the queue to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vQueueDelete vQueueDelete * @endcond * \ingroup QueueManagement @@ -991,7 +991,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToFrontFromISR( @@ -1057,7 +1057,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1067,7 +1067,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBackFromISR( @@ -1133,7 +1133,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1142,7 +1142,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwriteFromISR( @@ -1225,7 +1225,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR * @endcond * \ingroup QueueManagement @@ -1234,7 +1234,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendFromISR( @@ -1304,7 +1304,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1312,10 +1312,10 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; #define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /**@{*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSendFromISR( @@ -1402,7 +1402,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceiveFromISR( @@ -1487,7 +1487,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR * @endcond * \ingroup QueueManagement @@ -1504,7 +1504,7 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * The functions defined above are for passing data to and from tasks. The * functions below are the equivalents for passing data to and from @@ -1778,7 +1778,7 @@ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, */ QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Not public API functions. */ void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, diff --git a/tools/sdk/esp32/include/freertos/include/freertos/semphr.h b/tools/sdk/esp32/include/freertos/include/freertos/semphr.h index 7e99c0b396c..2041641b91d 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/semphr.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/semphr.h @@ -39,7 +39,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * semphr. h * @code{c} @@ -88,7 +88,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -106,7 +106,7 @@ typedef QueueHandle_t SemaphoreHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinary( void ); @@ -163,7 +163,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -173,7 +173,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); @@ -229,7 +229,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // Rest of task code goes here. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic * @endcond * \ingroup Semaphores @@ -239,7 +239,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTake( @@ -304,7 +304,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTake xSemaphoreTake * @endcond * \ingroup Semaphores @@ -312,7 +312,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeRecursive( @@ -403,7 +403,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive * @endcond * \ingroup Semaphores @@ -465,7 +465,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGive xSemaphoreGive * @endcond * \ingroup Semaphores @@ -473,7 +473,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); @@ -555,7 +555,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive * @endcond * \ingroup Semaphores @@ -641,7 +641,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR * @endcond * \ingroup Semaphores @@ -649,7 +649,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeFromISR( @@ -686,7 +686,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutex( void ); @@ -741,7 +741,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex * @endcond * \ingroup Semaphores @@ -751,7 +751,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); @@ -808,7 +808,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // so there is no need to check it. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic * @endcond * \ingroup Semaphores @@ -951,7 +951,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); @@ -1027,7 +1027,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * @endcond * \ingroup Semaphores @@ -1037,7 +1037,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer ); @@ -1118,7 +1118,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // is no need to check its value. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic * @endcond * \ingroup Semaphores @@ -1128,7 +1128,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); @@ -1140,7 +1140,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * * @param xSemaphore A handle to the semaphore to be deleted. * - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * \defgroup vSemaphoreDelete vSemaphoreDelete * @endcond * \ingroup Semaphores @@ -1148,7 +1148,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); @@ -1167,7 +1167,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex ); @@ -1182,7 +1182,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); diff --git a/tools/sdk/esp32/include/freertos/include/freertos/stream_buffer.h b/tools/sdk/esp32/include/freertos/include/freertos/stream_buffer.h index 9e58cff120c..a20dcf0375e 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/stream_buffer.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/stream_buffer.h @@ -71,7 +71,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -134,7 +134,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreate xStreamBufferCreate * @endcond * \ingroup StreamBufferManagement @@ -142,7 +142,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -220,7 +220,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * @endcond * \ingroup StreamBufferManagement @@ -229,7 +229,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -319,7 +319,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSend xStreamBufferSend * @endcond * \ingroup StreamBufferManagement @@ -330,7 +330,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -424,7 +424,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * @endcond * \ingroup StreamBufferManagement @@ -435,7 +435,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -517,7 +517,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceive xStreamBufferReceive * @endcond * \ingroup StreamBufferManagement @@ -528,7 +528,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -607,7 +607,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * @endcond * \ingroup StreamBufferManagement @@ -618,7 +618,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -636,7 +636,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * * @param xStreamBuffer The handle of the stream buffer to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vStreamBufferDelete vStreamBufferDelete * @endcond * \ingroup StreamBufferManagement @@ -644,7 +644,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -660,7 +660,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI * @return If the stream buffer is full then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsFull xStreamBufferIsFull * @endcond * \ingroup StreamBufferManagement @@ -668,7 +668,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -684,7 +684,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ * @return If the stream buffer is empty then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty * @endcond * \ingroup StreamBufferManagement @@ -692,7 +692,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -711,7 +711,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED * a task blocked waiting to send to or read from the stream buffer then the * stream buffer is not reset and pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReset xStreamBufferReset * @endcond * \ingroup StreamBufferManagement @@ -719,7 +719,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -736,7 +736,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F * @return The number of bytes that can be written to the stream buffer before * the stream buffer would be full. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable * @endcond * \ingroup StreamBufferManagement @@ -744,7 +744,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -761,7 +761,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL * @return The number of bytes that can be read from the stream buffer before * the stream buffer would be empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable * @endcond * \ingroup StreamBufferManagement @@ -769,7 +769,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -802,7 +802,7 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE * then the trigger level will be updated and pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * @endcond * \ingroup StreamBufferManagement @@ -811,7 +811,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -846,7 +846,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -855,7 +855,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -891,7 +891,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -899,7 +899,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Functions below here are not part of the public API. */ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, diff --git a/tools/sdk/esp32/include/freertos/include/freertos/task.h b/tools/sdk/esp32/include/freertos/include/freertos/task.h index 9135b76f014..125a924d061 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/task.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/task.h @@ -76,7 +76,7 @@ * returns (via a pointer parameter) an TaskHandle_t variable that can then * be used as a parameter to vTaskDelete to delete the task. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup TaskHandle_t TaskHandle_t * @endcond * \ingroup Tasks @@ -114,7 +114,7 @@ typedef enum eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ } eNotifyAction; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * Used internally only. */ @@ -189,11 +189,13 @@ typedef enum #define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro for forcing a context switch. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskYIELD taskYIELD * @endcond * \ingroup SchedulerControl @@ -201,7 +203,9 @@ typedef enum #define taskYIELD() portYIELD() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the start of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -209,7 +213,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL * @endcond * \ingroup SchedulerControl @@ -228,7 +232,9 @@ typedef enum #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the end of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -236,7 +242,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL * @endcond * \ingroup SchedulerControl @@ -255,11 +261,13 @@ typedef enum #define taskEXIT_CRITICAL_ISR( ) portEXIT_CRITICAL_ISR( ) #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to disable all maskable interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -267,11 +275,13 @@ typedef enum #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to enable microcontroller interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -422,7 +432,7 @@ typedef enum * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreate xTaskCreate * @endcond * \ingroup Tasks @@ -430,14 +440,14 @@ typedef enum #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) static inline IRAM_ATTR BaseType_t xTaskCreate( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pvCreatedTask) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask) PRIVILEGED_FUNCTION { - return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask, tskNO_AFFINITY ); + return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY ); } #endif @@ -599,20 +609,20 @@ typedef enum #if( configSUPPORT_STATIC_ALLOCATION == 1 ) static inline IRAM_ATTR TaskHandle_t xTaskCreateStatic( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const pxStackBuffer, - StaticTask_t * const pxTaskBuffer) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer) PRIVILEGED_FUNCTION { - return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, pxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); + return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); } #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -683,18 +693,18 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks */ #if ( portUSING_MPU_WRAPPERS == 1 ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, - TaskHandle_t * pxCreatedTask ); + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -777,7 +787,7 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic * @endcond * \ingroup Tasks @@ -788,7 +798,7 @@ typedef enum #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); @@ -833,7 +843,7 @@ typedef enum * // defined or shared regions have been declared elsewhere). * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks @@ -842,7 +852,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelete( TaskHandle_t xTask ); @@ -881,7 +891,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, * vTaskDelete( xHandle ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelete vTaskDelete * @endcond * \ingroup Tasks @@ -893,10 +903,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelay( const TickType_t xTicksToDelay ); * @endcode + * @endcond * * Delay a task for a given number of ticks. The actual time that the * task remains blocked depends on the tick rate. The constant @@ -938,7 +950,7 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelay vTaskDelay * @endcond * \ingroup TaskCtrl @@ -946,10 +958,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); * @endcode + * @endcond * * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. * See the configuration section for more information. @@ -1007,7 +1021,7 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskDelayUntil xTaskDelayUntil * @endcond * \ingroup TaskCtrl @@ -1026,7 +1040,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); @@ -1054,7 +1068,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, * @return If the task referenced by xTask was not in the Blocked state then * pdFAIL is returned. Otherwise pdPASS is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskAbortDelay xTaskAbortDelay * @endcond * \ingroup TaskCtrl @@ -1062,7 +1076,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ); @@ -1107,7 +1121,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskPriorityGet uxTaskPriorityGet * @endcond * \ingroup TaskCtrl @@ -1115,7 +1129,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ); @@ -1127,7 +1141,7 @@ UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * eTaskState eTaskGetState( TaskHandle_t xTask ); @@ -1149,7 +1163,7 @@ UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNC eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); @@ -1203,7 +1217,7 @@ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * eInvalid ); // Include the task state in xTaskDetails. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetInfo vTaskGetInfo * @endcond * \ingroup TaskCtrl @@ -1214,7 +1228,7 @@ void vTaskGetInfo( TaskHandle_t xTask, eTaskState eState ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); @@ -1254,7 +1268,7 @@ void vTaskGetInfo( TaskHandle_t xTask, * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskPrioritySet vTaskPrioritySet * @endcond * \ingroup TaskCtrl @@ -1263,7 +1277,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); @@ -1312,7 +1326,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, * // with our handle as the parameter. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspend vTaskSuspend * @endcond * \ingroup TaskCtrl @@ -1320,7 +1334,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskResume( TaskHandle_t xTaskToResume ); @@ -1367,7 +1381,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; * // time in accordance with its priority within the system. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResume vTaskResume * @endcond * \ingroup TaskCtrl @@ -1375,7 +1389,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); @@ -1402,7 +1416,7 @@ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * otherwise pdFALSE. This is used by the ISR to determine if a context switch * may be required following the ISR. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResumeFromISR vTaskResumeFromISR * @endcond * \ingroup TaskCtrl @@ -1412,9 +1426,9 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER CONTROL *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskStartScheduler( void ); @@ -1445,7 +1459,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskStartScheduler vTaskStartScheduler * @endcond * \ingroup SchedulerControl @@ -1453,7 +1467,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskEndScheduler( void ); @@ -1507,7 +1521,7 @@ void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskEndScheduler vTaskEndScheduler * @endcond * \ingroup SchedulerControl @@ -1517,7 +1531,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspendAll( void ); @@ -1566,7 +1580,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspendAll vTaskSuspendAll * @endcond * \ingroup SchedulerControl @@ -1574,7 +1588,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskResumeAll( void ); @@ -1626,7 +1640,7 @@ void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskResumeAll xTaskResumeAll * @endcond * \ingroup SchedulerControl @@ -1638,7 +1652,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCount( void ); @@ -1647,7 +1661,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; * * @return The count of ticks since vTaskStartScheduler was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCount xTaskGetTickCount * @endcond * \ingroup TaskUtils @@ -1655,7 +1669,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCountFromISR( void ); @@ -1669,7 +1683,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; * microcontroller being used or interrupt nesting is either not supported or * not being used. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR * @endcond * \ingroup TaskUtils @@ -1677,7 +1691,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint16_t uxTaskGetNumberOfTasks( void ); @@ -1689,7 +1703,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; * has been deleted but not yet freed by the idle task will also be * included in the count. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * @endcond * \ingroup TaskUtils @@ -1697,7 +1711,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); @@ -1708,7 +1722,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; * xTaskToQuery. A task can query its own name by either passing in its own * handle, or by setting xTaskToQuery to NULL. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetName pcTaskGetName * @endcond * \ingroup TaskUtils @@ -1716,7 +1730,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); @@ -1730,7 +1744,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lin * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetHandle pcTaskGetHandle * @endcond * \ingroup TaskUtils @@ -1813,7 +1827,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #ifdef configUSE_APPLICATION_TASK_TAG #if configUSE_APPLICATION_TASK_TAG == 1 /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); @@ -1830,7 +1844,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTag( TaskHandle_t xTask ); @@ -1844,7 +1858,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ); @@ -1932,7 +1946,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationStackOverflowHook( TaskHandle_t xTask char *pcTaskName); @@ -1952,7 +1966,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configUSE_TICK_HOOK > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationTickHook( void ); @@ -1967,7 +1981,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) @@ -1986,7 +2000,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); @@ -2155,7 +2169,7 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, * enough to contain the generated report. Approximately 40 bytes per * task should be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskList vTaskList * @endcond * \ingroup TaskUtils @@ -2210,7 +2224,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq * contain the generated report. Approximately 40 bytes per task should * be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * @endcond * \ingroup TaskUtils @@ -2218,7 +2232,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code * uint32_t ulTaskGetIdleRunTimeCounter( void ); @@ -2246,7 +2260,7 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and * portGET_RUN_TIME_COUNTER_VALUE() macros. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter * @endcond * \ingroup TaskUtils @@ -2254,11 +2268,13 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction ); * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2359,7 +2375,9 @@ uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, @@ -2373,11 +2391,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2393,7 +2413,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * than when the function returns) in the additional pulPreviousNotifyValue * parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ @@ -2402,11 +2424,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2511,7 +2535,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, @@ -2526,11 +2552,13 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2546,7 +2574,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * function is called rather than at the time the function returns) in the * additional pulPreviousNotifyValue parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ @@ -2555,12 +2585,14 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification to be pending at a given index within * an array of direct to task notifications. @@ -2655,7 +2687,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * already pending when xTaskNotifyWait was called) then pdPASS is * returned. Otherwise pdFAIL is returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, @@ -2669,11 +2703,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ); * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); * @endcode + * @endcond * * Sends a direct to task notification to a particular index in the target * task's notification array in a manner similar to giving a counting semaphore. @@ -2737,7 +2773,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the * eAction parameter set to eIncrement - so pdPASS is always returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyGive( xTaskToNotify ) \ @@ -2746,11 +2784,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ); * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt * service routine (ISR). @@ -2821,7 +2861,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * requested from an ISR is dependent on the port - see the documentation page * for the port in use. * + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR + * @endcond * \ingroup TaskNotifications */ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, @@ -2833,12 +2875,14 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) ); /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification on a particular index in the calling * task's notification array in a manner similar to taking a counting semaphore. @@ -2927,7 +2971,9 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, * @return The task's notification count before it is either cleared to zero or * decremented (see the xClearCountOnExit parameter). * + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, @@ -2939,12 +2985,14 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, ulTaskGenericNotifyTake( ( uxIndexToWaitOn ), ( xClearCountOnExit ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); * * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2992,7 +3040,9 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, * @return pdTRUE if the task's notification state was set to * eNotWaitingNotification, otherwise pdFALSE. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, @@ -3003,12 +3053,14 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ); * * uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -3057,7 +3109,9 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, * * @return The value of the target task's notification value before the bits * specified by ulBitsToClear were cleared. + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, @@ -3069,7 +3123,7 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); @@ -3082,14 +3136,14 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, * is to be captured. The captured time includes the tick count and the number * of times the tick count has overflowed since the system first booted. * \defgroup vTaskSetTimeOutState vTaskSetTimeOutState - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code * BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); @@ -3170,7 +3224,7 @@ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; * return uxReceived; * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCheckForTimeOut xTaskCheckForTimeOut * @endcond * \ingroup TaskCtrl @@ -3179,7 +3233,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ); @@ -3204,7 +3258,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, * blocked state and a context switch being performed. Otherwise pdFALSE. * * \defgroup xTaskCatchUpTicks xTaskCatchUpTicks - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ @@ -3214,7 +3268,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Return the handle of the task running on a certain CPU. Because of * the nature of SMP processing, there is no guarantee that this @@ -3335,8 +3389,8 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, * making the call, otherwise pdFALSE. */ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; -BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, - const TickType_t xItemValue ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, + const TickType_t xItemValue ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY @@ -3399,11 +3453,6 @@ void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, */ UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; -/* - * Get the current core affinity of a task - */ -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; - /* * Set the uxTaskNumber of the task referenced by the xTask parameter to * uxHandle. diff --git a/tools/sdk/esp32/include/freertos/include/freertos/task_snapshot.h b/tools/sdk/esp32/include/freertos/include/freertos/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32/include/freertos/include/freertos/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32/include/freertos/include/freertos/timers.h b/tools/sdk/esp32/include/freertos/include/freertos/timers.h index a8bc4f38c78..af6dcb23501 100644 --- a/tools/sdk/esp32/include/freertos/include/freertos/timers.h +++ b/tools/sdk/esp32/include/freertos/include/freertos/timers.h @@ -450,7 +450,7 @@ void vTimerSetTimerID( TimerHandle_t xTimer, BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * @endcond * @@ -1315,7 +1315,7 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; */ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Functions beyond this part are not part of the public API and are intended @@ -1339,7 +1339,7 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) diff --git a/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..f2aab51ccfc --- /dev/null +++ b/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,166 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_XTENSA_H +#define FREERTOS_CONFIG_XTENSA_H + +#include "sdkconfig.h" + +/* enable use of optimized task selection by the scheduler */ +#ifdef CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#define XT_USE_THREAD_SAFE_CLIB 0 +#undef XT_USE_SWPRI + +#if CONFIG_FREERTOS_CORETIMER_0 +#define XT_TIMER_INDEX 0 +#elif CONFIG_FREERTOS_CORETIMER_1 +#define XT_TIMER_INDEX 1 +#endif + +#ifndef __ASSEMBLER__ +/** + * This function is defined to provide a deprecation warning whenever + * XT_CLOCK_FREQ macro is used. + * Update the code to use esp_clk_cpu_freq function instead. + * @return current CPU clock frequency, in Hz + */ +int xt_clock_freq(void) __attribute__((deprecated)); + +#define XT_CLOCK_FREQ (xt_clock_freq()) + +#endif // __ASSEMBLER__ + +/* Required for configuration-dependent settings */ +#include + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include +#include "esp_rom_sys.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" // will be removed in idf v5.0 +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/ets_sys.h" +#endif +#endif // __ASSEMBLER__ + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#define configXT_BOARD 1 /* Board mode */ +#define configXT_SIMULATOR 0 + +/* The maximum interrupt priority from which FreeRTOS.org API functions can + be called. Only API functions that end in ...FromISR() can be used within + interrupts. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY XCHAL_EXCM_LEVEL + +/* Stack alignment, architecture specifc. Must be a power of two. */ +#define configSTACK_ALIGNMENT 16 + + +/* The Xtensa port uses a separate interrupt stack. Adjust the stack size + * to suit the needs of your specific application. + * Size needs to be aligned to the stack increment, since the location of + * the stack for the 2nd CPU will be calculated using configISR_STACK_SIZE. + */ +#ifndef configISR_STACK_SIZE +#define configISR_STACK_SIZE ((CONFIG_FREERTOS_ISR_STACKSIZE + configSTACK_ALIGNMENT - 1) & (~(configSTACK_ALIGNMENT - 1))) +#endif + +#ifndef __ASSEMBLER__ +#if CONFIG_APPTRACE_SV_ENABLE +extern uint32_t port_switch_flag[]; +#define os_task_switch_is_pended(_cpu_) (port_switch_flag[_cpu_]) +#else +#define os_task_switch_is_pended(_cpu_) (false) +#endif +#endif + +#endif // FREERTOS_CONFIG_XTENSA_H diff --git a/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h b/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h index 248c86d15c7..47187379c6c 100644 --- a/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h +++ b/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h @@ -24,317 +24,449 @@ * * 1 tab == 4 spaces! */ + #ifndef PORTMACRO_H #define PORTMACRO_H -#ifdef __cplusplus -extern "C" { -#endif - #ifndef __ASSEMBLER__ -#include +#include "sdkconfig.h" #include #include #include #include -#include #include -#include /* required for XSHAL_CLIB */ -#include -#include "esp_private/crosscore_int.h" -#include "esp_timer.h" /* required for FreeRTOS run time stats */ -#include "esp_system.h" -#include "esp_newlib.h" +#include /* required for xthal_get_ccount. [refactor-todo] use cpu_hal instead */ +#include /* required for XTOS_SET_INTLEVEL. [refactor-todo] add common intr functions to esp_hw_support */ +#include "xt_instr_macros.h" #include "soc/spinlock.h" -#include +#include "hal/cpu_hal.h" +#include "esp_private/crosscore_int.h" +#include "esp_attr.h" +#include "esp_timer.h" /* required for esp_timer_get_time. [refactor-todo] make this common between archs */ +#include "esp_newlib.h" /* required for esp_reent_init() in tasks.c */ +#include "esp_heap_caps.h" #include "esp_rom_sys.h" -#include "sdkconfig.h" -#include "freertos/xtensa_api.h" -#include "esp_system.h" -#include "soc/cpu.h" -#include +#include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */ +#include "portbenchmark.h" +/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */ +#include +#include +#include +#include "soc/cpu.h" #ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS #include "soc/soc_memory_layout.h" #endif -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ +#ifdef __cplusplus +extern "C" { +#endif + -#include "esp_system.h" -#include "hal/cpu_hal.h" -#include "xt_instr_macros.h" -/* Type definitions. */ -#define portCHAR int8_t -#define portFLOAT float -#define portDOUBLE double -#define portLONG int32_t -#define portSHORT int16_t -#define portSTACK_TYPE uint8_t -#define portBASE_TYPE int +/* --------------------------------------------------- Port Types ------------------------------------------------------ + * - Port specific types. + * - The settings in this file configure FreeRTOS correctly for the given hardware and compiler. + * - These settings should not be altered. + * - The port types must come before first as they are used further down the file + * ------------------------------------------------------------------------------------------------------------------ */ -typedef portSTACK_TYPE StackType_t; -typedef portBASE_TYPE BaseType_t; -typedef unsigned portBASE_TYPE UBaseType_t; +#define portCHAR int8_t +#define portFLOAT float +#define portDOUBLE double +#define portLONG int32_t +#define portSHORT int16_t +#define portSTACK_TYPE uint8_t +#define portBASE_TYPE int + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef unsigned portBASE_TYPE UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff +typedef uint16_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffff #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif -/*-----------------------------------------------------------*/ -// portbenchmark -#include "portbenchmark.h" +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#include "sdkconfig.h" -#include "esp_attr.h" -#include "portmacro_priv.h" - -// Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. -// They can be called from interrupts too. -// WARNING: Only applies to current CPU. See notes above. -static inline unsigned portENTER_CRITICAL_NESTED(void) { - unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); - portbenchmarkINTERRUPT_DISABLE(); - return state; -} -#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) -/* -Modifications to portENTER_CRITICAL. -For an introduction, see "Critical Sections & Disabling Interrupts" in docs/api-guides/freertos-smp.rst +/* ----------------------------------------------- Port Configurations ------------------------------------------------- + * - Configurations values supplied by each port + * - Required by FreeRTOS + * ------------------------------------------------------------------------------------------------------------------ */ -The original portENTER_CRITICAL only disabled the ISRs. This is enough for single-CPU operation: by -disabling the interrupts, there is no task switch so no other tasks can meddle in the data, and because -interrupts are disabled, ISRs can't corrupt data structures either. +#define portCRITICAL_NESTING_IN_TCB 0 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 4 +#define portNOP() XT_NOP() -For multiprocessing, things get a bit more hairy. First of all, disabling the interrupts doesn't stop -the tasks or ISRs on the other processors meddling with our CPU. For tasks, this is solved by adding -a spinlock to the portENTER_CRITICAL macro. A task running on the other CPU accessing the same data will -spinlock in the portENTER_CRITICAL code until the first CPU is done. -For ISRs, we now also need muxes: while portENTER_CRITICAL disabling interrupts will stop ISRs on the same -CPU from meddling with the data, it does not stop interrupts on the other cores from interfering with the -data. For this, we also use a spinlock in the routines called by the ISR, but these spinlocks -do not disable the interrupts (because they already are). -This all assumes that interrupts are either entirely disabled or enabled. Interrupt priority levels -will break this scheme. +/* ---------------------------------------------- Forward Declarations ------------------------------------------------- + * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface + * - These must come before definition/declaration of the FreeRTOS porting interface + * ------------------------------------------------------------------------------------------------------------------ */ -Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vPortEnterCritical, meaning -that either function can be called both from ISR as well as task context. This is not standard FreeRTOS -behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations. -*/ -/* "mux" data structure (spinlock) */ -typedef spinlock_t portMUX_TYPE; +// --------------------- Interrupts ------------------------ -#define portMUX_FREE_VAL SPINLOCK_FREE -#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /* When passed for 'timeout_cycles', spin forever if necessary */ -#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /* Try to acquire the spinlock a single time only */ -#define portMUX_INITIALIZER_UNLOCKED SPINLOCK_INITIALIZER +/** + * @brief Checks if the current core is in an ISR context + * + * - ISR context consist of Low/Mid priority ISR, or time tick ISR + * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in ISR + * - pdFALSE otherwise + */ +BaseType_t xPortInIsrContext(void); -#define portCRITICAL_NESTING_IN_TCB 0 +/** + * @brief Asserts if in ISR context + * + * - Asserts on xPortInIsrContext() internally + * + * @note [refactor-todo] Check if this API is still required + * @note [refactor-todo] Check if this should be inlined + */ +void vPortAssertIfInISR(void); -static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux) -{ - spinlock_initialize(mux); -} +/** + * @brief Check if in ISR context from High priority ISRs + * + * - Called from High priority ISR + * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority) + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in previous in ISR context + * - pdFALSE otherwise + */ +BaseType_t xPortInterruptedFromISRContext(void); -static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux) -{ - spinlock_acquire(mux, portMUX_NO_TIMEOUT); -} +/** + * @brief Disable interrupts in a nested manner + * + * - Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. + * - They can be called from interrupts too. + * - WARNING Only applies to current CPU. + * @note [refactor-todo] Define this as portSET_INTERRUPT_MASK_FROM_ISR() instead + * @return unsigned Previous interrupt state + */ +static inline unsigned __attribute__((always_inline)) portENTER_CRITICAL_NESTED(void); + +/* ---------------------- Spinlocks ------------------------ + * - Modifications made to critical sections to support SMP + * - See "Critical Sections & Disabling Interrupts" in docs/api-guides/freertos-smp.rst for more details + * - Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vPortEnterCritical, meaning that + * either function can be called both from ISR as well as task context. This is not standard FreeRTOS + * behaviorr; please keep this in mind if you need any compatibility with other FreeRTOS implementations. + * @note [refactor-todo] Check if these comments are still true + * ------------------------------------------------------ */ + +typedef spinlock_t portMUX_TYPE; /**< Spinlock type used by FreeRTOS critical sections */ +#define portMUX_INITIALIZER_UNLOCKED SPINLOCK_INITIALIZER /**< Spinlock initializer */ +#define portMUX_FREE_VAL SPINLOCK_FREE /**< Spinlock is free. [refactor-todo] check if this is still required */ +#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */ +#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */ -static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout) -{ - return (spinlock_acquire(mux, timeout)); -} +/** + * @brief Initialize a spinlock + * + * - Initializes a spinlock that is used by FreeRTOS SMP critical sections + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux) -{ - spinlock_release(mux); -} +/** + * @brief Acquire a spinlock + * + * @note [refactor-todo] check if we still need this + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux); +/** + * @brief Acquire a spinlock but with a specified timeout + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to bool return type) + * + * @param[in] mux Spinlock + * @param timeout + * @return true Spinlock acquired + * @return false Timed out + */ +static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout); + +/** + * @brief Release a spinlock + * + * @note [refactor-todo] check if we still need this + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux); + +/** + * @brief Wrapper for atomic compare-and-set instruction + * + * This subroutine will atomically compare *addr to 'compare'. If *addr == compare, *addr is set to *set. *set is + * updated with the previous value of *addr (either 'compare' or some other value.) + * + * @warning From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the "bitwise inverse" of + * the old mem if the mem wasn't written. This doesn't seem to happen on the ESP32 (portMUX assertions would + * fail). + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to void return type) + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set); + +/** + * @brief Wrapper for atomic compare-and-set instruction in external RAM + * + * Atomic compare-and-set but the target address is placed in external RAM + * + * @note [refactor-todo] check if we still need this + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set); + +// ------------------ Critical Sections -------------------- + +/** + * @brief Enter a SMP critical section + * + * - Disable interrupts + * - Takes spinlock + * - Can be nested + * + * @param[in] mux Spinlock + */ void vPortEnterCritical(portMUX_TYPE *mux); + +/** + * @brief Exit a SMP critical section + * + * - Releases spinlock + * - Reenables interrupts + * - Can be nested + * + * @param[in] mux Spinlock + */ void vPortExitCritical(portMUX_TYPE *mux); -#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() -void vPortAssertIfInISR(void); +/** + * @brief FreeRTOS compliant version of enter critical + * + * - Ensures that critical section is only entered from task context + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux); -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. +/** + * @brief FreeRTOS compliant version of exit critical + * + * @param[in] mux Spinlock */ -BaseType_t xPortInIsrContext(void); +static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux) -{ - if(!xPortInIsrContext()) { - vPortEnterCritical(mux); - } else { - esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } -} +/** + * @brief Safe version of enter critical + * + * - This function can be used to enter a critical section from both task and ISR contexts + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux) -{ - if(!xPortInIsrContext()) { - vPortExitCritical(mux); - } else { - esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } -} +/** + * @brief Safe version of exit critical + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux); -#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE -/* Calling port*_CRITICAL from ISR context would cause an assert failure. - * If the parent function is called from both ISR and Non-ISR context then call port*_CRITICAL_SAFE +// ---------------------- Yielding ------------------------- + +/** + * @brief Perform a solicited context switch + * + * - Defined in portasm.S + * + * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead */ -#define portENTER_CRITICAL(mux) vPortEnterCriticalCompliance(mux) -#define portEXIT_CRITICAL(mux) vPortExitCriticalCompliance(mux) -#else -#define portENTER_CRITICAL(mux) vPortEnterCritical(mux) -#define portEXIT_CRITICAL(mux) vPortExitCritical(mux) -#endif +void vPortYield( void ); -#define portENTER_CRITICAL_ISR(mux) vPortEnterCritical(mux) -#define portEXIT_CRITICAL_ISR(mux) vPortExitCritical(mux) +/** + * @brief + * + * @note [refactor-todo] Refactor this to avoid va_args + * @param argc + * @param ... Variable arguments to allow for IDF prototype without arguments, and vanilla version WITH argument + */ +void vPortEvaluateYieldFromISR(int argc, ...); -static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux) -{ - if (xPortInIsrContext()) { - portENTER_CRITICAL_ISR(mux); - } else { - portENTER_CRITICAL(mux); - } -} +/** + * @brief Yields the other core + * + * - Send an interrupt to another core in order to make the task running on it yield for a higher-priority task. + * - Can be used to yield current core as well + * + * @note [refactor-todo] Put this into private macros as its only called from task.c and is not public API + * @param coreid ID of core to yield + */ +void vPortYieldOtherCore(BaseType_t coreid); -static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux) -{ - if (xPortInIsrContext()) { - portEXIT_CRITICAL_ISR(mux); - } else { - portEXIT_CRITICAL(mux); - } -} +/** + * @brief Checks if the current core can yield + * + * - A core cannot yield if its in an ISR or in a critical section + * + * @note [refactor-todo] See if this can be separated from port macro + * @return true Core can yield + * @return false Core cannot yield + */ +static inline bool IRAM_ATTR xPortCanYield(void); -#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux) -#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux) +// ------------------- Hook Functions ---------------------- -/* - * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare - * *addr to 'compare'. If *addr == compare, *addr is set to *set. *set is updated with the previous - * value of *addr (either 'compare' or some other value.) +extern void esp_vApplicationIdleHook(void); /* Required by tasks.c */ +extern void esp_vApplicationTickHook(void); /* Required by tasks.c */ + +/** + * @brief Hook function called on entry to tickless idle + * + * - Implemented in pm_impl.c * - * Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the - * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the - * ESP32 (portMUX assertions would fail). + * @param xExpectedIdleTime Expected idle time */ -static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { - compare_and_set_native(addr, compare, set); -} +void vApplicationSleep(TickType_t xExpectedIdleTime); -// Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? -// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. -// -// Only applies to one CPU. See notes above & below for reasons not to use these. -#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) -#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) +// ----------------------- System -------------------------- +/** + * @brief Get the tick rate per second + * + * @note [refactor-todo] make this inline + * @return uint32_t Tick rate in Hz + */ +uint32_t xPortGetTickRateHz(void); -// These FreeRTOS versions are similar to the nested versions above -#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) +/** + * @brief Set a watchpoint to watch the last 32 bytes of the stack + * + * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint + * around. + * + * @param pxStackStart Pointer to the start of the stack + */ +void vPortSetStackWatchpoint( void *pxStackStart ); -//Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force -//the stack memory to always be internal. -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps) -#define pvPortMallocStackMem(size) heap_caps_malloc(size, portStackMemoryCaps) - -//xTaskCreateStatic uses these functions to check incoming memory. -#define portVALID_TCB_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY -#define portVALID_STACK_MEM(ptr) esp_ptr_byte_accessible(ptr) -#else -#define portVALID_STACK_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#endif +/** + * @brief Get the current core's ID + * + * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly + * @return BaseType_t Core ID + */ +static inline BaseType_t IRAM_ATTR xPortGetCoreID(void); -static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) -{ -#ifdef CONFIG_SPIRAM - compare_and_set_extram(addr, compare, set); -#endif -} +/* ------------------------------------------- FreeRTOS Porting Interface ---------------------------------------------- + * - Contains all the mappings of the macros required by FreeRTOS + * - Most come after forward declare as porting macros map to declared functions + * - Maps to forward declared functions + * ------------------------------------------------------------------------------------------------------------------ */ -/*-----------------------------------------------------------*/ +// ----------------------- Memory -------------------------- -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 4 -#define portNOP() XT_NOP() -/*-----------------------------------------------------------*/ +/** + * @brief Task memory allocation macros + * + * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack + * memory to always be internal. + * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes + */ +#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps) +#define pvPortMallocStackMem(size) heap_caps_malloc(size, portStackMemoryCaps) -/* Fine resolution time */ -#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() -//ccount or esp_timer are initialized elsewhere -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +// --------------------- Interrupts ------------------------ -#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER -/* Coarse resolution time (us) */ -#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do {x = (uint32_t)esp_timer_get_time();} while(0) -#endif +#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) -void vPortYield( void ); -void vPortEvaluateYieldFromISR(int argc, ...); -void _frxt_setup_switch( void ); +/** + * - Only applies to current core + * - These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. + * + * @note [refactor-todo] replace XTOS_SET_INTLEVEL with more efficient version, if any? + */ +#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) +#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) /** - * Macro to count number of arguments of a __VA_ARGS__ used to support portYIELD_FROM_ISR with, - * or without arguments. The macro counts only 0 or 1 arguments. + * ISR versions to enable/disable interrupts + */ +#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) + +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + +// ------------------ Critical Sections -------------------- + +/** + * @brief FreeRTOS critical section macros * - * In the future, we want to switch to C++20. We also want to become compatible with clang. - * Hence, we provide two versions of the following macros which are using variadic arguments. - * The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,). - * This allows users to compile their code with standard C++20 enabled instead of the GNU extension. - * Below C++20, we haven't found any good alternative to using ##__VA_ARGS__. + * - Added a spinlock argument for SMP + * - Can be nested + * - Compliance versions will assert if regular critical section API is used in ISR context + * - Safe versions can be called from either contexts */ -#if defined(__cplusplus) && (__cplusplus > 201703L) -#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0 __VA_OPT__(,) __VA_ARGS__,1,0) +#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE +#define portENTER_CRITICAL(mux) vPortEnterCriticalCompliance(mux) +#define portEXIT_CRITICAL(mux) vPortExitCriticalCompliance(mux) #else -#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0, ##__VA_ARGS__,1,0) -#endif -#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count +#define portENTER_CRITICAL(mux) vPortEnterCritical(mux) +#define portEXIT_CRITICAL(mux) vPortExitCritical(mux) +#endif /* CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE */ +#define portENTER_CRITICAL_ISR(mux) vPortEnterCritical(mux) +#define portEXIT_CRITICAL_ISR(mux) vPortExitCritical(mux) +#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux) +#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux) -_Static_assert(portGET_ARGUMENT_COUNT() == 0, "portGET_ARGUMENT_COUNT() result does not match for 0 arguments"); -_Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result does not match for 1 argument"); +// ---------------------- Yielding ------------------------- -#define portYIELD() vPortYield() +#define portYIELD() vPortYield() /** * @note The macro below could be used when passing a single argument, or without any argument, * it was developed to support both usages of portYIELD inside of an ISR. Any other usage form - * might result in undesired behaviour + * might result in undesired behavior + * + * @note [refactor-todo] Refactor this to avoid va_args */ #if defined(__cplusplus) && (__cplusplus > 201703L) #define portYIELD_FROM_ISR(...) vPortEvaluateYieldFromISR(portGET_ARGUMENT_COUNT(__VA_ARGS__) __VA_OPT__(,) __VA_ARGS__) @@ -351,121 +483,137 @@ _Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result */ #define portYIELD_WITHIN_API() esp_crosscore_int_send_yield(xPortGetCoreID()) -/*-----------------------------------------------------------*/ - -/* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) - -// When coprocessors are defined, we to maintain a pointer to coprocessors area. -// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: -// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. -// The field is normally used for memory protection. FreeRTOS should create another general purpose field. -typedef struct { - #if XCHAL_CP_NUM > 0 - volatile StackType_t* coproc_area; // Pointer to coprocessor save area; MUST BE FIRST - #endif - - #if portUSING_MPU_WRAPPERS - // Define here mpu_settings, which is port dependent - int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet - #endif - - #if configUSE_TRACE_FACILITY_2 - struct { - // Cf. porttraceStamp() - int taskstamp; /* Stamp from inside task to see where we are */ - int taskstampcount; /* A counter usually incremented when we restart the task's loop */ - } porttrace; - #endif -} xMPU_SETTINGS; - -// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) -#if (XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area - #undef portUSING_MPU_WRAPPERS - #define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area - #define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA -#endif - -extern void esp_vApplicationIdleHook( void ); -extern void esp_vApplicationTickHook( void ); +// ------------------- Hook Functions ---------------------- #ifndef CONFIG_FREERTOS_LEGACY_HOOKS -#define vApplicationIdleHook esp_vApplicationIdleHook -#define vApplicationTickHook esp_vApplicationTickHook +#define vApplicationIdleHook esp_vApplicationIdleHook +#define vApplicationTickHook esp_vApplicationTickHook #endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */ -void vApplicationSleep( TickType_t xExpectedIdleTime ); +#define portSUPPRESS_TICKS_AND_SLEEP(idleTime) vApplicationSleep(idleTime) -#define portSUPPRESS_TICKS_AND_SLEEP( idleTime ) vApplicationSleep( idleTime ) +// ------------------- Run Time Stats ---------------------- -void _xt_coproc_release(volatile void * coproc_sa_base); +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() -/* Architecture specific optimisations. */ -#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 +/** + * - Fine resolution uses ccount + * - ALT is coarse and uses esp_timer + * @note [refactor-todo] Make fine and alt timers mutually exclusive + */ +#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() +#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER +#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do {x = (uint32_t)esp_timer_get_time();} while(0) +#endif +// -------------- Optimized Task Selection ----------------- + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #if( configMAX_PRIORITIES > 32 ) - #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice. +#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) +#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( ( uxReadyPriorities ) ) ) +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -/*-----------------------------------------------------------*/ -#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( ( uxReadyPriorities ) ) ) -#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +/* --------------------------------------------- Inline Implementations ------------------------------------------------ + * - Implementation of inline functions of the forward declares + * - Should come after forward declare and FreeRTOS Porting interface, as implementation may use both. + * - For implementation of non-inlined functions, see port.c + * ------------------------------------------------------------------------------------------------------------------ */ -/* - * Send an interrupt to another core in order to make the task running - * on it yield for a higher-priority task. - */ +// --------------------- Interrupts ------------------------ -void vPortYieldOtherCore( BaseType_t coreid) ; +static inline unsigned portENTER_CRITICAL_NESTED(void) +{ + unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); + portbenchmarkINTERRUPT_DISABLE(); + return state; +} -/* - Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack - watchpoint around. - */ -void vPortSetStackWatchpoint( void* pxStackStart ); +// ---------------------- Spinlocks ------------------------ -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. - */ -BaseType_t xPortInIsrContext(void); +static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux) +{ + spinlock_initialize(mux); +} -/* - * This function will be called in High prio ISRs. Returns true if the current core was in ISR context - * before calling into high prio ISR context. - */ -BaseType_t xPortInterruptedFromISRContext(void); +static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux) +{ + spinlock_acquire(mux, portMUX_NO_TIMEOUT); +} -/* - * The structures and methods of manipulating the MPU are contained within the - * port layer. - * - * Fills the xMPUSettings structure with the memory region information - * contained in xRegions. - */ -#if( portUSING_MPU_WRAPPERS == 1 ) - struct xMEMORY_REGION; - void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION; - void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings ); +static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout) +{ + return (spinlock_acquire(mux, timeout)); +} + +static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux) +{ + spinlock_release(mux); +} + +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ + compare_and_set_native(addr, compare, set); +} + +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ +#ifdef CONFIG_SPIRAM + compare_and_set_extram(addr, compare, set); #endif +} -/* Multi-core: get current core ID */ -static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) { - return cpu_hal_get_core_id(); +// ------------------ Critical Sections -------------------- + +static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux) +{ + if (!xPortInIsrContext()) { + vPortEnterCritical(mux); + } else { + esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } } -/* Get tick rate per second */ -uint32_t xPortGetTickRateHz(void); +static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux) +{ + if (!xPortInIsrContext()) { + vPortExitCritical(mux); + } else { + esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } +} + +static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(mux); + } else { + portENTER_CRITICAL(mux); + } +} + +static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(mux); + } else { + portEXIT_CRITICAL(mux); + } +} + +// ---------------------- Yielding ------------------------- static inline bool IRAM_ATTR xPortCanYield(void) { @@ -484,22 +632,115 @@ static inline bool IRAM_ATTR xPortCanYield(void) return ((ps_reg & PS_INTLEVEL_MASK) == 0); } -// porttrace -#if configUSE_TRACE_FACILITY_2 -#include "porttrace.h" +// ----------------------- System -------------------------- + +static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) +{ + return (uint32_t) cpu_hal_get_core_id(); +} + + + +/* ------------------------------------------------------ Misc --------------------------------------------------------- + * - Miscellaneous porting macros + * - These are not port of the FreeRTOS porting interface, but are used by other FreeRTOS dependent components + * - [refactor-todo] Remove dependency on MPU wrappers by modifying TCB + * ------------------------------------------------------------------------------------------------------------------ */ + +// -------------------- Co-Processor ----------------------- + +// When coprocessors are defined, we maintain a pointer to coprocessors area. +// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: +// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. +// The field is normally used for memory protection. FreeRTOS should create another general purpose field. +typedef struct { +#if XCHAL_CP_NUM > 0 + volatile StackType_t *coproc_area; // Pointer to coprocessor save area; MUST BE FIRST +#endif + +#if portUSING_MPU_WRAPPERS + // Define here mpu_settings, which is port dependent + int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet #endif +} xMPU_SETTINGS; -// configASSERT_2 if requested -#if configASSERT_2 -#include -void exit(int); -#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); } +// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) +#if (XCHAL_CP_NUM > 0) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area +#undef portUSING_MPU_WRAPPERS +#define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area +#define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code +#define PRIVILEGED_FUNCTION +#define PRIVILEGED_DATA #endif -#endif // __ASSEMBLER__ +void _xt_coproc_release(volatile void *coproc_sa_base); + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +struct xMEMORY_REGION; +void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION *const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION; +void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings ); +#endif + +// -------------------- VA_ARGS Yield ---------------------- + +/** + * Macro to count number of arguments of a __VA_ARGS__ used to support portYIELD_FROM_ISR with, + * or without arguments. The macro counts only 0 or 1 arguments. + * + * In the future, we want to switch to C++20. We also want to become compatible with clang. + * Hence, we provide two versions of the following macros which are using variadic arguments. + * The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,). + * This allows users to compile their code with standard C++20 enabled instead of the GNU extension. + * Below C++20, we haven't found any good alternative to using ##__VA_ARGS__. + */ +#if defined(__cplusplus) && (__cplusplus > 201703L) +#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0 __VA_OPT__(,) __VA_ARGS__,1,0) +#else +#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0, ##__VA_ARGS__,1,0) +#endif +#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count + +_Static_assert(portGET_ARGUMENT_COUNT() == 0, "portGET_ARGUMENT_COUNT() result does not match for 0 arguments"); +_Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result does not match for 1 argument"); + +// -------------------- Heap Related ----------------------- + +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); + +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) #ifdef __cplusplus } #endif +#endif // __ASSEMBLER__ + #endif /* PORTMACRO_H */ diff --git a/tools/sdk/esp32/include/hal/include/hal/i2s_hal.h b/tools/sdk/esp32/include/hal/include/hal/i2s_hal.h index a08813db808..037970fa2b3 100644 --- a/tools/sdk/esp32/include/hal/include/hal/i2s_hal.h +++ b/tools/sdk/esp32/include/hal/include/hal/i2s_hal.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -176,28 +168,28 @@ void i2s_hal_enable_slave_fd_mode(i2s_hal_context_t *hal); * * @param hal Context of the HAL layer */ -#define i2s_hal_start_tx(hal) i2s_ll_tx_start((hal)->dev) +void i2s_hal_start_tx(i2s_hal_context_t *hal); /** * @brief Start I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_start_rx(hal) i2s_ll_rx_start((hal)->dev) +void i2s_hal_start_rx(i2s_hal_context_t *hal); /** * @brief Stop I2S tx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_tx(hal) i2s_ll_tx_stop((hal)->dev) +void i2s_hal_stop_tx(i2s_hal_context_t *hal); /** * @brief Stop I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_rx(hal) i2s_ll_rx_stop((hal)->dev) +void i2s_hal_stop_rx(i2s_hal_context_t *hal); /** * @brief Set the received data length to trigger `in_suc_eof` interrupt. diff --git a/tools/sdk/esp32/include/hal/include/hal/lcd_hal.h b/tools/sdk/esp32/include/hal/include/hal/lcd_hal.h index 76e28dda0e4..db255b3d1e4 100644 --- a/tools/sdk/esp32/include/hal/include/hal/lcd_hal.h +++ b/tools/sdk/esp32/include/hal/include/hal/lcd_hal.h @@ -1,22 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * NOTICE - * The HAL is not public api, don't use in application code. - * See readme.md in soc/README.md - ******************************************************************************/ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/tools/sdk/esp32/include/hal/include/hal/lcd_types.h b/tools/sdk/esp32/include/hal/include/hal/lcd_types.h index 69dab14801d..01e6d0c2949 100644 --- a/tools/sdk/esp32/include/hal/include/hal/lcd_types.h +++ b/tools/sdk/esp32/include/hal/include/hal/lcd_types.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -21,15 +13,12 @@ extern "C" { /** * @brief LCD clock source * @note User should select the clock source based on the real requirement: - * ╔═════════════════════╦══════════════════════════╦════════════════════════════╗ - * ║ LCD clock source ║ Features ║ Power Management ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_PLL160M ║ High resolution, fixed ║ ESP_PM_APB_FREQ_MAX lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_APLL ║ Configurable resolution ║ ESP_PM_NO_LIGHT_SLEEP lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_XTAL ║ Medium resolution, fixed ║ No PM lock ║ - * ╚═════════════════════╩══════════════════════════╩════════════════════════════╝ + * + * | LCD clock source | Features | Power Management | + * |---------------------|--------------------------|----------------------------| + * | LCD_CLK_SRC_PLL160M | High resolution, fixed | ESP_PM_APB_FREQ_MAX lock | + * | LCD_CLK_SRC_APLL | Configurable resolution | ESP_PM_NO_LIGHT_SLEEP lock | + * | LCD_CLK_SRC_XTAL | Medium resolution, fixed | No PM lock | */ typedef enum { LCD_CLK_SRC_PLL160M, /*!< Select PLL160M as the source clock */ diff --git a/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h b/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h index ec027bf8705..9085f5eecd8 100644 --- a/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h +++ b/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -155,12 +147,23 @@ typedef enum { TOUCH_PAD_INTR_MASK_INACTIVE = BIT(2), /*! +#include +#include "sdkconfig.h" +#include "esp_err.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#endif +#include "esp_flash.h" +#include "hal/spi_flash_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief To setup Flash chip + */ +esp_err_t spi_flash_init_chip_state(void); + +/** + * @brief Make MSPI work under 20Mhz + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_low_speed_mode(bool control_spi1); + +/** + * @brief Make MSPI work under the frequency as users set + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_high_speed_mode(bool control_spi1); + +/** + * @brief Tune MSPI flash timing to make it work under high frequency + */ +void spi_timing_flash_tuning(void); + +/** + * @brief Tune MSPI psram timing to make it work under high frequency + */ +void spi_timing_psram_tuning(void); + +/** + * @brief To initislize the MSPI pins + */ +void esp_mspi_pin_init(void); + +/** + * @brief Set SPI1 registers to make ROM functions work + * @note This function is used for setting SPI1 registers to the state that ROM SPI functions work + */ +void spi_flash_set_rom_required_regs(void); + +/** + * @brief Initialize main flash + * @param chip Pointer to main SPI flash(SPI1 CS0) chip to use.. + */ +esp_err_t esp_flash_init_main(esp_flash_t *chip); + +/** + * @brief Should be only used by SPI1 Flash driver to know the necessary timing registers + * @param out_timing_config Pointer to timing_tuning parameters. + */ +void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing_config); + +/** + * @brief Judge if the flash in tuned + */ +bool spi_timine_config_flash_is_tuned(void); + +/** + * @brief Set Flash chip specifically required MSPI register settings here + */ +void spi_flash_set_vendor_required_regs(void); + + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h b/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h new file mode 100644 index 00000000000..4292213943f --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ESP_MBO_H +#define _ESP_MBO_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum non_pref_chan_reason: Reason for non preference of channel + */ +enum non_pref_chan_reason { + NON_PREF_CHAN_REASON_UNSPECIFIED = 0, + NON_PREF_CHAN_REASON_RSSI = 1, + NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, + NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, +}; + +/** + * @brief Channel structure for non preferred channel + * + * @param reason: enum non_pref_chan_reason + * @param oper_class: operating class for the channel + * @param chan: channel number + * @param preference: channel preference + */ +struct non_pref_chan { + enum non_pref_chan_reason reason; + uint8_t oper_class; + uint8_t chan; + uint8_t preference; +}; + +/** + * @brief Array structure for non preferred channel struct + * + * @param non_pref_chan_num: channel count + * @param chan: array of non_pref_chan type + */ +struct non_pref_chan_s { + size_t non_pref_chan_num; + struct non_pref_chan chan[]; +}; + +/** + * @brief Update channel preference for MBO IE + * + * @param non_pref_chan: Non preference channel list + * + * @return + * - 0: success else failure + */ +int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h b/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h index a1dcfb655c5..4301385d2cf 100644 --- a/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h +++ b/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef _ESP_WNM_H @@ -29,11 +19,13 @@ enum btm_query_reason { REASON_UNSPECIFIED = 0, REASON_FRAME_LOSS = 1, REASON_DELAY = 2, - REASON_QOS_CAPACITY = 3, - REASON_FIRST_ASSOC = 4, - REASON_LOAD_BALALNCE = 5, - REASON_BETTER_AP = 6, - REASON_CURRENT_DEAUTH = 7, + REASON_BANDWIDTH = 3, + REASON_LOAD_BALANCE = 4, + REASON_RSSI = 5, + REASON_RETRANSMISSIONS = 6, + REASON_INTERFERENCE = 7, + REASON_GRAY_ZONE = 8, + REASON_PREMIUM_AP = 9, }; /** diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h new file mode 100644 index 00000000000..c6c86bc536f --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h @@ -0,0 +1,116 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_DPP_H +#define ESP_DPP_H + +#include + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ +#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */ +#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ + +/** @brief Types of Bootstrap Methods for DPP. */ +typedef enum dpp_bootstrap_type { + DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ + DPP_BOOTSTRAP_PKEX, /**< Proof of Knowledge Method */ + DPP_BOOTSTRAP_NFC_URI, /**< NFC URI record Method */ +} esp_supp_dpp_bootstrap_t; + +/** @brief Types of Callback Events received from DPP Supplicant. */ +typedef enum { + ESP_SUPP_DPP_URI_READY, /**< URI is ready through Bootstrapping */ + ESP_SUPP_DPP_CFG_RECVD, /**< Config received via DPP Authentication */ + ESP_SUPP_DPP_FAIL, /**< DPP Authentication failure */ +} esp_supp_dpp_event_t; + +/** + * @brief Callback function for receiving DPP Events from Supplicant. + * + * Callback function will be called with DPP related information. + * + * @param evt DPP event ID + * @param data Event data payload + */ +typedef void (*esp_supp_dpp_event_cb_t)(esp_supp_dpp_event_t evt, void *data); + +/** + * @brief Initialize DPP Supplicant + * + * Starts DPP Supplicant and initializes related Data Structures. + * + * @param evt_cb Callback function to receive DPP related events + * + * return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t evt_cb); + +/** + * @brief De-initalize DPP Supplicant + * + * Frees memory from DPP Supplicant Data Structures. + */ +void esp_supp_dpp_deinit(void); + +/** + * @brief Generates Bootstrap Information as an Enrollee. + * + * Generates Out Of Band Bootstrap information as an Enrollee which can be + * used by a DPP Configurator to provision the Enrollee. + * + * @param chan_list List of channels device will be available on for listening + * @param type Bootstrap method type, only QR Code method is supported for now. + * @param key (Optional) Private Key used to generate a Bootstrapping Public Key + * @param info (Optional) Ancilliary Device Information like Serial Number + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t +esp_supp_dpp_bootstrap_gen(const char *chan_list, esp_supp_dpp_bootstrap_t type, + const char *key, const char *info); + +/** + * @brief Start listening on Channels provided during esp_supp_dpp_bootstrap_gen. + * + * Listens on every Channel from Channel List for a pre-defined wait time. + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Generic Failure + * - ESP_ERR_INVALID_STATE: ROC attempted before WiFi is started + * - ESP_ERR_NO_MEM: Memory allocation failed while posting ROC request + */ +esp_err_t esp_supp_dpp_start_listen(void); + +/** + * @brief Stop listening on Channels. + * + * Stops listening on Channels and cancels ongoing listen operation. + */ +void esp_supp_dpp_stop_listen(void); + +#ifdef __cplusplus +} +#endif +#endif /* ESP_DPP_H */ diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h new file mode 100644 index 00000000000..1ffcf180475 --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h @@ -0,0 +1,52 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_RRM_H +#define _ESP_RRM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Callback function type to get neighbor report + * + * @param ctx: neighbor report context + * @param report: neighbor report + * @param report_len: neighbor report length + * + * @return + * - void + */ +typedef void (*neighbor_rep_request_cb)(void *ctx, const uint8_t *report, size_t report_len); + +/** + * @brief Send Radio measurement neighbor report request to connected AP + * + * @param cb: callback function for neighbor report + * @param cb_ctx: callback context + * + * @return + * - 0: success else failure + */ +int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb, + void *cb_ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h new file mode 100644 index 00000000000..a1dcfb655c5 --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h @@ -0,0 +1,56 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_WNM_H +#define _ESP_WNM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum btm_query_reason: Reason code for sending btm query + */ +enum btm_query_reason { + REASON_UNSPECIFIED = 0, + REASON_FRAME_LOSS = 1, + REASON_DELAY = 2, + REASON_QOS_CAPACITY = 3, + REASON_FIRST_ASSOC = 4, + REASON_LOAD_BALALNCE = 5, + REASON_BETTER_AP = 6, + REASON_CURRENT_DEAUTH = 7, +}; + +/** + * @brief Send bss transition query to connected AP + * + * @param query_reason: reason for sending query + * @param btm_candidates: btm candidates list if available + * @param cand_list: whether candidate list to be included from scan results available in supplicant's cache. + * + * @return + * - 0: success else failure + */ +int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, + const char *btm_candidates, + int cand_list); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h new file mode 100644 index 00000000000..f448b737c70 --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h @@ -0,0 +1,79 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPA_H__ +#define __ESP_WPA_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_wifi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPA_APIs WPS APIs + * @brief ESP32 Supplicant APIs + * + */ + +/** @addtogroup WPA_APIs + * @{ + */ +/* Crypto callback functions */ +const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; +/* Mesh crypto callback functions */ +const mesh_crypto_funcs_t g_wifi_default_mesh_crypto_funcs; + +/** + * @brief Supplicant initialization + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_NO_MEM : out of memory + */ +esp_err_t esp_supplicant_init(void); + +/** + * @brief Supplicant deinitialization + * + * @return + * - ESP_OK : succeed + * - others: failed + */ +esp_err_t esp_supplicant_deinit(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPA_H__ */ diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h new file mode 100644 index 00000000000..c6c2930a0fe --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h @@ -0,0 +1,215 @@ +// Hardware crypto support Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_WPA2_H +#define _ESP_WPA2_H + +#include + +#include "esp_err.h" + +typedef enum { + ESP_EAP_TTLS_PHASE2_EAP, + ESP_EAP_TTLS_PHASE2_MSCHAPV2, + ESP_EAP_TTLS_PHASE2_MSCHAP, + ESP_EAP_TTLS_PHASE2_PAP, + ESP_EAP_TTLS_PHASE2_CHAP +} esp_eap_ttls_phase2_types ; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_enable(void); + +/** + * @brief Disable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + */ +esp_err_t esp_wifi_sta_wpa2_ent_disable(void); + +/** + * @brief Set identity for PEAP/TTLS method. + * + * @attention The API only passes the parameter identity to the global pointer variable in wpa2 enterprise module. + * + * @param identity: point to address where stores the identity; + * @param len: length of identity, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len); + +/** + * @brief Clear identity for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_identity(void); + +/** + * @brief Set username for PEAP/TTLS method. + * + * @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module. + * + * @param username: point to address where stores the username; + * @param len: length of username, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len); + +/** + * @brief Clear username for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_username(void); + +/** + * @brief Set password for PEAP/TTLS method.. + * + * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * + * @param password: point to address where stores the password; + * @param len: length of password(len > 0) + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len); + +/** + * @brief Clear password for PEAP/TTLS method.. + */ +void esp_wifi_sta_wpa2_ent_clear_password(void); + +/** + * @brief Set new password for MSCHAPv2 method.. + * + * @attention 1. The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * @attention 2. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. + * + * @param new_password: point to address where stores the password; + * @param len: length of password + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ + +esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len); + +/** + * @brief Clear new password for MSCHAPv2 method.. + */ +void esp_wifi_sta_wpa2_ent_clear_new_password(void); + +/** + * @brief Set CA certificate for PEAP/TTLS method. + * + * @attention 1. The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. + * @attention 2. The ca_cert should be zero terminated. + * + * @param ca_cert: point to address where stores the CA certificate; + * @param ca_cert_len: length of ca_cert + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len); + +/** + * @brief Clear CA certificate for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); + +/** + * @brief Set client certificate and key. + * + * @attention 1. The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. + * @attention 2. The client_cert, private_key and private_key_passwd should be zero terminated. + * + * @param client_cert: point to address where stores the client certificate; + * @param client_cert_len: length of client certificate; + * @param private_key: point to address where stores the private key; + * @param private_key_len: length of private key, limited to 1~2048; + * @param private_key_password: point to address where stores the private key password; + * @param private_key_password_len: length of private key password; + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len); + +/** + * @brief Clear client certificate and key. + */ +void esp_wifi_sta_wpa2_ent_clear_cert_key(void); + +/** + * @brief Set wpa2 enterprise certs time check(disable or not). + * + * @param true: disable wpa2 enterprise certs time check + * @param false: enable wpa2 enterprise certs time check + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); + +/** + * @brief Get wpa2 enterprise certs time check(disable or not). + * + * @param disable: store disable value + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); + +/** + * @brief Set wpa2 enterprise ttls phase2 method + * + * @param type: the type of phase 2 method to be used + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wps.h b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wps.h new file mode 100644 index 00000000000..25c06782ecb --- /dev/null +++ b/tools/sdk/esp32/include/wpa_supplicant/include/esp_supplicant/esp_wps.h @@ -0,0 +1,141 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPS_H__ +#define __ESP_WPS_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP32 WPS APIs + * + * WPS can only be used when ESP32 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +#define ESP_ERR_WIFI_REGISTRAR (ESP_ERR_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ +#define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_MAX, +} wps_type_t; + +#define WPS_MAX_MANUFACTURER_LEN 65 +#define WPS_MAX_MODEL_NUMBER_LEN 33 +#define WPS_MAX_MODEL_NAME_LEN 33 +#define WPS_MAX_DEVICE_NAME_LEN 33 + +typedef struct { + char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer, null-terminated string. The default manufcturer is used if the string is empty */ + char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number, null-terminated string. The default model number is used if the string is empty */ + char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name, null-terminated string. The default model name is used if the string is empty */ + char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name, null-terminated string. The default device name is used if the string is empty */ +} wps_factory_information_t; + +typedef struct { + wps_type_t wps_type; + wps_factory_information_t factory_info; +} esp_wps_config_t; + +#define WPS_CONFIG_INIT_DEFAULT(type) { \ + .wps_type = type, \ + .factory_info = { \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP32") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_name, "ESPRESSIF IOT") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(device_name, "ESP STATION") \ + } \ +} + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_enable(const esp_wps_config_t *config); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + */ +esp_err_t esp_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time (not supported in IDF v1.0) + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_start(int timeout_ms); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPS_H__ */ diff --git a/tools/sdk/esp32/ld/libcat_face_detect.a b/tools/sdk/esp32/ld/libcat_face_detect.a index 18bff9da4e2..804fea7893f 100644 Binary files a/tools/sdk/esp32/ld/libcat_face_detect.a and b/tools/sdk/esp32/ld/libcat_face_detect.a differ diff --git a/tools/sdk/esp32/ld/libdetection.a b/tools/sdk/esp32/ld/libdetection.a new file mode 100644 index 00000000000..8d5081bdfd9 Binary files /dev/null and b/tools/sdk/esp32/ld/libdetection.a differ diff --git a/tools/sdk/esp32/ld/libdetection_cat_face.a b/tools/sdk/esp32/ld/libdetection_cat_face.a new file mode 100644 index 00000000000..e1d42e756b8 Binary files /dev/null and b/tools/sdk/esp32/ld/libdetection_cat_face.a differ diff --git a/tools/sdk/esp32/ld/libdl.a b/tools/sdk/esp32/ld/libdl.a index 8840177a68b..6917a349872 100644 Binary files a/tools/sdk/esp32/ld/libdl.a and b/tools/sdk/esp32/ld/libdl.a differ diff --git a/tools/sdk/esp32/ld/libfd.a b/tools/sdk/esp32/ld/libfd.a new file mode 100644 index 00000000000..9f58faef4a2 Binary files /dev/null and b/tools/sdk/esp32/ld/libfd.a differ diff --git a/tools/sdk/esp32/ld/libfr.a b/tools/sdk/esp32/ld/libfr.a new file mode 100644 index 00000000000..c824bcd9a3e Binary files /dev/null and b/tools/sdk/esp32/ld/libfr.a differ diff --git a/tools/sdk/esp32/ld/libhuman_face_detect.a b/tools/sdk/esp32/ld/libhuman_face_detect.a index 8a6930968aa..8656df19de8 100644 Binary files a/tools/sdk/esp32/ld/libhuman_face_detect.a and b/tools/sdk/esp32/ld/libhuman_face_detect.a differ diff --git a/tools/sdk/esp32/ld/libpe.a b/tools/sdk/esp32/ld/libpe.a new file mode 100644 index 00000000000..b859f2429eb Binary files /dev/null and b/tools/sdk/esp32/ld/libpe.a differ diff --git a/tools/sdk/esp32/ld/sections.ld b/tools/sdk/esp32/ld/sections.ld index 85a3a35947d..8a4eb2c853a 100644 --- a/tools/sdk/esp32/ld/sections.ld +++ b/tools/sdk/esp32/ld/sections.ld @@ -1,6 +1,6 @@ /* Automatically generated file; DO NOT EDIT */ /* Espressif IoT Development Framework Linker Script */ -/* Generated from: /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32/sections.ld.in */ +/* Generated from: /home/rocorbera/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32/sections.ld.in */ /* * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD diff --git a/tools/sdk/esp32/lib/libapp_trace.a b/tools/sdk/esp32/lib/libapp_trace.a index 457355a9cff..80b308caf57 100644 Binary files a/tools/sdk/esp32/lib/libapp_trace.a and b/tools/sdk/esp32/lib/libapp_trace.a differ diff --git a/tools/sdk/esp32/lib/libapp_update.a b/tools/sdk/esp32/lib/libapp_update.a index 551bfb86cf9..59702d99c5c 100644 Binary files a/tools/sdk/esp32/lib/libapp_update.a and b/tools/sdk/esp32/lib/libapp_update.a differ diff --git a/tools/sdk/esp32/lib/libasio.a b/tools/sdk/esp32/lib/libasio.a index 69e072d1737..e961f7a1258 100644 Binary files a/tools/sdk/esp32/lib/libasio.a and b/tools/sdk/esp32/lib/libasio.a differ diff --git a/tools/sdk/esp32/lib/libbootloader_support.a b/tools/sdk/esp32/lib/libbootloader_support.a index db0df17b7a6..967929c284e 100644 Binary files a/tools/sdk/esp32/lib/libbootloader_support.a and b/tools/sdk/esp32/lib/libbootloader_support.a differ diff --git a/tools/sdk/esp32/lib/libbt.a b/tools/sdk/esp32/lib/libbt.a index cf6f28abaf3..caa12018971 100644 Binary files a/tools/sdk/esp32/lib/libbt.a and b/tools/sdk/esp32/lib/libbt.a differ diff --git a/tools/sdk/esp32/lib/libbutton.a b/tools/sdk/esp32/lib/libbutton.a index ee6935a6eaf..36f8b0fc24d 100644 Binary files a/tools/sdk/esp32/lib/libbutton.a and b/tools/sdk/esp32/lib/libbutton.a differ diff --git a/tools/sdk/esp32/lib/libcbor.a b/tools/sdk/esp32/lib/libcbor.a index 2a9cb841698..ea973b4b891 100644 Binary files a/tools/sdk/esp32/lib/libcbor.a and b/tools/sdk/esp32/lib/libcbor.a differ diff --git a/tools/sdk/esp32/lib/libcmock.a b/tools/sdk/esp32/lib/libcmock.a index 819c5a55744..7fa02d4c1e4 100644 Binary files a/tools/sdk/esp32/lib/libcmock.a and b/tools/sdk/esp32/lib/libcmock.a differ diff --git a/tools/sdk/esp32/lib/libcoap.a b/tools/sdk/esp32/lib/libcoap.a index 475f344c21a..cd1a9789936 100644 Binary files a/tools/sdk/esp32/lib/libcoap.a and b/tools/sdk/esp32/lib/libcoap.a differ diff --git a/tools/sdk/esp32/lib/libcoexist.a b/tools/sdk/esp32/lib/libcoexist.a index 6a07d9fab49..1c67ea32c12 100644 Binary files a/tools/sdk/esp32/lib/libcoexist.a and b/tools/sdk/esp32/lib/libcoexist.a differ diff --git a/tools/sdk/esp32/lib/libconsole.a b/tools/sdk/esp32/lib/libconsole.a index f711007592c..936a0e763f5 100644 Binary files a/tools/sdk/esp32/lib/libconsole.a and b/tools/sdk/esp32/lib/libconsole.a differ diff --git a/tools/sdk/esp32/lib/libcore.a b/tools/sdk/esp32/lib/libcore.a index 5dfca587210..842c189cef0 100644 Binary files a/tools/sdk/esp32/lib/libcore.a and b/tools/sdk/esp32/lib/libcore.a differ diff --git a/tools/sdk/esp32/lib/libcxx.a b/tools/sdk/esp32/lib/libcxx.a index ef0e12ce41d..345f416d4cb 100644 Binary files a/tools/sdk/esp32/lib/libcxx.a and b/tools/sdk/esp32/lib/libcxx.a differ diff --git a/tools/sdk/esp32/lib/libdriver.a b/tools/sdk/esp32/lib/libdriver.a index f238bbb787e..df0adc2a386 100644 Binary files a/tools/sdk/esp32/lib/libdriver.a and b/tools/sdk/esp32/lib/libdriver.a differ diff --git a/tools/sdk/esp32/lib/libefuse.a b/tools/sdk/esp32/lib/libefuse.a index 3f941fd6035..931f812b60a 100644 Binary files a/tools/sdk/esp32/lib/libefuse.a and b/tools/sdk/esp32/lib/libefuse.a differ diff --git a/tools/sdk/esp32/lib/libesp-dsp.a b/tools/sdk/esp32/lib/libesp-dsp.a index 49b548eaf7a..caaa82682af 100644 Binary files a/tools/sdk/esp32/lib/libesp-dsp.a and b/tools/sdk/esp32/lib/libesp-dsp.a differ diff --git a/tools/sdk/esp32/lib/libesp-face.a b/tools/sdk/esp32/lib/libesp-face.a new file mode 100644 index 00000000000..d0190b7e6c5 Binary files /dev/null and b/tools/sdk/esp32/lib/libesp-face.a differ diff --git a/tools/sdk/esp32/lib/libesp-tls.a b/tools/sdk/esp32/lib/libesp-tls.a index b68a26e8905..bc5e30b2714 100644 Binary files a/tools/sdk/esp32/lib/libesp-tls.a and b/tools/sdk/esp32/lib/libesp-tls.a differ diff --git a/tools/sdk/esp32/lib/libesp32-camera.a b/tools/sdk/esp32/lib/libesp32-camera.a index 0514d6ce494..12dbc000d3a 100644 Binary files a/tools/sdk/esp32/lib/libesp32-camera.a and b/tools/sdk/esp32/lib/libesp32-camera.a differ diff --git a/tools/sdk/esp32/lib/libesp_adc_cal.a b/tools/sdk/esp32/lib/libesp_adc_cal.a index 0440a8e137a..7b9d44f4792 100644 Binary files a/tools/sdk/esp32/lib/libesp_adc_cal.a and b/tools/sdk/esp32/lib/libesp_adc_cal.a differ diff --git a/tools/sdk/esp32/lib/libesp_common.a b/tools/sdk/esp32/lib/libesp_common.a index 55ad6397248..2e68a12c3fa 100644 Binary files a/tools/sdk/esp32/lib/libesp_common.a and b/tools/sdk/esp32/lib/libesp_common.a differ diff --git a/tools/sdk/esp32/lib/libesp_eth.a b/tools/sdk/esp32/lib/libesp_eth.a index b1929f1e507..4a0b9489866 100644 Binary files a/tools/sdk/esp32/lib/libesp_eth.a and b/tools/sdk/esp32/lib/libesp_eth.a differ diff --git a/tools/sdk/esp32/lib/libesp_event.a b/tools/sdk/esp32/lib/libesp_event.a index 553ea1c7aee..df2d913ffb6 100644 Binary files a/tools/sdk/esp32/lib/libesp_event.a and b/tools/sdk/esp32/lib/libesp_event.a differ diff --git a/tools/sdk/esp32/lib/libesp_gdbstub.a b/tools/sdk/esp32/lib/libesp_gdbstub.a index 4532df2f78a..f6792e3d87c 100644 Binary files a/tools/sdk/esp32/lib/libesp_gdbstub.a and b/tools/sdk/esp32/lib/libesp_gdbstub.a differ diff --git a/tools/sdk/esp32/lib/libesp_hid.a b/tools/sdk/esp32/lib/libesp_hid.a index 81355c91e67..d33f2d11757 100644 Binary files a/tools/sdk/esp32/lib/libesp_hid.a and b/tools/sdk/esp32/lib/libesp_hid.a differ diff --git a/tools/sdk/esp32/lib/libesp_http_client.a b/tools/sdk/esp32/lib/libesp_http_client.a index 9d084d94942..7c114a2f7f8 100644 Binary files a/tools/sdk/esp32/lib/libesp_http_client.a and b/tools/sdk/esp32/lib/libesp_http_client.a differ diff --git a/tools/sdk/esp32/lib/libesp_http_server.a b/tools/sdk/esp32/lib/libesp_http_server.a index f20074b7e94..0e387a90a67 100644 Binary files a/tools/sdk/esp32/lib/libesp_http_server.a and b/tools/sdk/esp32/lib/libesp_http_server.a differ diff --git a/tools/sdk/esp32/lib/libesp_https_ota.a b/tools/sdk/esp32/lib/libesp_https_ota.a index c8f743f733a..bd9d0a229b1 100644 Binary files a/tools/sdk/esp32/lib/libesp_https_ota.a and b/tools/sdk/esp32/lib/libesp_https_ota.a differ diff --git a/tools/sdk/esp32/lib/libesp_hw_support.a b/tools/sdk/esp32/lib/libesp_hw_support.a index 8b318d6bfdb..84d856bcd2f 100644 Binary files a/tools/sdk/esp32/lib/libesp_hw_support.a and b/tools/sdk/esp32/lib/libesp_hw_support.a differ diff --git a/tools/sdk/esp32/lib/libesp_ipc.a b/tools/sdk/esp32/lib/libesp_ipc.a index 8958f861427..8357f40cd95 100644 Binary files a/tools/sdk/esp32/lib/libesp_ipc.a and b/tools/sdk/esp32/lib/libesp_ipc.a differ diff --git a/tools/sdk/esp32/lib/libesp_lcd.a b/tools/sdk/esp32/lib/libesp_lcd.a index 1801d9b8755..cf49ac8df62 100644 Binary files a/tools/sdk/esp32/lib/libesp_lcd.a and b/tools/sdk/esp32/lib/libesp_lcd.a differ diff --git a/tools/sdk/esp32/lib/libesp_littlefs.a b/tools/sdk/esp32/lib/libesp_littlefs.a index 38290da68ae..f2a23718dba 100644 Binary files a/tools/sdk/esp32/lib/libesp_littlefs.a and b/tools/sdk/esp32/lib/libesp_littlefs.a differ diff --git a/tools/sdk/esp32/lib/libesp_local_ctrl.a b/tools/sdk/esp32/lib/libesp_local_ctrl.a index e1f10c0dffe..b68b6bd06a9 100644 Binary files a/tools/sdk/esp32/lib/libesp_local_ctrl.a and b/tools/sdk/esp32/lib/libesp_local_ctrl.a differ diff --git a/tools/sdk/esp32/lib/libesp_netif.a b/tools/sdk/esp32/lib/libesp_netif.a index d606140499b..6da6843899f 100644 Binary files a/tools/sdk/esp32/lib/libesp_netif.a and b/tools/sdk/esp32/lib/libesp_netif.a differ diff --git a/tools/sdk/esp32/lib/libesp_phy.a b/tools/sdk/esp32/lib/libesp_phy.a index 3abd25f53b2..8fbd2126f6c 100644 Binary files a/tools/sdk/esp32/lib/libesp_phy.a and b/tools/sdk/esp32/lib/libesp_phy.a differ diff --git a/tools/sdk/esp32/lib/libesp_pm.a b/tools/sdk/esp32/lib/libesp_pm.a index 39cb0ce9527..6d792a9299d 100644 Binary files a/tools/sdk/esp32/lib/libesp_pm.a and b/tools/sdk/esp32/lib/libesp_pm.a differ diff --git a/tools/sdk/esp32/lib/libesp_rainmaker.a b/tools/sdk/esp32/lib/libesp_rainmaker.a index eb552bda46d..9dac83225b3 100644 Binary files a/tools/sdk/esp32/lib/libesp_rainmaker.a and b/tools/sdk/esp32/lib/libesp_rainmaker.a differ diff --git a/tools/sdk/esp32/lib/libesp_ringbuf.a b/tools/sdk/esp32/lib/libesp_ringbuf.a index e3fe56d6590..5bb6cd6d73e 100644 Binary files a/tools/sdk/esp32/lib/libesp_ringbuf.a and b/tools/sdk/esp32/lib/libesp_ringbuf.a differ diff --git a/tools/sdk/esp32/lib/libesp_rom.a b/tools/sdk/esp32/lib/libesp_rom.a index a6d86d724ed..3f729e9da7e 100644 Binary files a/tools/sdk/esp32/lib/libesp_rom.a and b/tools/sdk/esp32/lib/libesp_rom.a differ diff --git a/tools/sdk/esp32/lib/libesp_schedule.a b/tools/sdk/esp32/lib/libesp_schedule.a index 13d28e57465..2ec22bd25e9 100644 Binary files a/tools/sdk/esp32/lib/libesp_schedule.a and b/tools/sdk/esp32/lib/libesp_schedule.a differ diff --git a/tools/sdk/esp32/lib/libesp_serial_slave_link.a b/tools/sdk/esp32/lib/libesp_serial_slave_link.a index 0f49c488742..fd167c70606 100644 Binary files a/tools/sdk/esp32/lib/libesp_serial_slave_link.a and b/tools/sdk/esp32/lib/libesp_serial_slave_link.a differ diff --git a/tools/sdk/esp32/lib/libesp_system.a b/tools/sdk/esp32/lib/libesp_system.a index f50673a65c4..790eee722fe 100644 Binary files a/tools/sdk/esp32/lib/libesp_system.a and b/tools/sdk/esp32/lib/libesp_system.a differ diff --git a/tools/sdk/esp32/lib/libesp_timer.a b/tools/sdk/esp32/lib/libesp_timer.a index 6dd4d143f6e..6b295a4294f 100644 Binary files a/tools/sdk/esp32/lib/libesp_timer.a and b/tools/sdk/esp32/lib/libesp_timer.a differ diff --git a/tools/sdk/esp32/lib/libesp_websocket_client.a b/tools/sdk/esp32/lib/libesp_websocket_client.a index 4ea65a16e18..1e8899cad16 100644 Binary files a/tools/sdk/esp32/lib/libesp_websocket_client.a and b/tools/sdk/esp32/lib/libesp_websocket_client.a differ diff --git a/tools/sdk/esp32/lib/libesp_wifi.a b/tools/sdk/esp32/lib/libesp_wifi.a index 6d7bcc29315..43ef5583818 100644 Binary files a/tools/sdk/esp32/lib/libesp_wifi.a and b/tools/sdk/esp32/lib/libesp_wifi.a differ diff --git a/tools/sdk/esp32/lib/libespcoredump.a b/tools/sdk/esp32/lib/libespcoredump.a index 25cd8820b99..887eb069f89 100644 Binary files a/tools/sdk/esp32/lib/libespcoredump.a and b/tools/sdk/esp32/lib/libespcoredump.a differ diff --git a/tools/sdk/esp32/lib/libespnow.a b/tools/sdk/esp32/lib/libespnow.a index 9b53365726b..24169f6f0c2 100644 Binary files a/tools/sdk/esp32/lib/libespnow.a and b/tools/sdk/esp32/lib/libespnow.a differ diff --git a/tools/sdk/esp32/lib/libexpat.a b/tools/sdk/esp32/lib/libexpat.a index 6935208e49f..dd46bdfd9d0 100644 Binary files a/tools/sdk/esp32/lib/libexpat.a and b/tools/sdk/esp32/lib/libexpat.a differ diff --git a/tools/sdk/esp32/lib/libfatfs.a b/tools/sdk/esp32/lib/libfatfs.a index 4ee8d7990ed..7f871b06496 100644 Binary files a/tools/sdk/esp32/lib/libfatfs.a and b/tools/sdk/esp32/lib/libfatfs.a differ diff --git a/tools/sdk/esp32/lib/libfb_gfx.a b/tools/sdk/esp32/lib/libfb_gfx.a index b46cbb1a54b..53d6d67395f 100644 Binary files a/tools/sdk/esp32/lib/libfb_gfx.a and b/tools/sdk/esp32/lib/libfb_gfx.a differ diff --git a/tools/sdk/esp32/lib/libfreemodbus.a b/tools/sdk/esp32/lib/libfreemodbus.a index 66297b41164..7758f283797 100644 Binary files a/tools/sdk/esp32/lib/libfreemodbus.a and b/tools/sdk/esp32/lib/libfreemodbus.a differ diff --git a/tools/sdk/esp32/lib/libfreertos.a b/tools/sdk/esp32/lib/libfreertos.a index 310a0260efa..b45be838095 100644 Binary files a/tools/sdk/esp32/lib/libfreertos.a and b/tools/sdk/esp32/lib/libfreertos.a differ diff --git a/tools/sdk/esp32/lib/libhal.a b/tools/sdk/esp32/lib/libhal.a index 1ec5baa88e8..7d6517f618d 100644 Binary files a/tools/sdk/esp32/lib/libhal.a and b/tools/sdk/esp32/lib/libhal.a differ diff --git a/tools/sdk/esp32/lib/libheap.a b/tools/sdk/esp32/lib/libheap.a index 9c1f8d53e6e..f8a251b3f0f 100644 Binary files a/tools/sdk/esp32/lib/libheap.a and b/tools/sdk/esp32/lib/libheap.a differ diff --git a/tools/sdk/esp32/lib/libjsmn.a b/tools/sdk/esp32/lib/libjsmn.a index db3e654323b..a77876f7c2c 100644 Binary files a/tools/sdk/esp32/lib/libjsmn.a and b/tools/sdk/esp32/lib/libjsmn.a differ diff --git a/tools/sdk/esp32/lib/libjson.a b/tools/sdk/esp32/lib/libjson.a index cf7d8626fc9..3fad9c3ffa1 100644 Binary files a/tools/sdk/esp32/lib/libjson.a and b/tools/sdk/esp32/lib/libjson.a differ diff --git a/tools/sdk/esp32/lib/libjson_generator.a b/tools/sdk/esp32/lib/libjson_generator.a index 98f9139a1c3..dd87f2cfc3a 100644 Binary files a/tools/sdk/esp32/lib/libjson_generator.a and b/tools/sdk/esp32/lib/libjson_generator.a differ diff --git a/tools/sdk/esp32/lib/libjson_parser.a b/tools/sdk/esp32/lib/libjson_parser.a index aa782991769..a571ee627b7 100644 Binary files a/tools/sdk/esp32/lib/libjson_parser.a and b/tools/sdk/esp32/lib/libjson_parser.a differ diff --git a/tools/sdk/esp32/lib/liblibsodium.a b/tools/sdk/esp32/lib/liblibsodium.a index 938b26806f4..1b2812707fd 100644 Binary files a/tools/sdk/esp32/lib/liblibsodium.a and b/tools/sdk/esp32/lib/liblibsodium.a differ diff --git a/tools/sdk/esp32/lib/liblog.a b/tools/sdk/esp32/lib/liblog.a index 32d9e92b187..c19dfe5e3e0 100644 Binary files a/tools/sdk/esp32/lib/liblog.a and b/tools/sdk/esp32/lib/liblog.a differ diff --git a/tools/sdk/esp32/lib/liblwip.a b/tools/sdk/esp32/lib/liblwip.a index ad6dcde9e98..f3d504d02bd 100644 Binary files a/tools/sdk/esp32/lib/liblwip.a and b/tools/sdk/esp32/lib/liblwip.a differ diff --git a/tools/sdk/esp32/lib/libmbedcrypto.a b/tools/sdk/esp32/lib/libmbedcrypto.a index b63bf72ce9b..ccb707553c6 100644 Binary files a/tools/sdk/esp32/lib/libmbedcrypto.a and b/tools/sdk/esp32/lib/libmbedcrypto.a differ diff --git a/tools/sdk/esp32/lib/libmbedtls.a b/tools/sdk/esp32/lib/libmbedtls.a index 116564a2f60..00f6a4e3c51 100644 Binary files a/tools/sdk/esp32/lib/libmbedtls.a and b/tools/sdk/esp32/lib/libmbedtls.a differ diff --git a/tools/sdk/esp32/lib/libmbedx509.a b/tools/sdk/esp32/lib/libmbedx509.a index 0c60ab90cab..70c435f00eb 100644 Binary files a/tools/sdk/esp32/lib/libmbedx509.a and b/tools/sdk/esp32/lib/libmbedx509.a differ diff --git a/tools/sdk/esp32/lib/libmdns.a b/tools/sdk/esp32/lib/libmdns.a index a07fbbd45ea..8aa902f9d6d 100644 Binary files a/tools/sdk/esp32/lib/libmdns.a and b/tools/sdk/esp32/lib/libmdns.a differ diff --git a/tools/sdk/esp32/lib/libmesh.a b/tools/sdk/esp32/lib/libmesh.a index 9a32bef01fd..4796b538801 100644 Binary files a/tools/sdk/esp32/lib/libmesh.a and b/tools/sdk/esp32/lib/libmesh.a differ diff --git a/tools/sdk/esp32/lib/libmqtt.a b/tools/sdk/esp32/lib/libmqtt.a index 127053e6c78..68426aeaa76 100644 Binary files a/tools/sdk/esp32/lib/libmqtt.a and b/tools/sdk/esp32/lib/libmqtt.a differ diff --git a/tools/sdk/esp32/lib/libnet80211.a b/tools/sdk/esp32/lib/libnet80211.a index 75b75922b13..dce7fceb9d6 100644 Binary files a/tools/sdk/esp32/lib/libnet80211.a and b/tools/sdk/esp32/lib/libnet80211.a differ diff --git a/tools/sdk/esp32/lib/libnewlib.a b/tools/sdk/esp32/lib/libnewlib.a index 0f96d134212..4e8d16a00be 100644 Binary files a/tools/sdk/esp32/lib/libnewlib.a and b/tools/sdk/esp32/lib/libnewlib.a differ diff --git a/tools/sdk/esp32/lib/libnghttp.a b/tools/sdk/esp32/lib/libnghttp.a index b8d76a83672..510cd4438a0 100644 Binary files a/tools/sdk/esp32/lib/libnghttp.a and b/tools/sdk/esp32/lib/libnghttp.a differ diff --git a/tools/sdk/esp32/lib/libnvs_flash.a b/tools/sdk/esp32/lib/libnvs_flash.a index 7ef82432abc..9973caf9613 100644 Binary files a/tools/sdk/esp32/lib/libnvs_flash.a and b/tools/sdk/esp32/lib/libnvs_flash.a differ diff --git a/tools/sdk/esp32/lib/libopenssl.a b/tools/sdk/esp32/lib/libopenssl.a index 1a87c1f7d05..053369f1e64 100644 Binary files a/tools/sdk/esp32/lib/libopenssl.a and b/tools/sdk/esp32/lib/libopenssl.a differ diff --git a/tools/sdk/esp32/lib/libperfmon.a b/tools/sdk/esp32/lib/libperfmon.a index 45281b34c8f..e45b4ba6955 100644 Binary files a/tools/sdk/esp32/lib/libperfmon.a and b/tools/sdk/esp32/lib/libperfmon.a differ diff --git a/tools/sdk/esp32/lib/libpp.a b/tools/sdk/esp32/lib/libpp.a index 3ec218aa6f1..73458bfedf6 100644 Binary files a/tools/sdk/esp32/lib/libpp.a and b/tools/sdk/esp32/lib/libpp.a differ diff --git a/tools/sdk/esp32/lib/libprotobuf-c.a b/tools/sdk/esp32/lib/libprotobuf-c.a index 174b3237ced..69016370716 100644 Binary files a/tools/sdk/esp32/lib/libprotobuf-c.a and b/tools/sdk/esp32/lib/libprotobuf-c.a differ diff --git a/tools/sdk/esp32/lib/libprotocomm.a b/tools/sdk/esp32/lib/libprotocomm.a index 701acf9e584..c5697a3d2f1 100644 Binary files a/tools/sdk/esp32/lib/libprotocomm.a and b/tools/sdk/esp32/lib/libprotocomm.a differ diff --git a/tools/sdk/esp32/lib/libpthread.a b/tools/sdk/esp32/lib/libpthread.a index 1329ba601b3..305dc194c56 100644 Binary files a/tools/sdk/esp32/lib/libpthread.a and b/tools/sdk/esp32/lib/libpthread.a differ diff --git a/tools/sdk/esp32/lib/libqrcode.a b/tools/sdk/esp32/lib/libqrcode.a index c834f6d204b..8c52777a6bc 100644 Binary files a/tools/sdk/esp32/lib/libqrcode.a and b/tools/sdk/esp32/lib/libqrcode.a differ diff --git a/tools/sdk/esp32/lib/libsdmmc.a b/tools/sdk/esp32/lib/libsdmmc.a index 30b5bbaa4e5..693ffaaa070 100644 Binary files a/tools/sdk/esp32/lib/libsdmmc.a and b/tools/sdk/esp32/lib/libsdmmc.a differ diff --git a/tools/sdk/esp32/lib/libsmartconfig.a b/tools/sdk/esp32/lib/libsmartconfig.a index 2ae36360fa1..e5fb258bcbe 100644 Binary files a/tools/sdk/esp32/lib/libsmartconfig.a and b/tools/sdk/esp32/lib/libsmartconfig.a differ diff --git a/tools/sdk/esp32/lib/libsoc.a b/tools/sdk/esp32/lib/libsoc.a index 5b5287c04be..b3354ff138a 100644 Binary files a/tools/sdk/esp32/lib/libsoc.a and b/tools/sdk/esp32/lib/libsoc.a differ diff --git a/tools/sdk/esp32/lib/libspi_flash.a b/tools/sdk/esp32/lib/libspi_flash.a index f9a11137071..00749b37663 100644 Binary files a/tools/sdk/esp32/lib/libspi_flash.a and b/tools/sdk/esp32/lib/libspi_flash.a differ diff --git a/tools/sdk/esp32/lib/libspiffs.a b/tools/sdk/esp32/lib/libspiffs.a index 56eea5993cf..5fc86efd03e 100644 Binary files a/tools/sdk/esp32/lib/libspiffs.a and b/tools/sdk/esp32/lib/libspiffs.a differ diff --git a/tools/sdk/esp32/lib/libtcp_transport.a b/tools/sdk/esp32/lib/libtcp_transport.a index 83f2ad57d38..df92a6501c9 100644 Binary files a/tools/sdk/esp32/lib/libtcp_transport.a and b/tools/sdk/esp32/lib/libtcp_transport.a differ diff --git a/tools/sdk/esp32/lib/libtcpip_adapter.a b/tools/sdk/esp32/lib/libtcpip_adapter.a index 20f3e0cb843..d263833db57 100644 Binary files a/tools/sdk/esp32/lib/libtcpip_adapter.a and b/tools/sdk/esp32/lib/libtcpip_adapter.a differ diff --git a/tools/sdk/esp32/lib/libulp.a b/tools/sdk/esp32/lib/libulp.a index c3e3bdf0419..4a536b87cdc 100644 Binary files a/tools/sdk/esp32/lib/libulp.a and b/tools/sdk/esp32/lib/libulp.a differ diff --git a/tools/sdk/esp32/lib/libunity.a b/tools/sdk/esp32/lib/libunity.a index e977f3a578b..4f84d0551b5 100644 Binary files a/tools/sdk/esp32/lib/libunity.a and b/tools/sdk/esp32/lib/libunity.a differ diff --git a/tools/sdk/esp32/lib/libvfs.a b/tools/sdk/esp32/lib/libvfs.a index 51230fadaf3..f2a4b7b7074 100644 Binary files a/tools/sdk/esp32/lib/libvfs.a and b/tools/sdk/esp32/lib/libvfs.a differ diff --git a/tools/sdk/esp32/lib/libwapi.a b/tools/sdk/esp32/lib/libwapi.a index 4d0200ad4b0..53e0fe9d410 100644 Binary files a/tools/sdk/esp32/lib/libwapi.a and b/tools/sdk/esp32/lib/libwapi.a differ diff --git a/tools/sdk/esp32/lib/libwear_levelling.a b/tools/sdk/esp32/lib/libwear_levelling.a index e6793f3b3c9..0cd3b5ff669 100644 Binary files a/tools/sdk/esp32/lib/libwear_levelling.a and b/tools/sdk/esp32/lib/libwear_levelling.a differ diff --git a/tools/sdk/esp32/lib/libwifi_provisioning.a b/tools/sdk/esp32/lib/libwifi_provisioning.a index b0764129217..cbbbe74a72d 100644 Binary files a/tools/sdk/esp32/lib/libwifi_provisioning.a and b/tools/sdk/esp32/lib/libwifi_provisioning.a differ diff --git a/tools/sdk/esp32/lib/libwpa_supplicant.a b/tools/sdk/esp32/lib/libwpa_supplicant.a index 011380db2c8..2a42ebd4fa6 100644 Binary files a/tools/sdk/esp32/lib/libwpa_supplicant.a and b/tools/sdk/esp32/lib/libwpa_supplicant.a differ diff --git a/tools/sdk/esp32/lib/libws2812_led.a b/tools/sdk/esp32/lib/libws2812_led.a index 17c368b009a..79f78433fb4 100644 Binary files a/tools/sdk/esp32/lib/libws2812_led.a and b/tools/sdk/esp32/lib/libws2812_led.a differ diff --git a/tools/sdk/esp32/lib/libxtensa.a b/tools/sdk/esp32/lib/libxtensa.a index 37ff7464dc0..1548b8ccda0 100644 Binary files a/tools/sdk/esp32/lib/libxtensa.a and b/tools/sdk/esp32/lib/libxtensa.a differ diff --git a/tools/sdk/esp32/sdkconfig b/tools/sdk/esp32/sdkconfig index 79ed5b40ca2..f6b53e2d216 100644 --- a/tools/sdk/esp32/sdkconfig +++ b/tools/sdk/esp32/sdkconfig @@ -63,7 +63,6 @@ CONFIG_BOOTLOADER_WDT_TIME_MS=9000 # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Bootloader config # @@ -84,7 +83,6 @@ CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set @@ -265,9 +263,10 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # CONFIG_BT_ENABLED=y +CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller +# Bluetooth controller(ESP32 Dual Mode Bluetooth) # # CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set # CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY is not set @@ -319,9 +318,37 @@ CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 -CONFIG_BTDM_RESERVE_DRAM=0xdb5c -CONFIG_BTDM_CTRL_HLI=y -# end of Bluetooth controller +# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) + +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 + +# +# MODEM SLEEP Options +# +# end of MODEM SLEEP Options + +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 + +# +# MODEM SLEEP Options +# +# end of MODEM SLEEP Options CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -344,7 +371,7 @@ CONFIG_BT_HFP_CLIENT_ENABLE=y # CONFIG_BT_HFP_AG_ENABLE is not set CONFIG_BT_HFP_AUDIO_DATA_PATH_PCM=y # CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI is not set -# CONFIG_BT_HID_ENABLED is not set +# CONFIG_BT_HID_HOST_ENABLED is not set CONFIG_BT_SSP_ENABLED=y CONFIG_BT_BLE_ENABLED=y CONFIG_BT_GATTS_ENABLE=y @@ -369,7 +396,10 @@ CONFIG_BT_SMP_ENABLE=y # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 # CONFIG_BT_BLE_RPA_SUPPORTED is not set +CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options + +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y # end of Bluetooth # CONFIG_BLE_MESH is not set @@ -394,12 +424,6 @@ CONFIG_COAP_LOG_DEFAULT_LEVEL=0 CONFIG_ADC_DISABLE_DAC=y # end of ADC configuration -# -# MCPWM configuration -# -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# end of MCPWM configuration - # # SPI configuration # @@ -455,7 +479,6 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 CONFIG_ESP_TLS_USING_MBEDTLS=y # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set # CONFIG_ESP_TLS_SERVER is not set -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS @@ -494,7 +517,6 @@ CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 # CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set -# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set CONFIG_SPIRAM_CACHE_WORKAROUND=y # @@ -683,29 +705,12 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 # # Sleep Config # -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND is not set -# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set # end of Sleep Config # end of Hardware Settings -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - # # LCD and Touch Panel # - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# end of LCD Peripheral Configuration # end of LCD and Touch Panel # @@ -770,8 +775,9 @@ CONFIG_ESP_TASK_WDT_PANIC=y CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y # end of ESP System Settings # @@ -893,8 +899,6 @@ CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 CONFIG_FMB_TIMER_PORT_ENABLED=y CONFIG_FMB_TIMER_GROUP=0 CONFIG_FMB_TIMER_INDEX=0 -CONFIG_FMB_MASTER_TIMER_GROUP=0 -CONFIG_FMB_MASTER_TIMER_INDEX=0 # CONFIG_FMB_TIMER_ISR_IN_IRAM is not set # end of Modbus configuration @@ -903,10 +907,8 @@ CONFIG_FMB_MASTER_TIMER_INDEX=0 # # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -935,8 +937,6 @@ CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set CONFIG_FREERTOS_DEBUG_OCDAWARE=y # CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set # end of FreeRTOS # @@ -1001,7 +1001,6 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_LOCAL_HOSTNAME="espressif" # CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # CONFIG_LWIP_L2_TO_L3_COPY is not set # CONFIG_LWIP_IRAM_OPTIMIZATION is not set @@ -1040,6 +1039,7 @@ CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=0 # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1117,8 +1117,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # # SNTP # -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 # end of SNTP @@ -1208,7 +1207,6 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set CONFIG_MBEDTLS_SSL_PROTO_DTLS=y CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1281,7 +1279,6 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 # CONFIG_MDNS_STRICT_MODE is not set CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set # end of mDNS # @@ -1424,6 +1421,11 @@ CONFIG_WS_BUFFER_SIZE=1024 # end of Websocket # end of TCP Transport +# +# TinyUSB +# +# end of TinyUSB + # # Unity unit testing library # @@ -1502,6 +1504,37 @@ CONFIG_DSP_MAX_FFT_SIZE_4096=y CONFIG_DSP_MAX_FFT_SIZE=4096 # end of DSP Library +# CONFIG_C_IMPL is not set +CONFIG_XTENSA_IMPL=y + +# +# ESP-FACE Configuration +# +CONFIG_MTMN_LITE_QUANT=y +# CONFIG_MTMN_LITE_FLOAT is not set +# CONFIG_MTMN_HEAVY_QUANT is not set +# CONFIG_FRMN is not set +CONFIG_MFN56_1X=y +# CONFIG_MFN56_2X is not set +# CONFIG_MFN56_3X is not set +# CONFIG_MFN56_4X is not set + +# +# Object Detection +# +# CONFIG_DETECT_WITH_LANDMARK is not set +# end of Object Detection + +# +# Pose Estimation +# +CONFIG_HD_NANO1=y +# CONFIG_HD_LITE1 is not set +CONFIG_HP_NANO1=y +# CONFIG_HP_LITE1 is not set +# end of Pose Estimation +# end of ESP-FACE Configuration + # # Camera configuration # @@ -1671,7 +1704,6 @@ CONFIG_POST_EVENTS_FROM_IRAM_ISR=y # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_REDUCE_PHY_TX_POWER=y # CONFIG_ESP32S2_PANIC_PRINT_HALT is not set CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y @@ -1694,6 +1726,7 @@ CONFIG_TASK_WDT_PANIC=y CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y # CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=4096 CONFIG_SW_COEXIST_ENABLE=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set diff --git a/tools/sdk/esp32c3/bin/bootloader_dio_40m.bin b/tools/sdk/esp32c3/bin/bootloader_dio_40m.bin index 78c947604fd..1904dd294f3 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_dio_40m.bin and b/tools/sdk/esp32c3/bin/bootloader_dio_40m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_dio_80m.bin b/tools/sdk/esp32c3/bin/bootloader_dio_80m.bin index 5fdaf4eed6a..0a65f3ab39c 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_dio_80m.bin and b/tools/sdk/esp32c3/bin/bootloader_dio_80m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_dout_40m.bin b/tools/sdk/esp32c3/bin/bootloader_dout_40m.bin index e369d99e862..21516fc37ee 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_dout_40m.bin and b/tools/sdk/esp32c3/bin/bootloader_dout_40m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_dout_80m.bin b/tools/sdk/esp32c3/bin/bootloader_dout_80m.bin index 2b9800fc7e7..f346f448585 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_dout_80m.bin and b/tools/sdk/esp32c3/bin/bootloader_dout_80m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_qio_40m.bin b/tools/sdk/esp32c3/bin/bootloader_qio_40m.bin index 22880d8cf71..2442a0eb902 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_qio_40m.bin and b/tools/sdk/esp32c3/bin/bootloader_qio_40m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_qio_80m.bin b/tools/sdk/esp32c3/bin/bootloader_qio_80m.bin index d630c8774ee..0df210df12f 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_qio_80m.bin and b/tools/sdk/esp32c3/bin/bootloader_qio_80m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_qout_40m.bin b/tools/sdk/esp32c3/bin/bootloader_qout_40m.bin index 9566026d6b4..18ad9777368 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_qout_40m.bin and b/tools/sdk/esp32c3/bin/bootloader_qout_40m.bin differ diff --git a/tools/sdk/esp32c3/bin/bootloader_qout_80m.bin b/tools/sdk/esp32c3/bin/bootloader_qout_80m.bin index d8a35e03d63..d05ca290ec8 100644 Binary files a/tools/sdk/esp32c3/bin/bootloader_qout_80m.bin and b/tools/sdk/esp32c3/bin/bootloader_qout_80m.bin differ diff --git a/tools/sdk/esp32c3/include/asio/port/include/esp_asio_config.h b/tools/sdk/esp32c3/include/asio/port/include/esp_asio_config.h index cba316527e6..3f3a9b03ed4 100644 --- a/tools/sdk/esp32c3/include/asio/port/include/esp_asio_config.h +++ b/tools/sdk/esp32c3/include/asio/port/include/esp_asio_config.h @@ -18,6 +18,11 @@ # define ASIO_NO_TYPEID # endif // CONFIG_COMPILER_RTTI +// +// Supress OpenSSL deprecation warning, when building ASIO +// +#define ESP_OPENSSL_SUPPRESS_LEGACY_WARNING + // // LWIP compatibility inet and address macros/functions // diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/address.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/address.h new file mode 100644 index 00000000000..a51236d5a60 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/address.h @@ -0,0 +1,177 @@ +/* + * address.h -- representation of network addresses + * + * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file address.h + * @brief Representation of network addresses + */ + +#ifndef COAP_ADDRESS_H_ +#define COAP_ADDRESS_H_ + +#include +#include +#include +#include +#include "libcoap.h" + +#if defined(WITH_LWIP) + +#include + +typedef struct coap_address_t { + uint16_t port; + ip_addr_t addr; +} coap_address_t; + +#define _coap_address_equals_impl(A, B) \ + ((A)->port == (B)->port \ + && (!!ip_addr_cmp(&(A)->addr,&(B)->addr))) + +#define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) + +#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr) + +#elif defined(WITH_CONTIKI) + +#include "uip.h" + +typedef struct coap_address_t { + uip_ipaddr_t addr; + uint16_t port; +} coap_address_t; + +#define _coap_address_equals_impl(A,B) \ + ((A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) + +/** @todo implementation of _coap_address_isany_impl() for Contiki */ +#define _coap_address_isany_impl(A) 0 + +#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) + +#else /* WITH_LWIP || WITH_CONTIKI */ + + /** multi-purpose address abstraction */ +typedef struct coap_address_t { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +} coap_address_t; + +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +int coap_address_equals(const coap_address_t *a, const coap_address_t *b); + +COAP_STATIC_INLINE int +_coap_address_isany_impl(const coap_address_t *a) { + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return a->addr.sin.sin_addr.s_addr == INADDR_ANY; + case AF_INET6: + return memcmp(&in6addr_any, + &a->addr.sin6.sin6_addr, + sizeof(in6addr_any)) == 0; + default: + ; + } + + return 0; +} +#endif /* WITH_LWIP || WITH_CONTIKI */ + +/** + * Resets the given coap_address_t object @p addr to its default values. In + * particular, the member size must be initialized to the available size for + * storing addresses. + * + * @param addr The coap_address_t object to initialize. + */ +COAP_STATIC_INLINE void +coap_address_init(coap_address_t *addr) { + assert(addr); + memset(addr, 0, sizeof(coap_address_t)); +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + /* lwip and Contiki have constant address sizes and doesn't need the .size part */ + addr->size = sizeof(addr->addr); +#endif +} + +/* Convenience function to copy IPv6 addresses without garbage. */ + +COAP_STATIC_INLINE void +coap_address_copy( coap_address_t *dst, const coap_address_t *src ) { +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) + memcpy( dst, src, sizeof( coap_address_t ) ); +#else + memset( dst, 0, sizeof( coap_address_t ) ); + dst->size = src->size; + if ( src->addr.sa.sa_family == AF_INET6 ) { + dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family; + dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr; + dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port; + dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id; + } else if ( src->addr.sa.sa_family == AF_INET ) { + dst->addr.sin = src->addr.sin; + } else { + memcpy( &dst->addr, &src->addr, src->size ); + } +#endif +} + +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_equals(const coap_address_t *a, const coap_address_t *b) { + assert(a); assert(b); + return _coap_address_equals_impl(a, b); +} +#endif + +/** + * Checks if given address object @p a denotes the wildcard address. This + * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p + * a must not be @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_isany(const coap_address_t *a) { + assert(a); + return _coap_address_isany_impl(a); +} + +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +int coap_is_mcast(const coap_address_t *a); +#else /* !WITH_LWIP && !WITH_CONTIKI */ +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +coap_is_mcast(const coap_address_t *a) { + return a && _coap_is_mcast_impl(a); +} +#endif /* !WITH_LWIP && !WITH_CONTIKI */ + +#endif /* COAP_ADDRESS_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/async.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/async.h new file mode 100644 index 00000000000..e399929677d --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/async.h @@ -0,0 +1,148 @@ +/* + * async.h -- state management for asynchronous messages + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file async.h + * @brief State management for asynchronous messages + */ + +#ifndef COAP_ASYNC_H_ +#define COAP_ASYNC_H_ + +#include "net.h" + +#ifndef WITHOUT_ASYNC + +/** + * @defgroup coap_async Asynchronous Messaging + * @{ + * Structure for managing asynchronous state of CoAP resources. A + * coap_resource_t object holds a list of coap_async_state_t objects that can be + * used to generate a separate response in case a result of an operation cannot + * be delivered in time, or the resource has been explicitly subscribed to with + * the option @c observe. + */ +typedef struct coap_async_state_t { + unsigned char flags; /**< holds the flags to control behaviour */ + + /** + * Holds the internal time when the object was registered with a + * resource. This field will be updated whenever + * coap_register_async() is called for a specific resource. + */ + coap_tick_t created; + + /** + * This field can be used to register opaque application data with the + * asynchronous state object. + */ + void *appdata; + coap_session_t *session; /**< transaction session */ + coap_tid_t id; /**< transaction id */ + struct coap_async_state_t *next; /**< internally used for linking */ + size_t tokenlen; /**< length of the token */ + uint8_t token[8]; /**< the token to use in a response */ +} coap_async_state_t; + +/* Definitions for Async Status Flags These flags can be used to control the + * behaviour of asynchronous response generation. + */ +#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */ +#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */ +#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */ + +/** release application data on destruction */ +#define COAP_ASYNC_RELEASE_DATA 0x08 + +/** + * Allocates a new coap_async_state_t object and fills its fields according to + * the given @p request. The @p flags are used to control generation of empty + * ACK responses to stop retransmissions and to release registered @p data when + * the resource is deleted by coap_free_async(). This function returns a pointer + * to the registered coap_async_t object or @c NULL on error. Note that this + * function will return @c NULL in case that an object with the same identifier + * is already registered. + * + * @param context The context to use. + * @param session The session that is used for asynchronous transmissions. + * @param request The request that is handled asynchronously. + * @param flags Flags to control state management. + * @param data Opaque application data to register. Note that the + * storage occupied by @p data is released on destruction + * only if flag COAP_ASYNC_RELEASE_DATA is set. + * + * @return A pointer to the registered coap_async_state_t object or @c + * NULL in case of an error. + */ +coap_async_state_t * +coap_register_async(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request, + unsigned char flags, + void *data); + +/** + * Removes the state object identified by @p id from @p context. The removed + * object is returned in @p s, if found. Otherwise, @p s is undefined. This + * function returns @c 1 if the object was removed, @c 0 otherwise. Note that + * the storage allocated for the stored object is not released by this + * functions. You will have to call coap_free_async() to do so. + * + * @param context The context where the async object is registered. + * @param session The session that is used for asynchronous transmissions. + * @param id The identifier of the asynchronous transaction. + * @param s Will be set to the object identified by @p id after removal. + * + * @return @c 1 if object was removed and @p s updated, or @c 0 if no + * object was found with the given id. @p s is valid only if the + * return value is @c 1. + */ +int coap_remove_async(coap_context_t *context, + coap_session_t *session, + coap_tid_t id, + coap_async_state_t **s); + +/** + * Releases the memory that was allocated by coap_async_state_init() for the + * object @p s. The registered application data will be released automatically + * if COAP_ASYNC_RELEASE_DATA is set. + * + * @param state The object to delete. + */ +void +coap_free_async(coap_async_state_t *state); + +/** + * Retrieves the object identified by @p id from the list of asynchronous + * transactions that are registered with @p context. This function returns a + * pointer to that object or @c NULL if not found. + * + * @param context The context where the asynchronous objects are registered + * with. + * @param session The session that is used for asynchronous transmissions. + * @param id The id of the object to retrieve. + * + * @return A pointer to the object identified by @p id or @c NULL if + * not found. + */ +coap_async_state_t *coap_find_async(coap_context_t *context, coap_session_t *session, coap_tid_t id); + +/** + * Updates the time stamp of @p s. + * + * @param s The state object to update. + */ +COAP_STATIC_INLINE void +coap_touch_async(coap_async_state_t *s) { coap_ticks(&s->created); } + +/** @} */ + +#endif /* WITHOUT_ASYNC */ + +#endif /* COAP_ASYNC_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/bits.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/bits.h new file mode 100644 index 00000000000..3b1871487c9 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/bits.h @@ -0,0 +1,78 @@ +/* + * bits.h -- bit vector manipulation + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file bits.h + * @brief Bit vector manipulation + */ + +#ifndef COAP_BITS_H_ +#define COAP_BITS_H_ + +#include + +/** + * Sets the bit @p bit in bit-vector @p vec. This function returns @c 1 if bit + * was set or @c -1 on error (i.e. when the given bit does not fit in the + * vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to set in @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_setb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07)); + return 1; +} + +/** + * Clears the bit @p bit from bit-vector @p vec. This function returns @c 1 if + * bit was cleared or @c -1 on error (i.e. when the given bit does not fit in + * the vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to clear from @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_clrb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07))); + return 1; +} + +/** + * Gets the status of bit @p bit from bit-vector @p vec. This function returns + * @c 1 if the bit is set, @c 0 otherwise (even in case of an error). + * + * @param vec The bit-vector to read from. + * @param size The size of @p vec in bytes. + * @param bit The bit to get from @p vec. + * + * @return @c 1 if the bit is set, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +bits_getb(const uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0; +} + +#endif /* COAP_BITS_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/block.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/block.h new file mode 100644 index 00000000000..848897639c9 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/block.h @@ -0,0 +1,173 @@ +/* + * block.h -- block transfer + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_BLOCK_H_ +#define COAP_BLOCK_H_ + +#include "encode.h" +#include "option.h" +#include "pdu.h" + +struct coap_resource_t; +struct coap_session_t; + +/** + * @defgroup block Block Transfer + * API functions for handling PDUs using CoAP BLOCK options + * @{ + */ + +#ifndef COAP_MAX_BLOCK_SZX +/** + * The largest value for the SZX component in a Block option. + */ +#define COAP_MAX_BLOCK_SZX 6 +#endif /* COAP_MAX_BLOCK_SZX */ + +/** + * Structure of Block options. + */ +typedef struct { + unsigned int num; /**< block number */ + unsigned int m:1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx:3; /**< block size */ +} coap_block_t; + +/** + * Returns the value of the least significant byte of a Block option @p opt. + * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST + * returns @c NULL. + */ +#define COAP_OPT_BLOCK_LAST(opt) \ + (coap_opt_length(opt) ? (coap_opt_value(opt) + (coap_opt_length(opt)-1)) : 0) + +/** Returns the value of the More-bit of a Block option @p opt. */ +#define COAP_OPT_BLOCK_MORE(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0) + +/** Returns the value of the SZX-field of a Block option @p opt. */ +#define COAP_OPT_BLOCK_SZX(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0) + +/** + * Returns the value of field @c num in the given block option @p block_opt. + */ +unsigned int coap_opt_block_num(const coap_opt_t *block_opt); + +/** + * Checks if more than @p num blocks are required to deliver @p data_len + * bytes of data for a block size of 1 << (@p szx + 4). + */ +COAP_STATIC_INLINE int +coap_more_blocks(size_t data_len, unsigned int num, uint16_t szx) { + return ((num+1) << (szx + 4)) < data_len; +} + +#if 0 +/** Sets the More-bit in @p block_opt */ +COAP_STATIC_INLINE void +coap_opt_block_set_m(coap_opt_t *block_opt, int m) { + if (m) + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) |= 0x08; + else + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) &= ~0x08; +} +#endif + +/** + * Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1 + * or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block is + * initialized with values from this option and the function returns the value + * @c 1. Otherwise, @c 0 is returned. + * + * @param pdu The pdu to search for option @p type. + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * COAP_OPTION_BLOCK2). + * @param block The block structure to initilize. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_get_block(coap_pdu_t *pdu, uint16_t type, coap_block_t *block); + +/** + * Writes a block option of type @p type to message @p pdu. If the requested + * block size is too large to fit in @p pdu, it is reduced accordingly. An + * exception is made for the final block when less space is required. The actual + * length of the resource is specified in @p data_length. + * + * This function may change *block to reflect the values written to @p pdu. As + * the function takes into consideration the remaining space @p pdu, no more + * options should be added after coap_write_block_opt() has returned. + * + * @param block The block structure to use. On return, this object is + * updated according to the values that have been written to + * @p pdu. + * @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2. + * @param pdu The message where the block option should be written. + * @param data_length The length of the actual data that will be added the @p + * pdu by calling coap_add_block(). + * + * @return @c 1 on success, or a negative value on error. + */ +int coap_write_block_opt(coap_block_t *block, + uint16_t type, + coap_pdu_t *pdu, + size_t data_length); + +/** + * Adds the @p block_num block of size 1 << (@p block_szx + 4) from source @p + * data to @p pdu. + * + * @param pdu The message to add the block. + * @param len The length of @p data. + * @param data The source data to fill the block with. + * @param block_num The actual block number. + * @param block_szx Encoded size of block @p block_number. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_add_block(coap_pdu_t *pdu, + unsigned int len, + const uint8_t *data, + unsigned int block_num, + unsigned char block_szx); + +/** + * Adds the appropriate part of @p data to the @p response pdu. If blocks are + * required, then the appropriate block will be added to the PDU and sent. + * Adds a ETAG option that is the hash of the entire data if the data is to be + * split into blocks + * Used by a GET request handler. + * + * @param resource The resource the data is associated with. + * @param session The coap session. + * @param request The requesting pdu. + * @param response The response pdu. + * @param token The token taken from the (original) requesting pdu. + * @param media_type The format of the data. + * @param maxage The maxmimum life of the data. If @c -1, then there + * is no maxage. + * @param length The total length of the data. + * @param data The entire data block to transmit. + * + */ +void +coap_add_data_blocked_response(struct coap_resource_t *resource, + struct coap_session_t *session, + coap_pdu_t *request, + coap_pdu_t *response, + const coap_binary_t *token, + uint16_t media_type, + int maxage, + size_t length, + const uint8_t* data); + +/**@}*/ + +#endif /* COAP_BLOCK_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_debug.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_debug.h new file mode 100644 index 00000000000..e4631b71f2b --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_debug.h @@ -0,0 +1,209 @@ +/* + * coap_debug.h -- debug utilities + * + * Copyright (C) 2010-2011,2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DEBUG_H_ +#define COAP_DEBUG_H_ + +/** + * @defgroup logging Logging Support + * API functions for logging support + * @{ + */ + +#ifndef COAP_DEBUG_FD +/** + * Used for output for @c LOG_DEBUG to @c LOG_ERR. + */ +#define COAP_DEBUG_FD stdout +#endif + +#ifndef COAP_ERR_FD +/** + * Used for output for @c LOG_CRIT to @c LOG_EMERG. + */ +#define COAP_ERR_FD stderr +#endif + +#ifdef HAVE_SYSLOG_H +#include +/** + * Logging type. One of LOG_* from @b syslog. + */ +typedef short coap_log_t; +#else +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { + LOG_EMERG=0, /**< Emergency */ + LOG_ALERT, /**< Alert */ + LOG_CRIT, /**< Critical */ + LOG_ERR, /**< Error */ + LOG_WARNING, /**< Warning */ + LOG_NOTICE, /**< Notice */ + LOG_INFO, /**< Information */ + LOG_DEBUG /**< Debug */ +} coap_log_t; +#endif + +/** + * Get the current logging level. + * + * @return One of the LOG_* values. + */ +coap_log_t coap_get_log_level(void); + +/** + * Sets the log level to the specified value. + * + * @param level One of the LOG_* values. + */ +void coap_set_log_level(coap_log_t level); + +/** + * Logging call-back handler definition. + * + * @param level One of the LOG_* values. + * @param message Zero-terminated string message to log. + */ +typedef void (*coap_log_handler_t) (coap_log_t level, const char *message); + +/** + * Add a custom log callback handler. + * + * @param handler The logging handler to use or @p NULL to use default handler. + */ +void coap_set_log_handler(coap_log_handler_t handler); + +/** + * Get the library package name. + * + * @return Zero-terminated string with the name of this library. + */ +const char *coap_package_name(void); + +/** + * Get the library package version. + * + * @return Zero-terminated string with the library version. + */ +const char *coap_package_version(void); + +/** + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * Internal function. + * + * @param level One of the LOG_* values. + & @param format The format string to use. + */ +#if (defined(__GNUC__)) +void coap_log_impl(coap_log_t level, + const char *format, ...) __attribute__ ((format(printf, 2, 3))); +#else +void coap_log_impl(coap_log_t level, const char *format, ...); +#endif + +#ifndef coap_log +/** + * Logging function. + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * @param level One of the LOG_* values. + */ +#define coap_log(level, ...) do { \ + if ((int)((level))<=(int)coap_get_log_level()) \ + coap_log_impl((level), __VA_ARGS__); \ +} while(0) +#endif + +#include "pdu.h" + +/** + * Defines the output mode for the coap_show_pdu() function. + * + * @param use_fprintf @p 1 if the output is to use fprintf() (the default) + * @p 0 if the output is to use coap_log(). + */ +void coap_set_show_pdu_output(int use_fprintf); + +/** + * Display the contents of the specified @p pdu. + * Note: The output method of coap_show_pdu() is dependent on the setting of + * coap_set_show_pdu_output(). + * + * @param level The required minimum logging level. + * @param pdu The PDU to decode. + */ +void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu); + +/** + * Display the current (D)TLS library linked with and built for version. + * + * @param level The required minimum logging level. + */ +void coap_show_tls_version(coap_log_t level); + +/** + * Build a string containing the current (D)TLS library linked with and + * built for version. + * + * @param buffer The buffer to put the string into. + * @param bufsize The size of the buffer to put the string into. + * + * @return A pointer to the provided buffer. + */ +char *coap_string_tls_version(char *buffer, size_t bufsize); + +struct coap_address_t; + +/** + * Print the address into the defined buffer. + * + * Internal Function. + * + * @param address The address to print. + * @param buffer The buffer to print into. + * @param size The size of the buffer to print into. + * + * @return The amount written into the buffer. + */ +size_t coap_print_addr(const struct coap_address_t *address, + unsigned char *buffer, size_t size); + +/** @} */ + +/** + * Set the packet loss level for testing. This can be in one of two forms. + * + * Percentage : 0% to 100%. Use the specified probability. + * 0% is send all packets, 100% is drop all packets. + * + * List: A comma separated list of numbers or number ranges that are the + * packets to drop. + * + * @param loss_level The defined loss level (percentage or list). + * + * @return @c 1 If loss level set, @c 0 if there is an error. + */ +int coap_debug_set_packet_loss(const char *loss_level); + +/** + * Check to see whether a packet should be sent or not. + * + * Internal function + * + * @return @c 1 if packet is to be sent, @c 0 if packet is to be dropped. + */ +int coap_debug_send_packet(void); + + +#endif /* COAP_DEBUG_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_dtls.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_dtls.h new file mode 100644 index 00000000000..f0554f3dfea --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_dtls.h @@ -0,0 +1,611 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +#define COAP_TLS_LIBRARY_NOTLS 0 /**< No DTLS library */ +#define COAP_TLS_LIBRARY_TINYDTLS 1 /**< Using TinyDTLS library */ +#define COAP_TLS_LIBRARY_OPENSSL 2 /**< Using OpenSSL library */ +#define COAP_TLS_LIBRARY_GNUTLS 3 /**< Using GnuTLS library */ + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + int type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t reserved[6]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 6 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_event.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_event.h new file mode 100644 index 00000000000..81a3b0511fd --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_event.h @@ -0,0 +1,102 @@ +/* + * coap_event.h -- libcoap Event API + * + * Copyright (C) 2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_EVENT_H_ +#define COAP_EVENT_H_ + +#include "libcoap.h" + +struct coap_context_t; +struct coap_session_t; + +/** + * @defgroup events Event API + * API functions for event delivery from lower-layer library functions. + * @{ + */ + +/** + * Scalar type to represent different events, e.g. DTLS events or + * retransmission timeouts. + */ + typedef unsigned int coap_event_t; + +/** + * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS + */ +#define COAP_EVENT_DTLS_CLOSED 0x0000 +#define COAP_EVENT_DTLS_CONNECTED 0x01DE +#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF +#define COAP_EVENT_DTLS_ERROR 0x0200 + +/** + * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS + */ +#define COAP_EVENT_TCP_CONNECTED 0x1001 +#define COAP_EVENT_TCP_CLOSED 0x1002 +#define COAP_EVENT_TCP_FAILED 0x1003 + +/** + * CSM exchange events for reliable protocols only + */ +#define COAP_EVENT_SESSION_CONNECTED 0x2001 +#define COAP_EVENT_SESSION_CLOSED 0x2002 +#define COAP_EVENT_SESSION_FAILED 0x2003 + +/** + * Type for event handler functions that can be registered with a CoAP + * context using the unction coap_set_event_handler(). When called by + * the library, the first argument will be the coap_context_t object + * where the handler function has been registered. The second argument + * is the event type that may be complemented by event-specific data + * passed as the third argument. + */ +typedef int (*coap_event_handler_t)(struct coap_context_t *, + coap_event_t event, + struct coap_session_t *session); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. @c NULL if to be + * de-registered. + */ +void coap_register_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @deprecated Use coap_register_event_handler() instead. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. + */ +COAP_DEPRECATED +void coap_set_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Clears the event handler registered with @p context. + * + * @deprecated Use coap_register_event_handler() instead with NULL for hnd. + * + * @param context The CoAP context whose event handler is to be removed. + */ +COAP_DEPRECATED +void coap_clear_event_handler(struct coap_context_t *context); + +/** @} */ + +#endif /* COAP_EVENT_H */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_hashkey.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_hashkey.h new file mode 100644 index 00000000000..252f34822d4 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_hashkey.h @@ -0,0 +1,59 @@ +/* + * coap_hashkey.h -- definition of hash key type and helper functions + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_hashkey.h + * @brief definition of hash key type and helper functions + */ + +#ifndef COAP_HASHKEY_H_ +#define COAP_HASHKEY_H_ + +#include "libcoap.h" +#include "uthash.h" +#include "str.h" + +typedef unsigned char coap_key_t[4]; + +#ifndef coap_hash +/** + * Calculates a fast hash over the given string @p s of length @p len and stores + * the result into @p h. Depending on the exact implementation, this function + * cannot be used as one-way function to check message integrity or simlar. + * + * @param s The string used for hash calculation. + * @param len The length of @p s. + * @param h The result buffer to store the calculated hash key. + */ +void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); + +#define coap_hash(String,Length,Result) \ + coap_hash_impl((String),(Length),(Result)) + +/* This is used to control the pre-set hash-keys for resources. */ +#define COAP_DEFAULT_HASH +#else +#undef COAP_DEFAULT_HASH +#endif /* coap_hash */ + +/** + * Calls coap_hash() with given @c coap_string_t object as parameter. + * + * @param Str Must contain a pointer to a coap string object. + * @param H A coap_key_t object to store the result. + * + * @hideinitializer + */ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((Str)->s, (Str)->length, (H)); \ + } + +#endif /* COAP_HASHKEY_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_io.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_io.h new file mode 100644 index 00000000000..1854501be89 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_io.h @@ -0,0 +1,210 @@ +/* + * coap_io.h -- Default network I/O functions for libcoap + * + * Copyright (C) 2012-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_IO_H_ +#define COAP_IO_H_ + +#include +#include + +#include "address.h" + +#ifndef COAP_RXBUFFER_SIZE +#define COAP_RXBUFFER_SIZE 1472 +#endif /* COAP_RXBUFFER_SIZE */ + +#ifdef _WIN32 +typedef SOCKET coap_fd_t; +#define coap_closesocket closesocket +#define COAP_SOCKET_ERROR SOCKET_ERROR +#define COAP_INVALID_SOCKET INVALID_SOCKET +#else +typedef int coap_fd_t; +#define coap_closesocket close +#define COAP_SOCKET_ERROR (-1) +#define COAP_INVALID_SOCKET (-1) +#endif + +struct coap_packet_t; +struct coap_session_t; +struct coap_pdu_t; + +typedef uint16_t coap_socket_flags_t; + +typedef struct coap_socket_t { +#if defined(WITH_LWIP) + struct udp_pcb *pcb; +#elif defined(WITH_CONTIKI) + void *conn; +#else + coap_fd_t fd; +#endif /* WITH_LWIP */ + coap_socket_flags_t flags; +} coap_socket_t; + +/** + * coap_socket_flags_t values + */ +#define COAP_SOCKET_EMPTY 0x0000 /**< the socket is not used */ +#define COAP_SOCKET_NOT_EMPTY 0x0001 /**< the socket is not empty */ +#define COAP_SOCKET_BOUND 0x0002 /**< the socket is bound */ +#define COAP_SOCKET_CONNECTED 0x0004 /**< the socket is connected */ +#define COAP_SOCKET_WANT_READ 0x0010 /**< non blocking socket is waiting for reading */ +#define COAP_SOCKET_WANT_WRITE 0x0020 /**< non blocking socket is waiting for writing */ +#define COAP_SOCKET_WANT_ACCEPT 0x0040 /**< non blocking server socket is waiting for accept */ +#define COAP_SOCKET_WANT_CONNECT 0x0080 /**< non blocking client socket is waiting for connect */ +#define COAP_SOCKET_CAN_READ 0x0100 /**< non blocking socket can now read without blocking */ +#define COAP_SOCKET_CAN_WRITE 0x0200 /**< non blocking socket can now write without blocking */ +#define COAP_SOCKET_CAN_ACCEPT 0x0400 /**< non blocking server socket can now accept without blocking */ +#define COAP_SOCKET_CAN_CONNECT 0x0800 /**< non blocking client socket can now connect without blocking */ +#define COAP_SOCKET_MULTICAST 0x1000 /**< socket is used for multicast communication */ + +struct coap_endpoint_t *coap_malloc_endpoint( void ); +void coap_mfree_endpoint( struct coap_endpoint_t *ep ); + +int +coap_socket_connect_udp(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_udp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr ); + +int +coap_socket_connect_tcp1(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_connect_tcp2(coap_socket_t *sock, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_tcp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr); + +int +coap_socket_accept_tcp(coap_socket_t *server, + coap_socket_t *new_client, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +void coap_socket_close(coap_socket_t *sock); + +ssize_t +coap_socket_send( coap_socket_t *sock, struct coap_session_t *session, + const uint8_t *data, size_t data_len ); + +ssize_t +coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len); + +ssize_t +coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len); + +#ifdef WITH_LWIP +ssize_t +coap_socket_send_pdu( coap_socket_t *sock, struct coap_session_t *session, + struct coap_pdu_t *pdu ); +#endif + +const char *coap_socket_strerror( void ); + +/** + * Function interface for data transmission. This function returns the number of + * bytes that have been transmitted, or a value less than zero on error. + * + * @param sock Socket to send data with + * @param session Addressing information for unconnected sockets, or NULL + * @param data The data to send. + * @param datalen The actual length of @p data. + * + * @return The number of bytes written on success, or a value + * less than zero on error. + */ +ssize_t coap_network_send( coap_socket_t *sock, const struct coap_session_t *session, const uint8_t *data, size_t datalen ); + +/** + * Function interface for reading data. This function returns the number of + * bytes that have been read, or a value less than zero on error. In case of an + * error, @p *packet is set to NULL. + * + * @param sock Socket to read data from + * @param packet Received packet metadata and payload. src and dst should be preset. + * + * @return The number of bytes received on success, or a value less than + * zero on error. + */ +ssize_t coap_network_read( coap_socket_t *sock, struct coap_packet_t *packet ); + +#ifndef coap_mcast_interface +# define coap_mcast_interface(Local) 0 +#endif + +/** + * Given a packet, set msg and msg_len to an address and length of the packet's + * data in memory. + * */ +void coap_packet_get_memmapped(struct coap_packet_t *packet, + unsigned char **address, + size_t *length); + +#ifdef WITH_LWIP +/** + * Get the pbuf of a packet. The caller takes over responsibility for freeing + * the pbuf. + */ +struct pbuf *coap_packet_extract_pbuf(struct coap_packet_t *packet); +#endif + +#if defined(WITH_LWIP) +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in lwippools.h. + * Simple carry-over of the incoming pbuf that is later turned into a node. + * + * Source address data is currently side-banded via ip_current_dest_addr & co + * as the packets have limited lifetime anyway. + */ +struct coap_packet_t { + struct pbuf *pbuf; + const struct coap_endpoint_t *local_interface; + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ +// uint16_t srcport; +}; +#else +struct coap_packet_t { + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ + size_t length; /**< length of payload */ + unsigned char payload[COAP_RXBUFFER_SIZE]; /**< payload */ +}; +#endif +typedef struct coap_packet_t coap_packet_t; + +typedef enum { + COAP_NACK_TOO_MANY_RETRIES, + COAP_NACK_NOT_DELIVERABLE, + COAP_NACK_RST, + COAP_NACK_TLS_FAILED +} coap_nack_reason_t; + +#endif /* COAP_IO_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_mutex.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_mutex.h new file mode 100644 index 00000000000..99d7d335e47 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_mutex.h @@ -0,0 +1,50 @@ +/* + * coap_mutex.h -- mutex utilities + * + * Copyright (C) 2019 Jon Shallow + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_mutex.h + * @brief COAP mutex mechanism wrapper + */ + +#ifndef COAP_MUTEX_H_ +#define COAP_MUTEX_H_ + +#if defined(RIOT_VERSION) + +#include + +typedef mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER MUTEX_INIT +#define coap_mutex_lock(a) mutex_lock(a) +#define coap_mutex_trylock(a) mutex_trylock(a) +#define coap_mutex_unlock(a) mutex_unlock(a) + +#elif defined(WITH_CONTIKI) + +/* CONTIKI does not support mutex */ + +typedef int coap_mutex_t; +#define COAP_MUTEX_INITIALIZER 0 +#define coap_mutex_lock(a) *(a) = 1 +#define coap_mutex_trylock(a) *(a) = 1 +#define coap_mutex_unlock(a) *(a) = 0 + +#else /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#include + +typedef pthread_mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define coap_mutex_lock(a) pthread_mutex_lock(a) +#define coap_mutex_trylock(a) pthread_mutex_trylock(a) +#define coap_mutex_unlock(a) pthread_mutex_unlock(a) + +#endif /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#endif /* COAP_MUTEX_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_session.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_session.h new file mode 100644 index 00000000000..1dc0103e3e7 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_session.h @@ -0,0 +1,492 @@ +/* coap_session.h -- Session management for libcoap +* +* Copyright (C) 2017 Jean-Claue Michelou +* +* This file is part of the CoAP library libcoap. Please see +* README for terms of use. +*/ + +#ifndef COAP_SESSION_H_ +#define COAP_SESSION_H_ + + +#include "coap_io.h" +#include "coap_time.h" +#include "pdu.h" + +struct coap_endpoint_t; +struct coap_context_t; +struct coap_queue_t; + +/** +* Abstraction of a fixed point number that can be used where necessary instead +* of a float. 1,000 fractional bits equals one integer +*/ +typedef struct coap_fixed_point_t { + uint16_t integer_part; /**< Integer part of fixed point variable */ + uint16_t fractional_part; /**< Fractional part of fixed point variable + 1/1000 (3 points) precision */ +} coap_fixed_point_t; + +#define COAP_DEFAULT_SESSION_TIMEOUT 300 +#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND) +#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100 + +#define COAP_PROTO_NOT_RELIABLE(p) ((p)==COAP_PROTO_UDP || (p)==COAP_PROTO_DTLS) +#define COAP_PROTO_RELIABLE(p) ((p)==COAP_PROTO_TCP || (p)==COAP_PROTO_TLS) + +typedef uint8_t coap_session_type_t; +/** + * coap_session_type_t values + */ +#define COAP_SESSION_TYPE_CLIENT 1 /**< client-side */ +#define COAP_SESSION_TYPE_SERVER 2 /**< server-side */ +#define COAP_SESSION_TYPE_HELLO 3 /**< server-side ephemeral session for responding to a client hello */ + +typedef uint8_t coap_session_state_t; +/** + * coap_session_state_t values + */ +#define COAP_SESSION_STATE_NONE 0 +#define COAP_SESSION_STATE_CONNECTING 1 +#define COAP_SESSION_STATE_HANDSHAKE 2 +#define COAP_SESSION_STATE_CSM 3 +#define COAP_SESSION_STATE_ESTABLISHED 4 + +typedef struct coap_session_t { + struct coap_session_t *next; + coap_proto_t proto; /**< protocol used */ + coap_session_type_t type; /**< client or server side socket */ + coap_session_state_t state; /**< current state of relationaship with peer */ + unsigned ref; /**< reference count from queues */ + unsigned tls_overhead; /**< overhead of TLS layer */ + unsigned mtu; /**< path or CSM mtu */ + coap_address_t local_if; /**< optional local interface address */ + coap_address_t remote_addr; /**< remote address and port */ + coap_address_t local_addr; /**< local address and port */ + int ifindex; /**< interface index */ + coap_socket_t sock; /**< socket object for the session, if any */ + struct coap_endpoint_t *endpoint; /**< session's endpoint */ + struct coap_context_t *context; /**< session's context */ + void *tls; /**< security parameters */ + uint16_t tx_mid; /**< the last message id that was used in this session */ + uint8_t con_active; /**< Active CON request sent */ + struct coap_queue_t *delayqueue; /**< list of delayed messages waiting to be sent */ + size_t partial_write; /**< if > 0 indicates number of bytes already written from the pdu at the head of sendqueue */ + uint8_t read_header[8]; /**< storage space for header of incoming message header */ + size_t partial_read; /**< if > 0 indicates number of bytes already read for an incoming message */ + coap_pdu_t *partial_pdu; /**< incomplete incoming pdu */ + coap_tick_t last_rx_tx; + coap_tick_t last_tx_rst; + coap_tick_t last_ping; + coap_tick_t last_pong; + coap_tick_t csm_tx; + uint8_t *psk_identity; + size_t psk_identity_len; + uint8_t *psk_key; + size_t psk_key_len; + void *app; /**< application-specific data */ + unsigned int max_retransmit; /**< maximum re-transmit count (default 4) */ + coap_fixed_point_t ack_timeout; /**< timeout waiting for ack (default 2 secs) */ + coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default 1.5) */ + unsigned int dtls_timeout_count; /**< dtls setup retry counter */ + int dtls_event; /**< Tracking any (D)TLS events on this sesison */ +} coap_session_t; + +/** +* Increment reference counter on a session. +* +* @param session The CoAP session. +* @return same as session +*/ +coap_session_t *coap_session_reference(coap_session_t *session); + +/** +* Decrement reference counter on a session. +* Note that the session may be deleted as a result and should not be used +* after this call. +* +* @param session The CoAP session. +*/ +void coap_session_release(coap_session_t *session); + +/** +* Stores @p data with the given session. This function overwrites any value +* that has previously been stored with @p session. +*/ +void coap_session_set_app_data(coap_session_t *session, void *data); + +/** +* Returns any application-specific data that has been stored with @p +* session using the function coap_session_set_app_data(). This function will +* return @c NULL if no data has been stored. +*/ +void *coap_session_get_app_data(const coap_session_t *session); + +/** +* Notify session that it has failed. +* +* @param session The CoAP session. +* @param reason The reason why the session was disconnected. +*/ +void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason); + +/** +* Notify session transport has just connected and CSM exchange can now start. +* +* @param session The CoAP session. +*/ +void coap_session_send_csm(coap_session_t *session); + +/** +* Notify session that it has just connected or reconnected. +* +* @param session The CoAP session. +*/ +void coap_session_connected(coap_session_t *session); + +/** +* Set the session MTU. This is the maximum message size that can be sent, +* excluding IP and UDP overhead. +* +* @param session The CoAP session. +* @param mtu maximum message size +*/ +void coap_session_set_mtu(coap_session_t *session, unsigned mtu); + +/** + * Get maximum acceptable PDU size + * + * @param session The CoAP session. + * @return maximum PDU size, not including header (but including token). + */ +size_t coap_session_max_pdu_size(const coap_session_t *session); + +/** +* Creates a new client session to the designated server. +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto +); + +/** +* Creates a new client session to the designated server with PSK credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* @param identity PSK client identity +* @param key PSK shared key +* @param key_len PSK shared key length +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session_psk( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + const char *identity, + const uint8_t *key, + unsigned key_len +); + +struct coap_dtls_pki_t; + +/** +* Creates a new client session to the designated server with PKI credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to +* let the operating system choose a suitable local interface. +* If an address is specified, the port number should be zero, +* which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default +* port for the protocol will be used. +* @param proto CoAP Protocol. +* @param setup_data PKI parameters. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release() +* to free. +*/ +coap_session_t *coap_new_client_session_pki( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + struct coap_dtls_pki_t *setup_data +); + +/** +* Creates a new server session for the specified endpoint. +* @param ctx The CoAP context. +* @param ep An endpoint where an incoming connection request is pending. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_server_session( + struct coap_context_t *ctx, + struct coap_endpoint_t *ep +); + +/** +* Function interface for datagram data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Function interface for stream data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. The number of bytes written may be less than datalen because of +* congestion control. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_write(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Send a pdu according to the session's protocol. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send pdu on. +* @param pdu The pdu to send. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu); + + +/** + * @ingroup logging + * Get session description. + * + * @param session The CoAP session. + * @return description string. + */ +const char *coap_session_str(const coap_session_t *session); + +ssize_t +coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, + struct coap_queue_t *node); +/** +* Abstraction of virtual endpoint that can be attached to coap_context_t. The +* tuple (handle, addr) must uniquely identify this endpoint. +*/ +typedef struct coap_endpoint_t { + struct coap_endpoint_t *next; + struct coap_context_t *context; /**< endpoint's context */ + coap_proto_t proto; /**< protocol used on this interface */ + uint16_t default_mtu; /**< default mtu for this interface */ + coap_socket_t sock; /**< socket object for the interface, if any */ + coap_address_t bind_addr; /**< local interface address */ + coap_session_t *sessions; /**< list of active sessions */ +} coap_endpoint_t; + +/** +* Create a new endpoint for communicating with peers. +* +* @param context The coap context that will own the new endpoint +* @param listen_addr Address the endpoint will listen for incoming requests on or originate outgoing requests from. Use NULL to specify that no incoming request will be accepted and use a random endpoint. +* @param proto Protocol used on this endpoint +*/ + +coap_endpoint_t *coap_new_endpoint(struct coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto); + +/** +* Set the endpoint's default MTU. This is the maximum message size that can be +* sent, excluding IP and UDP overhead. +* +* @param endpoint The CoAP endpoint. +* @param mtu maximum message size +*/ +void coap_endpoint_set_default_mtu(coap_endpoint_t *endpoint, unsigned mtu); + +void coap_free_endpoint(coap_endpoint_t *ep); + + +/** + * @ingroup logging +* Get endpoint description. +* +* @param endpoint The CoAP endpoint. +* @return description string. +*/ +const char *coap_endpoint_str(const coap_endpoint_t *endpoint); + +/** +* Lookup the server session for the packet received on an endpoint, or create +* a new one. +* +* @param endpoint Active endpoint the packet was received on. +* @param packet Received packet. +* @param now The current time in ticks. +* @return The CoAP session or @c NULL if error. +*/ +coap_session_t *coap_endpoint_get_session(coap_endpoint_t *endpoint, + const struct coap_packet_t *packet, coap_tick_t now); + +/** + * Create a new DTLS session for the @p session. + * Note: the @p session is released if no DTLS server session can be created. + * + * @ingroup dtls_internal + * + * @param session Session to add DTLS session to + * @param now The current time in ticks. + * + * @return CoAP session or @c NULL if error. + */ +coap_session_t *coap_session_new_dtls_session(coap_session_t *session, + coap_tick_t now); + +coap_session_t *coap_session_get_by_peer(struct coap_context_t *ctx, + const struct coap_address_t *remote_addr, int ifindex); + +void coap_session_free(coap_session_t *session); +void coap_session_mfree(coap_session_t *session); + + /** + * @defgroup cc Rate Control + * The transmission parameters for CoAP rate control ("Congestion + * Control" in stream-oriented protocols) are defined in + * https://tools.ietf.org/html/rfc7252#section-4.8 + * @{ + */ + + /** + * Number of seconds when to expect an ACK or a response to an + * outstanding CON message. + * RFC 7252, Section 4.8 Default value of ACK_TIMEOUT is 2 + */ +#define COAP_DEFAULT_ACK_TIMEOUT ((coap_fixed_point_t){2,0}) + + /** + * A factor that is used to randomize the wait time before a message + * is retransmitted to prevent synchronization effects. + * RFC 7252, Section 4.8 Default value of ACK_RANDOM_FACTOR is 1.5 + */ +#define COAP_DEFAULT_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1,500}) + + /** + * Number of message retransmissions before message sending is stopped + * RFC 7252, Section 4.8 Default value of MAX_RETRANSMIT is 4 + */ +#define COAP_DEFAULT_MAX_RETRANSMIT 4 + + /** + * The number of simultaneous outstanding interactions that a client + * maintains to a given server. + * RFC 7252, Section 4.8 Default value of NSTART is 1 + */ +#define COAP_DEFAULT_NSTART 1 + + /** @} */ + +/** +* Set the CoAP maximum retransmit count before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* @param value The value to set to. The default is 4 and should not normally +* get changed. +*/ +void coap_session_set_max_retransmit(coap_session_t *session, + unsigned int value); + +/** +* Set the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 2 and should not normally +* get changed. +*/ +void coap_session_set_ack_timeout(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Set the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 1.5 and should not normally +* get changed. +*/ +void coap_session_set_ack_random_factor(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Get the CoAP maximum retransmit before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* +* @return Current maximum retransmit value +*/ +unsigned int coap_session_get_max_transmit(coap_session_t *session); + +/** +* Get the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* +* @return Current ack response timeout value +*/ +coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t *session); + +/** +* Get the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* +* @return Current ack randomize value +*/ +coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t *session); + +/** + * Send a ping message for the session. + * @param session The CoAP session. + * + * @return COAP_INVALID_TID if there is an error + */ +coap_tid_t coap_session_send_ping(coap_session_t *session); + +#endif /* COAP_SESSION_H */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_time.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_time.h new file mode 100644 index 00000000000..e4a8e7c7c73 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/coap_time.h @@ -0,0 +1,162 @@ +/* + * coap_time.h -- Clock Handling + * + * Copyright (C) 2010-2019 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_time.h + * @brief Clock Handling + */ + +#ifndef COAP_TIME_H_ +#define COAP_TIME_H_ + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. + * @{ + */ + +#if defined(WITH_LWIP) + +#include +#include + +/* lwIP provides ms in sys_now */ +#define COAP_TICKS_PER_SECOND 1000 + +typedef uint32_t coap_tick_t; +typedef uint32_t coap_time_t; +typedef int32_t coap_tick_diff_t; + +COAP_STATIC_INLINE void coap_ticks_impl(coap_tick_t *t) { + *t = sys_now(); +} + +COAP_STATIC_INLINE void coap_clock_init_impl(void) { +} + +#define coap_clock_init coap_clock_init_impl +#define coap_ticks coap_ticks_impl + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#elif defined(WITH_CONTIKI) + +#include "clock.h" + +typedef clock_time_t coap_tick_t; +typedef clock_time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int coap_tick_diff_t; + +#define COAP_TICKS_PER_SECOND CLOCK_SECOND + +COAP_STATIC_INLINE void coap_clock_init(void) { + clock_init(); +} + +COAP_STATIC_INLINE void coap_ticks(coap_tick_t *t) { + *t = clock_time(); +} + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#else +#include + +/** + * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND + * resolution. + */ +typedef uint64_t coap_tick_t; + +/** + * CoAP time in seconds since epoch. + */ +typedef time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int64_t coap_tick_diff_t; + +/** Use ms resolution on POSIX systems */ +#define COAP_TICKS_PER_SECOND ((coap_tick_t)(1000U)) + +/** + * Initializes the internal clock. + */ +void coap_clock_init(void); + +/** + * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. + */ +void coap_ticks(coap_tick_t *t); + +/** + * Helper function that converts coap ticks to wallclock time. On POSIX, this + * function returns the number of seconds since the epoch. On other systems, it + * may be the calculated number of seconds since last reboot or so. + * + * @param t Internal system ticks. + * + * @return The number of seconds that has passed since a specific reference + * point (seconds since epoch on POSIX). + */ +coap_time_t coap_ticks_to_rt(coap_tick_t t); + +/** +* Helper function that converts coap ticks to POSIX wallclock time in us. +* +* @param t Internal system ticks. +* +* @return The number of seconds that has passed since a specific reference +* point (seconds since epoch on POSIX). +*/ +uint64_t coap_ticks_to_rt_us(coap_tick_t t); + +/** +* Helper function that converts POSIX wallclock time in us to coap ticks. +* +* @param t POSIX time is us +* +* @return coap ticks +*/ +coap_tick_t coap_ticks_from_rt_us(uint64_t t); +#endif + +/** + * Returns @c 1 if and only if @p a is less than @p b where less is defined on a + * signed data type. + */ +COAP_STATIC_INLINE int coap_time_lt(coap_tick_t a, coap_tick_t b) { + return ((coap_tick_diff_t)(a - b)) < 0; +} + +/** + * Returns @c 1 if and only if @p a is less than or equal @p b where less is + * defined on a signed data type. + */ +COAP_STATIC_INLINE int coap_time_le(coap_tick_t a, coap_tick_t b) { + return a == b || coap_time_lt(a,b); +} + +/** @} */ + +#endif /* COAP_TIME_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/encode.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/encode.h new file mode 100644 index 00000000000..b6d1524443c --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/encode.h @@ -0,0 +1,96 @@ +/* + * encode.h -- encoding and decoding of CoAP data types + * + * Copyright (C) 2010-2012 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_ENCODE_H_ +#define COAP_ENCODE_H_ + +#if (BSD >= 199103) || defined(WITH_CONTIKI) || defined(_WIN32) +# include +#else +# include +#endif + +#include + +#define Nn 8 /* duplicate definition of N if built on sky motes */ +#define ENCODE_HEADER_SIZE 4 +#define HIBIT (1 << (Nn - 1)) +#define EMASK ((1 << ENCODE_HEADER_SIZE) - 1) +#define MMASK ((1 << Nn) - 1 - EMASK) +#define MAX_VALUE ( (1 << Nn) - (1 << ENCODE_HEADER_SIZE) ) * (1 << ((1 << ENCODE_HEADER_SIZE) - 1)) + +#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK)) + +#ifndef HAVE_FLS +/* include this only if fls() is not available */ +extern int coap_fls(unsigned int i); +#else +#define coap_fls(i) fls(i) +#endif + +#ifndef HAVE_FLSLL + /* include this only if flsll() is not available */ +extern int coap_flsll(long long i); +#else +#define coap_flsll(i) flsll(i) +#endif + +/* ls and s must be integer variables */ +#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls) +#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls)) + +/** + * Decodes multiple-length byte sequences. @p buf points to an input byte + * sequence of length @p length. Returns the decoded value. + * + * @param buf The input byte sequence to decode from + * @param length The length of the input byte sequence + * + * @return The decoded value + */ +unsigned int coap_decode_var_bytes(const uint8_t *buf, unsigned int length); + +/** + * Encodes multiple-length byte sequences. @p buf points to an output buffer of + * sufficient length to store the encoded bytes. @p value is the value to + * encode. + * Returns the number of bytes used to encode @p value or 0 on error. + * + * @param buf The output buffer to decode into + * @param length The output buffer size to encode into (must be sufficient) + * @param value The value to encode into the buffer + * + * @return The number of bytes used to encode @p value or @c 0 on error. + */ +unsigned int coap_encode_var_safe(uint8_t *buf, + size_t length, + unsigned int value); + +/** + * @deprecated Use coap_encode_var_safe() instead. + * Provided for backward compatibility. As @p value has a + * maximum value of 0xffffffff, and buf is usually defined as an array, it + * is unsafe to continue to use this variant if buf[] is less than buf[4]. + * + * For example + * char buf[1],oops; + * .. + * coap_encode_var_bytes(buf, 0xfff); + * would cause oops to get overwritten. This error can only be found by code + * inspection. + * coap_encode_var_safe(buf, sizeof(buf), 0xfff); + * would catch this error at run-time and should be used instead. + */ +COAP_STATIC_INLINE COAP_DEPRECATED int +coap_encode_var_bytes(uint8_t *buf, unsigned int value +) { + return (int)coap_encode_var_safe(buf, sizeof(value), value); +} + +#endif /* COAP_ENCODE_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/libcoap.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/libcoap.h new file mode 100644 index 00000000000..77ba5db23e2 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/libcoap.h @@ -0,0 +1,54 @@ +/* + * libcoap.h -- platform specific header file for CoAP stack + * + * Copyright (C) 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_LIBCOAP_H_ +#define COAP_LIBCOAP_H_ + +/* The non posix embedded platforms like Contiki, TinyOS, RIOT, ... doesn't have + * a POSIX compatible header structure so we have to slightly do some platform + * related things. Currently there is only Contiki available so we check for a + * CONTIKI environment and do *not* include the POSIX related network stuff. If + * there are other platforms in future there need to be analogous environments. + * + * The CONTIKI variable is within the Contiki build environment! */ + +#if defined(_WIN32) +#pragma comment(lib,"Ws2_32.lib") +#include +typedef SSIZE_T ssize_t; +typedef USHORT in_port_t; +#elif !defined (CONTIKI) +#include +#include +#endif /* CONTIKI */ + +#ifndef COAP_STATIC_INLINE +# if defined(__cplusplus) +# define COAP_STATIC_INLINE inline +# else +# if defined(_MSC_VER) +# define COAP_STATIC_INLINE static __inline +# else +# define COAP_STATIC_INLINE static inline +# endif +# endif +#endif +#ifndef COAP_DEPRECATED +# if defined(_MSC_VER) +# define COAP_DEPRECATED __declspec(deprecated) +# else +# define COAP_DEPRECATED __attribute__ ((deprecated)) +# endif +#endif + +void coap_startup(void); + +void coap_cleanup(void); + +#endif /* COAP_LIBCOAP_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/lwippools.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/lwippools.h new file mode 100644 index 00000000000..cb90d8099db --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/lwippools.h @@ -0,0 +1,81 @@ +/* + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/* Memory pool definitions for the libcoap when used with lwIP (which has its + * own mechanism for quickly allocating chunks of data with known sizes). Has + * to be findable by lwIP (ie. an #include must either directly + * include this or include something more generic which includes this), and + * MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */ + +#include "coap_config.h" +#include +#include +#include + +#ifndef MEMP_NUM_COAPCONTEXT +#define MEMP_NUM_COAPCONTEXT 1 +#endif + +#ifndef MEMP_NUM_COAPENDPOINT +#define MEMP_NUM_COAPENDPOINT 1 +#endif + +/* 1 is sufficient as this is very short-lived */ +#ifndef MEMP_NUM_COAPPACKET +#define MEMP_NUM_COAPPACKET 1 +#endif + +#ifndef MEMP_NUM_COAPNODE +#define MEMP_NUM_COAPNODE 4 +#endif + +#ifndef MEMP_NUM_COAPPDU +#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE +#endif + +#ifndef MEMP_NUM_COAPSESSION +#define MEMP_NUM_COAPSESSION 2 +#endif + +#ifndef MEMP_NUM_COAP_SUBSCRIPTION +#define MEMP_NUM_COAP_SUBSCRIPTION 4 +#endif + +#ifndef MEMP_NUM_COAPRESOURCE +#define MEMP_NUM_COAPRESOURCE 10 +#endif + +#ifndef MEMP_NUM_COAPRESOURCEATTR +#define MEMP_NUM_COAPRESOURCEATTR 20 +#endif + +#ifndef MEMP_NUM_COAPOPTLIST +#define MEMP_NUM_COAPOPTLIST 1 +#endif + +#ifndef MEMP_LEN_COAPOPTLIST +#define MEMP_LEN_COAPOPTLIST 12 +#endif + +#ifndef MEMP_NUM_COAPSTRING +#define MEMP_NUM_COAPSTRING 10 +#endif + +#ifndef MEMP_LEN_COAPSTRING +#define MEMP_LEN_COAPSTRING 32 +#endif + +LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") +LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") +LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") +LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") +LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION") +LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") +LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") +LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") +LWIP_MEMPOOL(COAP_OPTLIST, MEMP_NUM_COAPOPTLIST, sizeof(coap_optlist_t)+MEMP_LEN_COAPOPTLIST, "COAP_OPTLIST") +LWIP_MEMPOOL(COAP_STRING, MEMP_NUM_COAPSTRING, sizeof(coap_string_t)+MEMP_LEN_COAPSTRING, "COAP_STRING") + diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/mem.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/mem.h new file mode 100644 index 00000000000..ea3c619fd30 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/mem.h @@ -0,0 +1,116 @@ +/* + * mem.h -- CoAP memory handling + * + * Copyright (C) 2010-2011,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_MEM_H_ +#define COAP_MEM_H_ + +#include + +#ifndef WITH_LWIP +/** + * Initializes libcoap's memory management. + * This function must be called once before coap_malloc() can be used on + * constrained devices. + */ +void coap_memory_init(void); +#endif /* WITH_LWIP */ + +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed to + * facilitate arrays of type objects to be used instead of dynamic memory + * management on constrained devices. + */ +typedef enum { + COAP_STRING, + COAP_ATTRIBUTE_NAME, + COAP_ATTRIBUTE_VALUE, + COAP_PACKET, + COAP_NODE, + COAP_CONTEXT, + COAP_ENDPOINT, + COAP_PDU, + COAP_PDU_BUF, + COAP_RESOURCE, + COAP_RESOURCEATTR, +#ifdef HAVE_LIBTINYDTLS + COAP_DTLS_SESSION, +#endif + COAP_SESSION, + COAP_OPTLIST, +} coap_memory_tag_t; + +#ifndef WITH_LWIP + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the newly + * allocated memory. The @p type is used to select the appropriate storage + * container on constrained devices. The storage allocated by coap_malloc_type() + * must be released with coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). The type tag @p + * type must be the same that was used for allocating the object pointed to by + * @p . + * + * @param type The type of the object to release. + * @param p A pointer to memory that was allocated by coap_malloc_type(). + */ +void coap_free_type(coap_memory_tag_t type, void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void coap_free(void *object) { + coap_free_type(COAP_STRING, object); +} + +#endif /* not WITH_LWIP */ + +#ifdef WITH_LWIP + +#include + +/* no initialization needed with lwip (or, more precisely: lwip must be + * completely initialized anyway by the time coap gets active) */ +COAP_STATIC_INLINE void coap_memory_init(void) {} + +/* It would be nice to check that size equals the size given at the memp + * declaration, but i currently don't see a standard way to check that without + * sourcing the custom memp pools and becoming dependent of its syntax + */ +#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_free_type(type, p) memp_free(MEMP_ ## type, p) + +/* Those are just here to make uri.c happy where string allocation has not been + * made conditional. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + LWIP_ASSERT("coap_malloc must not be used in lwIP", 0); +} + +COAP_STATIC_INLINE void coap_free(void *pointer) { + LWIP_ASSERT("coap_free must not be used in lwIP", 0); +} + +#endif /* WITH_LWIP */ + +#endif /* COAP_MEM_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/net.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/net.h new file mode 100644 index 00000000000..7fccf3326c7 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/net.h @@ -0,0 +1,746 @@ +/* + * net.h -- CoAP network interface + * + * Copyright (C) 2010-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_NET_H_ +#define COAP_NET_H_ + +#include +#include +#include +#ifndef _WIN32 +#include +#endif +#include + +#ifdef WITH_LWIP +#include +#endif + +#include "coap_io.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_time.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "coap_session.h" + +struct coap_queue_t; + +/** + * Queue entry + */ +typedef struct coap_queue_t { + struct coap_queue_t *next; + coap_tick_t t; /**< when to send PDU for the next time */ + unsigned char retransmit_cnt; /**< retransmission counter, will be removed + * when zero */ + unsigned int timeout; /**< the randomized timeout value */ + coap_session_t *session; /**< the CoAP session */ + coap_tid_t id; /**< CoAP transaction id */ + coap_pdu_t *pdu; /**< the CoAP PDU to send */ +} coap_queue_t; + +/** + * Adds @p node to given @p queue, ordered by variable t in @p node. + * + * @param queue Queue to add to. + * @param node Node entry to add to Queue. + * + * @return @c 1 added to queue, @c 0 failure. + */ +int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); + +/** + * Destroys specified @p node. + * + * @param node Node entry to remove. + * + * @return @c 1 node deleted from queue, @c 0 failure. + */ +int coap_delete_node(coap_queue_t *node); + +/** + * Removes all items from given @p queue and frees the allocated storage. + * + * @param queue The queue to delete. + */ +void coap_delete_all(coap_queue_t *queue); + +/** + * Creates a new node suitable for adding to the CoAP sendqueue. + * + * @return New node entry, or @c NULL if failure. + */ +coap_queue_t *coap_new_node(void); + +struct coap_resource_t; +struct coap_context_t; +#ifndef WITHOUT_ASYNC +struct coap_async_state_t; +#endif + +/** + * Response handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_response_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Negative Acknowedge handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param reason The reason for the NACK. + * @param id CoAP transaction ID. + */ +typedef void (*coap_nack_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_nack_reason_t reason, + const coap_tid_t id); + +/** + * Recieved Ping handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_ping_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Recieved Pong handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_pong_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * The CoAP stack's global state is stored in a coap_context_t object. + */ +typedef struct coap_context_t { + coap_opt_filter_t known_options; + struct coap_resource_t *resources; /**< hash table or list of known + resources */ + struct coap_resource_t *unknown_resource; /**< can be used for handling + unknown resources */ + +#ifndef WITHOUT_ASYNC + /** + * list of asynchronous transactions */ + struct coap_async_state_t *async_state; +#endif /* WITHOUT_ASYNC */ + + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue; + coap_endpoint_t *endpoint; /**< the endpoints used for listening */ + coap_session_t *sessions; /**< client sessions */ + +#ifdef WITH_CONTIKI + struct uip_udp_conn *conn; /**< uIP connection object */ + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ + struct etimer notify_timer; /**< used to check resources periodically */ +#endif /* WITH_CONTIKI */ + +#ifdef WITH_LWIP + uint8_t timer_configured; /**< Set to 1 when a retransmission is + * scheduled using lwIP timers for this + * context, otherwise 0. */ +#endif /* WITH_LWIP */ + + coap_response_handler_t response_handler; + coap_nack_handler_t nack_handler; + coap_ping_handler_t ping_handler; + coap_pong_handler_t pong_handler; + + /** + * Callback function that is used to signal events to the + * application. This field is set by coap_set_event_handler(). + */ + coap_event_handler_t handle_event; + + ssize_t (*network_send)(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen); + + ssize_t (*network_read)(coap_socket_t *sock, struct coap_packet_t *packet); + + size_t(*get_client_psk)(const coap_session_t *session, const uint8_t *hint, size_t hint_len, uint8_t *identity, size_t *identity_len, size_t max_identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_psk)(const coap_session_t *session, const uint8_t *identity, size_t identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len); + + void *dtls_context; + uint8_t *psk_hint; + size_t psk_hint_len; + uint8_t *psk_key; + size_t psk_key_len; + + unsigned int session_timeout; /**< Number of seconds of inactivity after which an unused session will be closed. 0 means use default. */ + unsigned int max_idle_sessions; /**< Maximum number of simultaneous unused sessions per endpoint. 0 means no maximum. */ + unsigned int max_handshake_sessions; /**< Maximum number of simultaneous negotating sessions per endpoint. 0 means use default. */ + unsigned int ping_timeout; /**< Minimum inactivity time before sending a ping message. 0 means disabled. */ + unsigned int csm_timeout; /**< Timeout for waiting for a CSM from the remote side. 0 means disabled. */ + + void *app; /**< application-specific data */ +} coap_context_t; + +/** + * Registers a new message handler that is called whenever a response was + * received that matches an ongoing transaction. + * + * @param context The context to register the handler for. + * @param handler The response handler to register. + */ +COAP_STATIC_INLINE void +coap_register_response_handler(coap_context_t *context, + coap_response_handler_t handler) { + context->response_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a confirmable + * message (request or response) is dropped after all retries have been + * exhausted, or a rst message was received, or a network or TLS level + * event was received that indicates delivering the message is not possible. + * + * @param context The context to register the handler for. + * @param handler The nack handler to register. + */ +COAP_STATIC_INLINE void +coap_register_nack_handler(coap_context_t *context, + coap_nack_handler_t handler) { + context->nack_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Ping + * message is received. + * + * @param context The context to register the handler for. + * @param handler The ping handler to register. + */ +COAP_STATIC_INLINE void +coap_register_ping_handler(coap_context_t *context, + coap_ping_handler_t handler) { + context->ping_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Pong + * message is received. + * + * @param context The context to register the handler for. + * @param handler The pong handler to register. + */ +COAP_STATIC_INLINE void +coap_register_pong_handler(coap_context_t *context, + coap_pong_handler_t handler) { + context->pong_handler = handler; +} + +/** + * Registers the option type @p type with the given context object @p ctx. + * + * @param ctx The context to use. + * @param type The option type to register. + */ +COAP_STATIC_INLINE void +coap_register_option(coap_context_t *ctx, uint16_t type) { + coap_option_setb(ctx->known_options, type); +} + +/** + * Set sendqueue_basetime in the given context object @p ctx to @p now. This + * function returns the number of elements in the queue head that have timed + * out. + */ +unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); + +/** + * Returns the next pdu to send without removing from sendqeue. + */ +coap_queue_t *coap_peek_next( coap_context_t *context ); + +/** + * Returns the next pdu to send and removes it from the sendqeue. + */ +coap_queue_t *coap_pop_next( coap_context_t *context ); + +/** + * Creates a new coap_context_t object that will hold the CoAP stack status. + */ +coap_context_t *coap_new_context(const coap_address_t *listen_addr); + +/** + * Set the context's default PSK hint and/or key for a server. + * + * @param context The current coap_context_t object. + * @param hint The default PSK server hint sent to a client. If @p NULL, PSK + * authentication is disabled. Empty string is a valid hint. + * @param key The default PSK key. If @p NULL, PSK authentication will fail. + * @param key_len The default PSK key's length. If @p 0, PSK authentication will + * fail. + * + * @return @c 1 if successful, else @c 0. + */ +int coap_context_set_psk( coap_context_t *context, const char *hint, + const uint8_t *key, size_t key_len ); + +/** + * Set the context's default PKI information for a server. + * + * @param context The current coap_context_t object. + * @param setup_data If @p NULL, PKI authentication will fail. Certificate + * information required. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki(coap_context_t *context, + coap_dtls_pki_t *setup_data); + +/** + * Set the context's default Root CA information for a client or server. + * + * @param context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki_root_cas(coap_context_t *context, + const char *ca_file, + const char *ca_dir); + +/** + * Set the context keepalive timer for sessions. + * A keepalive message will be sent after if a session has been inactive, + * i.e. no packet sent or received, for the given number of seconds. + * For reliable protocols, a PING message will be sent. If a PONG has not + * been received before the next PING is due to be sent, the session will + * considered as disconnected. + * + * @param context The coap_context_t object. + * @param seconds Number of seconds for the inactivity timer, or zero + * to disable CoAP-level keepalive messages. + * + * @return 1 if successful, else 0 + */ +void coap_context_set_keepalive(coap_context_t *context, unsigned int seconds); + +/** + * Returns a new message id and updates @p session->tx_mid accordingly. The + * message id is returned in network byte order to make it easier to read in + * tracing tools. + * + * @param session The current coap_session_t object. + * + * @return Incremented message id in network byte order. + */ +COAP_STATIC_INLINE uint16_t +coap_new_message_id(coap_session_t *session) { + return ++session->tx_mid; +} + +/** + * CoAP stack context must be released with coap_free_context(). This function + * clears all entries from the receive queue and send queue and deletes the + * resources that have been registered with @p context, and frees the attached + * endpoints. + * + * @param context The current coap_context_t object to free off. + */ +void coap_free_context(coap_context_t *context); + +/** + * Stores @p data with the given CoAP context. This function + * overwrites any value that has previously been stored with @p + * context. + * + * @param context The CoAP context. + * @param data The data to store with wih the context. Note that this data + * must be valid during the lifetime of @p context. + */ +void coap_set_app_data(coap_context_t *context, void *data); + +/** + * Returns any application-specific data that has been stored with @p + * context using the function coap_set_app_data(). This function will + * return @c NULL if no data has been stored. + * + * @param context The CoAP context. + * + * @return The data previously stored or @c NULL if not data stored. + */ +void *coap_get_app_data(const coap_context_t *context); + +/** + * Creates a new ACK PDU with specified error @p code. The options specified by + * the filter expression @p opts will be copied from the original request + * contained in @p request. Unless @c SHORT_ERROR_RESPONSE was defined at build + * time, the textual reason phrase for @p code will be added as payload, with + * Content-Type @c 0. + * This function returns a pointer to the new response message, or @c NULL on + * error. The storage allocated for the new message must be relased with + * coap_free(). + * + * @param request Specification of the received (confirmable) request. + * @param code The error code to set. + * @param opts An option filter that specifies which options to copy from + * the original request in @p node. + * + * @return A pointer to the new message or @c NULL on error. + */ +coap_pdu_t *coap_new_error_response(coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Sends an error response with code @p code for request @p request to @p dst. + * @p opts will be passed to coap_new_error_response() to copy marked options + * from the request. This function returns the transaction id if the message was + * sent, or @c COAP_INVALID_TID otherwise. + * + * @param session The CoAP session. + * @param request The original request to respond to. + * @param code The response code. + * @param opts A filter that specifies the options to copy from the + * @p request. + * + * @return The transaction id if the message was sent, or @c + * COAP_INVALID_TID otherwise. + */ +coap_tid_t coap_send_error(coap_session_t *session, + coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Helper funktion to create and send a message with @p type (usually ACK or + * RST). This function returns @c COAP_INVALID_TID when the message was not + * sent, a valid transaction id otherwise. + * + * @param session The CoAP session. + * @param request The request that should be responded to. + * @param type Which type to set. + * @return transaction id on success or @c COAP_INVALID_TID + * otherwise. + */ +coap_tid_t +coap_send_message_type(coap_session_t *session, coap_pdu_t *request, unsigned char type); + +/** + * Sends an ACK message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be acknowledged. + * + * @return The transaction id if ACK was sent or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_ack(coap_session_t *session, coap_pdu_t *request); + +/** + * Sends an RST message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be reset. + * + * @return The transaction id if RST was sent or @c + * COAP_INVALID_TID on error. + */ +COAP_STATIC_INLINE coap_tid_t +coap_send_rst(coap_session_t *session, coap_pdu_t *request) { + return coap_send_message_type(session, request, COAP_MESSAGE_RST); +} + +/** +* Sends a CoAP message to given peer. The memory that is +* allocated by pdu will be released by coap_send(). +* The caller must not use the pdu after calling coap_send(). +* +* @param session The CoAP session. +* @param pdu The CoAP PDU to send. +* +* @return The message id of the sent message or @c +* COAP_INVALID_TID on error. +*/ +coap_tid_t coap_send( coap_session_t *session, coap_pdu_t *pdu ); + +/** + * Handles retransmissions of confirmable messages + * + * @param context The CoAP context. + * @param node The node to retransmit. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); + +/** +* For applications with their own message loop, send all pending retransmits and +* return the list of sockets with events to wait for and the next timeout +* The application should call coap_read, then coap_write again when any condition below is true: +* - data is available on any of the sockets with the COAP_SOCKET_WANT_READ +* - an incoming connection is pending in the listen queue and the COAP_SOCKET_WANT_ACCEPT flag is set +* - at least some data can be written without blocking on any of the sockets with the COAP_SOCKET_WANT_WRITE flag set +* - a connection event occured (success or failure) and the COAP_SOCKET_WANT_CONNECT flag is set +* - the timeout has expired +* Before calling coap_read or coap_write again, the application should position COAP_SOCKET_CAN_READ and COAP_SOCKET_CAN_WRITE flags as applicable. +* +* @param ctx The CoAP context +* @param sockets array of socket descriptors, filled on output +* @param max_sockets size of socket array. +* @param num_sockets pointer to the number of valid entries in the socket arrays on output +* @param now Current time. +* +* @return timeout as maxmimum number of milliseconds that the application should wait for network events or 0 if the application should wait forever. +*/ + +unsigned int +coap_write(coap_context_t *ctx, + coap_socket_t *sockets[], + unsigned int max_sockets, + unsigned int *num_sockets, + coap_tick_t now +); + +/** + * For applications with their own message loop, reads all data from the network. + * + * @param ctx The CoAP context + * @param now Current time + */ +void coap_read(coap_context_t *ctx, coap_tick_t now); + +/** + * The main message processing loop. + * + * @param ctx The CoAP context + * @param timeout_ms Minimum number of milliseconds to wait for new messages before returning. If zero the call will block until at least one packet is sent or received. + * + * @return number of milliseconds spent or @c -1 if there was an error + */ + +int coap_run_once( coap_context_t *ctx, unsigned int timeout_ms ); + +/** + * Parses and interprets a CoAP datagram with context @p ctx. This function + * returns @c 0 if the datagram was handled, or a value less than zero on + * error. + * + * @param ctx The current CoAP context. + * @param session The current CoAP session. + * @param data The received packet'd data. + * @param data_len The received packet'd data length. + * + * @return @c 0 if message was handled successfully, or less than zero on + * error. + */ +int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len); + +/** + * Invokes the event handler of @p context for the given @p event and + * @p data. + * + * @param context The CoAP context whose event handler is to be called. + * @param event The event to deliver. + * @param session The session related to @p event. + * @return The result from the associated event handler or 0 if none was + * registered. + */ +int coap_handle_event(coap_context_t *context, + coap_event_t event, + coap_session_t *session); +/** + * This function removes the element with given @p id from the list given list. + * If @p id was found, @p node is updated to point to the removed element. Note + * that the storage allocated by @p node is @b not released. The caller must do + * this manually using coap_delete_node(). This function returns @c 1 if the + * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, + * the contents of @p node is undefined. + * + * @param queue The queue to search for @p id. + * @param session The session to look for. + * @param id The transaction id to look for. + * @param node If found, @p node is updated to point to the removed node. You + * must release the storage pointed to by @p node manually. + * + * @return @c 1 if @p id was found, @c 0 otherwise. + */ +int coap_remove_from_queue(coap_queue_t **queue, + coap_session_t *session, + coap_tid_t id, + coap_queue_t **node); + +coap_tid_t +coap_wait_ack( coap_context_t *context, coap_session_t *session, + coap_queue_t *node); + +/** + * Retrieves transaction from the queue. + * + * @param queue The transaction queue to be searched. + * @param session The session to find. + * @param id The transaction id to find. + * + * @return A pointer to the transaction object or @c NULL if not found. + */ +coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_session_t *session, coap_tid_t id); + +/** + * Cancels all outstanding messages for session @p session that have the specified + * token. + * + * @param context The context in use. + * @param session Session of the messages to remove. + * @param token Message token. + * @param token_length Actual length of @p token. + */ +void coap_cancel_all_messages(coap_context_t *context, + coap_session_t *session, + const uint8_t *token, + size_t token_length); + +/** +* Cancels all outstanding messages for session @p session. +* +* @param context The context in use. +* @param session Session of the messages to remove. +* @param reason The reasion for the session cancellation +*/ +void +coap_cancel_session_messages(coap_context_t *context, + coap_session_t *session, + coap_nack_reason_t reason); + +/** + * Dispatches the PDUs from the receive queue in given context. + */ +void coap_dispatch(coap_context_t *context, coap_session_t *session, + coap_pdu_t *pdu); + +/** + * Returns 1 if there are no messages to send or to dispatch in the context's + * queues. */ +int coap_can_exit(coap_context_t *context); + +/** + * Returns the current value of an internal tick counter. The counter counts \c + * COAP_TICKS_PER_SECOND ticks every second. + */ +void coap_ticks(coap_tick_t *); + +/** + * Verifies that @p pdu contains no unknown critical options. Options must be + * registered at @p ctx, using the function coap_register_option(). A basic set + * of options is registered automatically by coap_new_context(). This function + * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p + * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT + * options can be signalled this way, remaining options must be examined + * manually. + * + * @code + coap_opt_filter_t f = COAP_OPT_NONE; + coap_opt_iterator_t opt_iter; + + if (coap_option_check_critical(ctx, pdu, f) == 0) { + coap_option_iterator_init(pdu, &opt_iter, f); + + while (coap_option_next(&opt_iter)) { + if (opt_iter.type & 0x01) { + ... handle unknown critical option in opt_iter ... + } + } + } + @endcode + * + * @param ctx The context where all known options are registered. + * @param pdu The PDU to check. + * @param unknown The output filter that will be updated to indicate the + * unknown critical options found in @p pdu. + * + * @return @c 1 if everything was ok, @c 0 otherwise. + */ +int coap_option_check_critical(coap_context_t *ctx, + coap_pdu_t *pdu, + coap_opt_filter_t unknown); + +/** + * Creates a new response for given @p request with the contents of @c + * .well-known/core. The result is NULL on error or a newly allocated PDU that + * must be either sent with coap_sent() or released by coap_delete_pdu(). + * + * @param context The current coap context to use. + * @param session The CoAP session. + * @param request The request for @c .well-known/core . + * + * @return A new 2.05 response for @c .well-known/core or NULL on error. + */ +coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request); + +/** + * Calculates the initial timeout based on the session CoAP transmission + * parameters 'ack_timeout', 'ack_random_factor', and COAP_TICKS_PER_SECOND. + * The calculation requires 'ack_timeout' and 'ack_random_factor' to be in + * Qx.FRAC_BITS fixed point notation, whereas the passed parameter @p r + * is interpreted as the fractional part of a Q0.MAX_BITS random value. + * + * @param session session timeout is associated with + * @param r random value as fractional part of a Q0.MAX_BITS fixed point + * value + * @return COAP_TICKS_PER_SECOND * 'ack_timeout' * + * (1 + ('ack_random_factor' - 1) * r) + */ +unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r); + +/** + * Function interface for joining a multicast group for listening + * + * @param ctx The current context + * @param groupname The name of the group that is to be joined for listening + * + * @return 0 on success, -1 on error + */ +int +coap_join_mcast_group(coap_context_t *ctx, const char *groupname); + +#endif /* COAP_NET_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/option.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/option.h new file mode 100644 index 00000000000..3af9e71e706 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/option.h @@ -0,0 +1,461 @@ +/* + * option.h -- helpers for handling options in CoAP PDUs + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file option.h + * @brief Helpers for handling options in CoAP PDUs + */ + +#ifndef COAP_OPTION_H_ +#define COAP_OPTION_H_ + +#include "bits.h" +#include "pdu.h" + +/** + * Use byte-oriented access methods here because sliding a complex struct + * coap_opt_t over the data buffer may cause bus error on certain platforms. + */ +typedef uint8_t coap_opt_t; +#define PCHAR(p) ((coap_opt_t *)(p)) + +/** + * Representation of CoAP options. + */ +typedef struct { + uint16_t delta; + size_t length; + const uint8_t *value; +} coap_option_t; + +/** + * Parses the option pointed to by @p opt into @p result. This function returns + * the number of bytes that have been parsed, or @c 0 on error. An error is + * signaled when illegal delta or length values are encountered or when option + * parsing would result in reading past the option (i.e. beyond opt + length). + * + * @param opt The beginning of the option to parse. + * @param length The maximum length of @p opt. + * @param result A pointer to the coap_option_t structure that is filled with + * actual values iff coap_opt_parse() > 0. + * @return The number of bytes parsed or @c 0 on error. + */ +size_t coap_opt_parse(const coap_opt_t *opt, + size_t length, + coap_option_t *result); + +/** + * Returns the size of the given option, taking into account a possible option + * jump. + * + * @param opt An option jump or the beginning of the option. + * @return The number of bytes between @p opt and the end of the option + * starting at @p opt. In case of an error, this function returns + * @c 0 as options need at least one byte storage space. + */ +size_t coap_opt_size(const coap_opt_t *opt); + +/** + * @defgroup opt_filter Option Filters + * API functions for access option filters + * @{ + */ + +/** + * The number of option types below 256 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_SHORT 6 + +/** + * The number of option types above 255 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * COAP_OPT_FILTER_LONG * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_LONG 2 + +/* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set + * correctly. */ +#if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) +#error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16 +#endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */ + +/** The number of elements in coap_opt_filter_t. */ +#define COAP_OPT_FILTER_SIZE \ + (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1 + +/** + * Fixed-size vector we use for option filtering. It is large enough + * to hold COAP_OPT_FILTER_SHORT entries with an option number between + * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number + * between 256 and 65535. Its internal structure is + * + * @code +struct { + uint16_t mask; + uint16_t long_opts[COAP_OPT_FILTER_LONG]; + uint8_t short_opts[COAP_OPT_FILTER_SHORT]; +} + * @endcode + * + * The first element contains a bit vector that indicates which fields + * in the remaining array are used. The first COAP_OPT_FILTER_LONG + * bits correspond to the long option types that are stored in the + * elements from index 1 to COAP_OPT_FILTER_LONG. The next + * COAP_OPT_FILTER_SHORT bits correspond to the short option types + * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1 + * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter + * elements are treated as bytes. + */ +typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE]; + +/** Pre-defined filter that includes all options. */ +#define COAP_OPT_ALL NULL + +/** + * Clears filter @p f. + * + * @param f The filter to clear. + */ +COAP_STATIC_INLINE void +coap_option_filter_clear(coap_opt_filter_t f) { + memset(f, 0, sizeof(coap_opt_filter_t)); +} + +/** + * Sets the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_set(coap_opt_filter_t filter, uint16_t type); + +/** + * Clears the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type that should be cleared from the filter. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_unset(coap_opt_filter_t filter, uint16_t type); + +/** + * Checks if @p type is contained in @p filter. This function returns + * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given + * type does not fit in the filter). + * + * @param filter The filter object to search. + * @param type The type to search for. + * + * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error. + */ +int coap_option_filter_get(coap_opt_filter_t filter, uint16_t type); + +/** + * Sets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in + * the filter). + * + * @deprecated Use coap_option_filter_set() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_setb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_set(filter, type) ? 1 : -1; +} + +/** + * Clears the corresponding bit for @p type in @p filter. This function returns + * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not + * fit in the filter). + * + * @deprecated Use coap_option_filter_unset() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be cleared. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_clrb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_unset(filter, type) ? 1 : -1; +} + +/** + * Gets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type + * does not fit in the filter). + * + * @deprecated Use coap_option_filter_get() instead. + * + * @param filter The filter object to read bit from. + * @param type The type for which the bit should be read. + * + * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. + */ +COAP_STATIC_INLINE int +coap_option_getb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_get(filter, type); +} + +/** + * Iterator to run through PDU options. This object must be + * initialized with coap_option_iterator_init(). Call + * coap_option_next() to walk through the list of options until + * coap_option_next() returns @c NULL. + * + * @code + * coap_opt_t *option; + * coap_opt_iterator_t opt_iter; + * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + * + * while ((option = coap_option_next(&opt_iter))) { + * ... do something with option ... + * } + * @endcode + */ +typedef struct { + size_t length; /**< remaining length of PDU */ + uint16_t type; /**< decoded option type */ + unsigned int bad:1; /**< iterator object is ok if not set */ + unsigned int filtered:1; /**< denotes whether or not filter is used */ + coap_opt_t *next_option; /**< pointer to the unparsed next option */ + coap_opt_filter_t filter; /**< option filter */ +} coap_opt_iterator_t; + +/** + * Initializes the given option iterator @p oi to point to the beginning of the + * @p pdu's option list. This function returns @p oi on success, @c NULL + * otherwise (i.e. when no options exist). Note that a length check on the + * option list must be performed before coap_option_iterator_init() is called. + * + * @param pdu The PDU the options of which should be walked through. + * @param oi An iterator object that will be initilized. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. + * Fence-post options @c 14, @c 28, @c 42, ... are always + * skipped. + * + * @return The iterator object @p oi on success, @c NULL otherwise. + */ +coap_opt_iterator_t *coap_option_iterator_init(const coap_pdu_t *pdu, + coap_opt_iterator_t *oi, + const coap_opt_filter_t filter); + +/** + * Updates the iterator @p oi to point to the next option. This function returns + * a pointer to that option or @c NULL if no more options exist. The contents of + * @p oi will be updated. In particular, @c oi->n specifies the current option's + * ordinal number (counted from @c 1), @c oi->type is the option's type code, + * and @c oi->option points to the beginning of the current option itself. When + * advanced past the last option, @c oi->option will be @c NULL. + * + * Note that options are skipped whose corresponding bits in the filter + * specified with coap_option_iterator_init() are @c 0. Options with type codes + * that do not fit in this filter hence will always be returned. + * + * @param oi The option iterator to update. + * + * @return The next option or @c NULL if no more options exist. + */ +coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); + +/** + * Retrieves the first option of type @p type from @p pdu. @p oi must point to a + * coap_opt_iterator_t object that will be initialized by this function to + * filter only options with code @p type. This function returns the first option + * with this type, or @c NULL if not found. + * + * @param pdu The PDU to parse for options. + * @param type The option type code to search for. + * @param oi An iterator object to use. + * + * @return A pointer to the first option of type @p type, or @c NULL if + * not found. + */ +coap_opt_t *coap_check_option(coap_pdu_t *pdu, + uint16_t type, + coap_opt_iterator_t *oi); + +/** + * Encodes the given delta and length values into @p opt. This function returns + * the number of bytes that were required to encode @p delta and @p length or @c + * 0 on error. Note that the result indicates by how many bytes @p opt must be + * advanced to encode the option value. + * + * @param opt The option buffer space where @p delta and @p length are + * written. + * @param maxlen The maximum length of @p opt. + * @param delta The actual delta value to encode. + * @param length The actual length value to encode. + * + * @return The number of bytes used or @c 0 on error. + */ +size_t coap_opt_setheader(coap_opt_t *opt, + size_t maxlen, + uint16_t delta, + size_t length); + +/** + * Compute storage bytes needed for an option with given @p delta and + * @p length + * + * @param delta The option delta. + * @param length The option length. + * + * @return The number of bytes required to encode this option. + */ +size_t coap_opt_encode_size(uint16_t delta, size_t length); + +/** + * Encodes option with given @p delta into @p opt. This function returns the + * number of bytes written to @p opt or @c 0 on error. This happens especially + * when @p opt does not provide sufficient space to store the option value, + * delta, and option jumps when required. + * + * @param opt The option buffer space where @p val is written. + * @param n Maximum length of @p opt. + * @param delta The option delta. + * @param val The option value to copy into @p opt. + * @param length The actual length of @p val. + * + * @return The number of bytes that have been written to @p opt or @c 0 on + * error. The return value will always be less than @p n. + */ +size_t coap_opt_encode(coap_opt_t *opt, + size_t n, + uint16_t delta, + const uint8_t *val, + size_t length); + +/** + * Decodes the delta value of the next option. This function returns the number + * of bytes read or @c 0 on error. The caller of this function must ensure that + * it does not read over the boundaries of @p opt (e.g. by calling + * coap_opt_check_delta(). + * + * @param opt The option to examine. + * + * @return The number of bytes read or @c 0 on error. + */ +uint16_t coap_opt_delta(const coap_opt_t *opt); + +/** + * Returns the length of the given option. @p opt must point to an option jump + * or the beginning of the option. This function returns @c 0 when @p opt is not + * an option or the actual length of @p opt (which can be @c 0 as well). + * + * @note {The rationale for using @c 0 in case of an error is that in most + * contexts, the result of this function is used to skip the next + * coap_opt_length() bytes.} + * + * @param opt The option whose length should be returned. + * + * @return The option's length or @c 0 when undefined. + */ +uint16_t coap_opt_length(const coap_opt_t *opt); + +/** + * Returns a pointer to the value of the given option. @p opt must point to an + * option jump or the beginning of the option. This function returns @c NULL if + * @p opt is not a valid option. + * + * @param opt The option whose value should be returned. + * + * @return A pointer to the option value or @c NULL on error. + */ +const uint8_t *coap_opt_value(const coap_opt_t *opt); + +/** @} */ + +/** + * Representation of chained list of CoAP options to install. + * + * @code + * coap_optlist_t *optlist_chain = NULL; + * coap_pdu_t *pdu = coap_new_pdu(session); + * + * ... other set up code ... + * coap_insert_optlist(&optlist_chain, coap_new_optlist(COAP_OPTION_OBSERVE, + * COAP_OBSERVE_ESTABLISH, NULL)); + * + * coap_add_optlist_pdu(pdu, &optlist_chain); + * ... other code ... + * coap_delete_optlist(optlist_chain); + * @endcode + */ +typedef struct coap_optlist_t { + struct coap_optlist_t *next; /**< next entry in the optlist chain */ + uint16_t number; /**< the option number (no delta coding) */ + size_t length; /**< the option value length */ + uint8_t *data; /**< the option data */ +} coap_optlist_t; + +/** + * Create a new optlist entry. + * + * @param number The option number (COAP_OPTION_*) + * @param length The option length + * @param data The option value data + * + * @return A pointer to the new optlist entry, or @c NULL if error + */ +coap_optlist_t *coap_new_optlist(uint16_t number, + size_t length, + const uint8_t *data); + +/** + * The current optlist of @p optlist_chain is first sorted (as per RFC7272 + * ordering requirements) and then added to the @p pdu. + * + * @param pdu The pdu to add the options to from the chain list + * @param optlist_chain The chained list of optlist to add to the pdu + * + * @return @c 1 if succesful or @c 0 if failure; + */ +int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t** optlist_chain); + +/** + * Adds @p optlist to the given @p optlist_chain. The optlist_chain variable + * be set to NULL before the initial call to coap_insert_optlist(). + * The optlist_chain will need to be deleted using coap_delete_optlist() + * when no longer required. + * + * @param optlist_chain The chain to add optlist to + * @param optlist The optlist to add to the queue + * + * @return @c 1 if successful, @c 0 otherwise. + */ +int coap_insert_optlist(coap_optlist_t **optlist_chain, + coap_optlist_t *optlist); + +/** + * Removes all entries from the @p optlist_chain, freeing off their + * memory usage. + * + * @param optlist_chain The optlist chain to remove all the entries from + */ +void coap_delete_optlist(coap_optlist_t *optlist_chain); + +#endif /* COAP_OPTION_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/pdu.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/pdu.h new file mode 100644 index 00000000000..206e2643543 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/pdu.h @@ -0,0 +1,543 @@ +/* + * pdu.h -- CoAP message structure + * + * Copyright (C) 2010-2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file pdu.h + * @brief Pre-defined constants that reflect defaults for CoAP + */ + +#ifndef COAP_PDU_H_ +#define COAP_PDU_H_ + +#include "uri.h" + +struct coap_session_t; + +#ifdef WITH_LWIP +#include +#endif + +#include + +#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP/TCP port */ +#define COAPS_DEFAULT_PORT 5684 /* CoAP default UDP/TCP port for secure transmission */ +#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ +#ifndef COAP_DEFAULT_MTU +#define COAP_DEFAULT_MTU 1152 +#endif /* COAP_DEFAULT_MTU */ + +/* TCP Message format constants, do not modify */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP8 13 +#define COAP_MESSAGE_SIZE_OFFSET_TCP16 269 /* 13 + 256 */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP32 65805 /* 269 + 65536 */ + +/* Derived message size limits */ +#define COAP_MAX_MESSAGE_SIZE_TCP0 (COAP_MESSAGE_SIZE_OFFSET_TCP8-1) /* 12 */ +#define COAP_MAX_MESSAGE_SIZE_TCP8 (COAP_MESSAGE_SIZE_OFFSET_TCP16-1) /* 268 */ +#define COAP_MAX_MESSAGE_SIZE_TCP16 (COAP_MESSAGE_SIZE_OFFSET_TCP32-1) /* 65804 */ +#define COAP_MAX_MESSAGE_SIZE_TCP32 (COAP_MESSAGE_SIZE_OFFSET_TCP32+0xFFFFFFFF) + +#ifndef COAP_DEFAULT_MAX_PDU_RX_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4) +#else +/* 8 MiB max-message-size plus some space for options */ +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (8*1024*1024+256) +#endif +#endif /* COAP_DEFAULT_MAX_PDU_RX_SIZE */ + +#ifndef COAP_DEBUG_BUF_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEBUG_BUF_SIZE 128 +#else /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +/* 1024 derived from RFC7252 4.6. Message Size max payload */ +#define COAP_DEBUG_BUF_SIZE (8 + 1024 * 2) +#endif /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +#endif /* COAP_DEBUG_BUF_SIZE */ + +#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ +#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ + +/** well-known resources URI */ +#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" + +/* CoAP message types */ + +#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */ +#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */ +#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */ +#define COAP_MESSAGE_RST 3 /* indicates error in received messages */ + +/* CoAP request methods */ + +#define COAP_REQUEST_GET 1 +#define COAP_REQUEST_POST 2 +#define COAP_REQUEST_PUT 3 +#define COAP_REQUEST_DELETE 4 +#define COAP_REQUEST_FETCH 5 /* RFC 8132 */ +#define COAP_REQUEST_PATCH 6 /* RFC 8132 */ +#define COAP_REQUEST_IPATCH 7 /* RFC 8132 */ + +/* + * CoAP option types (be sure to update coap_option_check_critical() when + * adding options + */ + +#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */ +#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */ +#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */ +#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */ +#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */ +#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */ +#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */ +#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ +#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */ +#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */ +#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */ +#define COAP_OPTION_SIZE2 28 /* E, uint, 0-4 B, (none) */ +#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */ +#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */ + +/* option types from RFC 7641 */ + +#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */ +#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE + +/* selected option types from RFC 7959 */ + +#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */ +#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */ + +/* selected option types from RFC 7967 */ + +#define COAP_OPTION_NORESPONSE 258 /* N, uint, 0--1 B, 0 */ + +#define COAP_MAX_OPT 65535 /**< the highest option number we know */ + +/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */ + +/* As of draft-ietf-core-coap-04, response codes are encoded to base + * 32, i.e. the three upper bits determine the response class while + * the remaining five fine-grained information specific to that class. + */ +#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100) + +/* Determines the class of response code C */ +#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) + +#ifndef SHORT_ERROR_RESPONSE +/** + * Returns a human-readable response phrase for the specified CoAP response @p + * code. This function returns @c NULL if not found. + * + * @param code The response code for which the literal phrase should be + * retrieved. + * + * @return A zero-terminated string describing the error, or @c NULL if not + * found. + */ +const char *coap_response_phrase(unsigned char code); + +#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */ + +#else +#define coap_response_phrase(x) ((char *)NULL) + +#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */ +#endif /* SHORT_ERROR_RESPONSE */ + +/* The following definitions exist for backwards compatibility */ +#if 0 /* this does not exist any more */ +#define COAP_RESPONSE_100 40 /* 100 Continue */ +#endif +#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */ +#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */ +#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */ +#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */ +#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */ +#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */ +#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */ +#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */ +#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */ +#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */ +#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */ +#if 0 /* these response codes do not have a valid code any more */ +# define COAP_RESPONSE_X_240 240 /* Token Option required by server */ +# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */ +#endif +#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */ + +#define COAP_SIGNALING_CODE(N) (((N)/100 << 5) | (N)%100) +#define COAP_SIGNALING_CSM COAP_SIGNALING_CODE(701) +#define COAP_SIGNALING_PING COAP_SIGNALING_CODE(702) +#define COAP_SIGNALING_PONG COAP_SIGNALING_CODE(703) +#define COAP_SIGNALING_RELEASE COAP_SIGNALING_CODE(704) +#define COAP_SIGNALING_ABORT COAP_SIGNALING_CODE(705) + +/* Applies to COAP_SIGNALING_CSM */ +#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE 2 +#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER 4 +/* Applies to COAP_SIGNALING_PING / COAP_SIGNALING_PONG */ +#define COAP_SIGNALING_OPTION_CUSTODY 2 +/* Applies to COAP_SIGNALING_RELEASE */ +#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS 2 +#define COAP_SIGNALING_OPTION_HOLD_OFF 4 +/* Applies to COAP_SIGNALING_ABORT */ +#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION 2 + +/* CoAP media type encoding */ + +#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */ +#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */ +#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */ +#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */ +#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */ +#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */ +#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */ +#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */ + +/* Content formats from RFC 8152 */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN 98 /* application/cose; cose-type="cose-sign" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1 18 /* application/cose; cose-type="cose-sign1" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT 96 /* application/cose; cose-type="cose-encrypt" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0 16 /* application/cose; cose-type="cose-encrypt0" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC 97 /* application/cose; cose-type="cose-mac" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0 17 /* application/cose; cose-type="cose-mac0" */ + +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY 101 /* application/cose-key */ +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET 102 /* application/cose-key-set */ + +/* Content formats from RFC 8428 */ +#define COAP_MEDIATYPE_APPLICATION_SENML_JSON 110 /* application/senml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON 111 /* application/sensml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR 112 /* application/senml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR 113 /* application/sensml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENML_EXI 114 /* application/senml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI 115 /* application/sensml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENML_XML 310 /* application/senml+xml */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_XML 311 /* application/sensml+xml */ + +/* Note that identifiers for registered media types are in the range 0-65535. We + * use an unallocated type here and hope for the best. */ +#define COAP_MEDIATYPE_ANY 0xff /* any media type */ + +/** + * coap_tid_t is used to store CoAP transaction id, i.e. a hash value + * built from the remote transport address and the message id of a + * CoAP PDU. Valid transaction ids are greater or equal zero. + */ +typedef int coap_tid_t; + +/** Indicates an invalid transaction id. */ +#define COAP_INVALID_TID -1 + +/** + * Indicates that a response is suppressed. This will occur for error + * responses if the request was received via IP multicast. + */ +#define COAP_DROPPED_RESPONSE -2 + +#define COAP_PDU_DELAYED -3 + +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list + * in a CoAP message is limited by 0b11110000 + * marker */ + +#define COAP_OPT_END 0xF0 /* end marker */ + +#define COAP_PAYLOAD_START 0xFF /* payload marker */ + +/** + * @deprecated Use coap_optlist_t instead. + * + * Structures for more convenient handling of options. (To be used with ordered + * coap_list_t.) The option's data will be added to the end of the coap_option + * structure (see macro COAP_OPTION_DATA). + */ +COAP_DEPRECATED typedef struct { + uint16_t key; /* the option key (no delta coding) */ + unsigned int length; +} coap_option; + +#define COAP_OPTION_KEY(option) (option).key +#define COAP_OPTION_LENGTH(option) (option).length +#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option)) + +/** + * structure for CoAP PDUs + * token, if any, follows the fixed size header, then options until + * payload marker (0xff), then the payload if stored inline. + * Memory layout is: + * <---header--->|<---token---><---options--->0xff<---payload---> + * header is addressed with a negative offset to token, its maximum size is + * max_hdr_size. + * options starts at token + token_length + * payload starts at data, its length is used_size - (data - token) + */ + +typedef struct coap_pdu_t { + uint8_t type; /**< message type */ + uint8_t code; /**< request method (value 1--10) or response code (value 40-255) */ + uint8_t max_hdr_size; /**< space reserved for protocol-specific header */ + uint8_t hdr_size; /**< actaul size used for protocol-specific header */ + uint8_t token_length; /**< length of Token */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + uint16_t max_delta; /**< highest option number */ + size_t alloc_size; /**< allocated storage for token, options and payload */ + size_t used_size; /**< used bytes of storage for token, options and payload */ + size_t max_size; /**< maximum size for token, options and payload, or zero for variable size pdu */ + uint8_t *token; /**< first byte of token, if any, or options */ + uint8_t *data; /**< first byte of payload, if any */ +#ifdef WITH_LWIP + struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside + * inside the pbuf's payload, but this pointer + * has to be kept because no exact offset can be + * given. This field must not be accessed from + * outside, because the pbuf's reference count + * is checked to be 1 when the pbuf is assigned + * to the pdu, and the pbuf stays exclusive to + * this pdu. */ +#endif +} coap_pdu_t; + +#define COAP_PDU_IS_EMPTY(pdu) ((pdu)->code == 0) +#define COAP_PDU_IS_REQUEST(pdu) (!COAP_PDU_IS_EMPTY(pdu) && (pdu)->code < 32) +#define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 224) +#define COAP_PDU_IS_SIGNALING(pdu) ((pdu)->code >= 224) + +#define COAP_PDU_MAX_UDP_HEADER_SIZE 4 +#define COAP_PDU_MAX_TCP_HEADER_SIZE 6 + +#ifdef WITH_LWIP +/** + * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this + * function. + * + * The pbuf is checked for being contiguous, and for having only one reference. + * The reference is stored in the PDU and will be freed when the PDU is freed. + * + * (For now, these are fatal errors; in future, a new pbuf might be allocated, + * the data copied and the passed pbuf freed). + * + * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards + * copying the contents of the pbuf to the pdu. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); +#endif + +typedef uint8_t coap_proto_t; +/** +* coap_proto_t values +*/ +#define COAP_PROTO_NONE 0 +#define COAP_PROTO_UDP 1 +#define COAP_PROTO_DTLS 2 +#define COAP_PROTO_TCP 3 +#define COAP_PROTO_TLS 4 + +/** + * Creates a new CoAP PDU with at least enough storage space for the given + * @p size maximum message size. The function returns a pointer to the + * node coap_pdu_t object on success, or @c NULL on error. The storage allocated + * for the result must be released with coap_delete_pdu() if coap_send() is not + * called. + * + * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON, + * COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * @param code The message code. + * @param tid The transcation id to set or 0 if unknown / not applicable. + * @param size The maximum allowed number of byte for the message. + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * +coap_pdu_init(uint8_t type, uint8_t code, uint16_t tid, size_t size); + +/** + * Dynamically grows the size of @p pdu to @p new_size. The new size + * must not exceed the PDU's configure maximum size. On success, this + * function returns 1, otherwise 0. + * + * @param pdu The PDU to resize. + * @param new_size The new size in bytes. + * @return 1 if the operation succeeded, 0 otherwise. + */ +int coap_pdu_resize(coap_pdu_t *pdu, size_t new_size); + +/** + * Clears any contents from @p pdu and resets @c used_size, + * and @c data pointers. @c max_size is set to @p size, any + * other field is set to @c 0. Note that @p pdu must be a valid + * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). + */ +void coap_pdu_clear(coap_pdu_t *pdu, size_t size); + +/** + * Creates a new CoAP PDU. + */ +coap_pdu_t *coap_new_pdu(const struct coap_session_t *session); + +/** + * Dispose of an CoAP PDU and frees associated storage. + * Not that in general you should not call this function directly. + * When a PDU is sent with coap_send(), coap_delete_pdu() will be + * called automatically for you. + */ + +void coap_delete_pdu(coap_pdu_t *); + +/** +* Interprets @p data to determine the number of bytes in the header. +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The first byte of raw data to parse as CoAP PDU. +* +* @return A value greater than zero on success or @c 0 on error. +*/ +size_t coap_pdu_parse_header_size(coap_proto_t proto, + const uint8_t *data); + +/** + * Parses @p data to extract the message size. + * @p length must be at least coap_pdu_parse_header_size(proto, data). + * This function returns @c 0 on error or a number greater than zero on success. + * + * @param proto Session's protocol + * @param data The raw data to parse as CoAP PDU. + * @param length The actual size of @p data. + * + * @return A value greater than zero on success or @c 0 on error. + */ +size_t coap_pdu_parse_size(coap_proto_t proto, + const uint8_t *data, + size_t length); + +/** + * Decode the protocol specific header for the specified PDU. + * @param pdu A newly received PDU. + * @param proto The target wire protocol. + * @return 1 for success or 0 on error. + */ + +int coap_pdu_parse_header(coap_pdu_t *pdu, coap_proto_t proto); + +/** + * Verify consistency in the given CoAP PDU structure and locate the data. + * This function returns @c 0 on error or a number greater than zero on + * success. + * This function only parses the token and options, up to the payload start + * marker. + * + * @param pdu The PDU structure to. + * + * @return 1 on success or @c 0 on error. + */ +int coap_pdu_parse_opt(coap_pdu_t *pdu); + +/** +* Parses @p data into the CoAP PDU structure given in @p result. +* The target pdu must be large enough to +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The raw data to parse as CoAP PDU. +* @param length The actual size of @p data. +* @param pdu The PDU structure to fill. Note that the structure must +* provide space to hold at least the token and options +* part of the message. +* +* @return 1 on success or @c 0 on error. +*/ +int coap_pdu_parse(coap_proto_t proto, + const uint8_t *data, + size_t length, + coap_pdu_t *pdu); +/** + * Adds token of length @p len to @p pdu. + * Adding the token destroys any following contents of the pdu. Hence options + * and data must be added after coap_add_token() has been called. In @p pdu, + * length is set to @p len + @c 4, and max_delta is set to @c 0. This function + * returns @c 0 on error or a value greater than zero on success. + * + * @param pdu The PDU where the token is to be added. + * @param len The length of the new token. + * @param data The token to add. + * + * @return A value greater than zero on success, or @c 0 on error. + */ +int coap_add_token(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first + * parameter. + * coap_add_option() destroys the PDU's data, so coap_add_data() must be called + * after all options have been added. As coap_add_token() destroys the options + * following the token, the token must be added before coap_add_option() is + * called. This function returns the number of bytes written or @c 0 on error. + */ +size_t coap_add_option(coap_pdu_t *pdu, + uint16_t type, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first parameter, but does + * not write a value. It works like coap_add_option with respect to calling + * sequence (i.e. after token and before data). This function returns a memory + * address to which the option data has to be written before the PDU can be + * sent, or @c NULL on error. + */ +uint8_t *coap_add_option_later(coap_pdu_t *pdu, + uint16_t type, + size_t len); + +/** + * Adds given data to the pdu that is passed as first parameter. Note that the + * PDU's data is destroyed by coap_add_option(). coap_add_data() must be called + * only once per PDU, otherwise the result is undefined. + */ +int coap_add_data(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds given data to the pdu that is passed as first parameter but does not + * copyt it. Note that the PDU's data is destroyed by coap_add_option(). + * coap_add_data() must be have been called once for this PDU, otherwise the + * result is undefined. + * The actual data must be copied at the returned location. + */ +uint8_t *coap_add_data_after(coap_pdu_t *pdu, size_t len); + +/** + * Retrieves the length and data pointer of specified PDU. Returns 0 on error or + * 1 if *len and *data have correct values. Note that these values are destroyed + * with the pdu. + */ +int coap_get_data(const coap_pdu_t *pdu, + size_t *len, + uint8_t **data); + +/** + * Compose the protocol specific header for the specified PDU. + * @param pdu A newly composed PDU. + * @param proto The target wire protocol. + * @return Number of header bytes prepended before pdu->token or 0 on error. + */ + +size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto); + +#endif /* COAP_PDU_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/prng.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/prng.h new file mode 100644 index 00000000000..c9510bf5602 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/prng.h @@ -0,0 +1,127 @@ +/* + * prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef COAP_PRNG_H_ +#define COAP_PRNG_H_ + +/** + * @defgroup prng Pseudo Random Numbers + * API functions for gerating pseudo random numbers + * @{ + */ + +#if defined(WITH_CONTIKI) +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +contiki_prng_impl(unsigned char *buf, size_t len) { + uint16_t v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) contiki_prng_impl((Buf), (Length)) +#define prng_init(Value) random_init((uint16_t)(Value)) +#elif defined(WITH_LWIP) && defined(LWIP_RAND) +COAP_STATIC_INLINE int +lwip_prng_impl(unsigned char *buf, size_t len) { + u32_t v = LWIP_RAND(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = LWIP_RAND(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) lwip_prng_impl((Buf), (Length)) +#define prng_init(Value) +#elif defined(_WIN32) +#define prng_init(Value) +errno_t __cdecl rand_s( _Out_ unsigned int* _RandomValue ); + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len != 0 ) { + uint32_t r = 0; + size_t i; + if ( rand_s( &r ) != 0 ) + return 0; + for ( i = 0; i < len && i < 4; i++ ) { + *buf++ = (uint8_t)r; + r >>= 8; + } + len -= i; + } + return 1; +} + +#else +#include + + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len-- ) + *buf++ = rand() & 0xFF; + return 1; +} +#endif + + +#ifndef prng +/** + * Fills \p Buf with \p Length bytes of random data. + * + * @hideinitializer + */ +#define prng(Buf,Length) coap_prng_impl((Buf), (Length)) +#endif + +#ifndef prng_init +/** + * Called to set the PRNG seed. You may want to re-define this to allow for a + * better PRNG. + * + * @hideinitializer + */ +#define prng_init(Value) srand((unsigned long)(Value)) +#endif + +/** @} */ + +#endif /* COAP_PRNG_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/resource.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/resource.h new file mode 100644 index 00000000000..58018720e4e --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/resource.h @@ -0,0 +1,524 @@ +/* + * resource.h -- generic resource handling + * + * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file resource.h + * @brief Generic resource handling + */ + +#ifndef COAP_RESOURCE_H_ +#define COAP_RESOURCE_H_ + +# include + +#ifndef COAP_RESOURCE_CHECK_TIME +/** The interval in seconds to check if resources have changed. */ +#define COAP_RESOURCE_CHECK_TIME 2 +#endif /* COAP_RESOURCE_CHECK_TIME */ + +#include "uthash.h" +#include "async.h" +#include "str.h" +#include "pdu.h" +#include "net.h" +#include "subscribe.h" + +/** + * Definition of message handler function (@sa coap_resource_t). + */ +typedef void (*coap_method_handler_t) + (coap_context_t *, + struct coap_resource_t *, + coap_session_t *, + coap_pdu_t *, + coap_binary_t * /* token */, + coap_string_t * /* query string */, + coap_pdu_t * /* response */); + +#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1 +#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2 + +typedef struct coap_attr_t { + struct coap_attr_t *next; + coap_str_const_t *name; + coap_str_const_t *value; + int flags; +} coap_attr_t; + +/** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ +#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1 + +/** + * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0 + +/** + * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2 + +typedef struct coap_resource_t { + unsigned int dirty:1; /**< set to 1 if resource has changed */ + unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet + * been notified of the last change */ + unsigned int observable:1; /**< can be observed */ + unsigned int cacheable:1; /**< can be cached */ + unsigned int is_unknown:1; /**< resource created for unknown handler */ + + /** + * Used to store handlers for the seven coap methods @c GET, @c POST, @c PUT, + * @c DELETE, @c FETCH, @c PATCH and @c IPATCH. + * coap_dispatch() will pass incoming requests to the handler + * that corresponds to its request method or generate a 4.05 response if no + * handler is available. + */ + coap_method_handler_t handler[7]; + + UT_hash_handle hh; + + coap_attr_t *link_attr; /**< attributes to be included with the link format */ + coap_subscription_t *subscribers; /**< list of observers for this resource */ + + /** + * Request URI Path for this resource. This field will point into static + * or allocated memory which must remain there for the duration of the + * resource. + */ + coap_str_const_t *uri_path; /**< the key used for hash lookup for this resource */ + int flags; + + /** + * The next value for the Observe option. This field must be increased each + * time the resource changes. Only the lower 24 bits are sent. + */ + unsigned int observe; + + /** + * This pointer is under user control. It can be used to store context for + * the coap handler. + */ + void *user_data; + +} coap_resource_t; + +/** + * Creates a new resource object and initializes the link field to the string + * @p uri_path. This function returns the new coap_resource_t object. + * + * If the string is going to be freed off by coap_delete_resource() when + * COAP_RESOURCE_FLAGS_RELEASE_URI is set in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param uri_path The string URI path of the new resource. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_RESOURCE_FLAGS_RELEASE_URI + * If this flag is set, the URI passed to + * coap_resource_init() is free'd by + * coap_delete_resource()@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_CON + * If this flag is set, coap-observe notifications + * will be sent confirmable by default.@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_NON (default) + * If this flag is set, coap-observe notifications + * will be sent non-confirmable by default.@n + * + * If flags is set to 0 then the + * COAP_RESOURCE_FLAGS_NOTIFY_NON is considered. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, + int flags); + + +/** + * Creates a new resource object for the unknown resource handler with support + * for PUT. + * + * In the same way that additional handlers can be added to the resource + * created by coap_resource_init() by using coap_register_handler(), POST, + * GET, DELETE etc. handlers can be added to this resource. It is the + * responsibility of the application to manage the unknown resources by either + * creating new resources with coap_resource_init() (which should have a + * DELETE handler specified for the resource removal) or by maintaining an + * active resource list. + * + * Note: There can only be one unknown resource handler per context - attaching + * a new one overrides the previous definition. + * + * Note: It is not possible to observe the unknown resource with a GET request + * - a separate resource needs to be reated by the PUT (or POST) handler, + * and make that resource observable. + * + * This function returns the new coap_resource_t object. + * + * @param put_handler The PUT handler to register with @p resource for + * unknown Uri-Path. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_unknown_init(coap_method_handler_t put_handler); + +/** + * Sets the notification message type of resource @p resource to given + * @p mode + + * @param resource The resource to update. + * @param mode Must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON + * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. + */ +COAP_STATIC_INLINE void +coap_resource_set_mode(coap_resource_t *resource, int mode) { + resource->flags = (resource->flags & + ~(COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)) | + (mode & (COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)); +} + +/** + * Sets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to attach the data to + * @param data Data to attach to the user_data field. This pointer is only used for + * storage, the data remains under user control + */ +COAP_STATIC_INLINE void +coap_resource_set_userdata(coap_resource_t *r, void *data) { + r->user_data = data; +} + +/** + * Gets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to retrieve the user_darta from + * + * @return The user_data pointer + */ +COAP_STATIC_INLINE void * +coap_resource_get_userdata(coap_resource_t *r) { + return r->user_data; +} + +/** + * Registers the given @p resource for @p context. The resource must have been + * created by coap_resource_init() or coap_resource_unknown_init(), the + * storage allocated for the resource will be released by coap_delete_resource(). + * + * @param context The context to use. + * @param resource The resource to store. + */ +void coap_add_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes a resource identified by @p resource. The storage allocated for that + * resource is freed, and removed from the context. + * + * @param context The context where the resources are stored. + * @param resource The resource to delete. + * + * @return @c 1 if the resource was found (and destroyed), + * @c 0 otherwise. + */ +int coap_delete_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes all resources from given @p context and frees their storage. + * + * @param context The CoAP context with the resources to be deleted. + */ +void coap_delete_all_resources(coap_context_t *context); + +/** + * Registers a new attribute with the given @p resource. As the + * attribute's coap_str_const_ fields will point to @p name and @p value the + * caller must ensure that these pointers are valid during the + * attribute's lifetime. + + * If the @p name and/or @p value string is going to be freed off at attribute + * removal time by the setting of COAP_ATTR_FLAGS_RELEASE_NAME or + * COAP_ATTR_FLAGS_RELEASE_VALUE in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param resource The resource to register the attribute with. + * @param name The attribute's name as a string. + * @param value The attribute's value as a string or @c NULL if none. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_ATTR_FLAGS_RELEASE_NAME + * If this flag is set, the name passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * COAP_ATTR_FLAGS_RELEASE_VALUE + * If this flag is set, the value passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * @return A pointer to the new attribute or @c NULL on error. + */ +coap_attr_t *coap_add_attr(coap_resource_t *resource, + coap_str_const_t *name, + coap_str_const_t *value, + int flags); + +/** + * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL + * otherwise. + * + * @param resource The resource to search for attribute @p name. + * @param name Name of the requested attribute as a string. + * @return The first attribute with specified @p name or @c NULL if none + * was found. + */ +coap_attr_t *coap_find_attr(coap_resource_t *resource, + coap_str_const_t *name); + +/** + * Deletes an attribute. + * Note: This is for internal use only, as it is not deleted from its chain. + * + * @param attr Pointer to a previously created attribute. + * + */ +void coap_delete_attr(coap_attr_t *attr); + +/** + * Status word to encode the result of conditional print or copy operations such + * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to + * encode the number of characters that has actually been printed, bits 28 to 31 + * encode the status. When COAP_PRINT_STATUS_ERROR is set, an error occurred + * during output. In this case, the other bits are undefined. + * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the + * printing would have exceeded the current buffer. + */ +typedef unsigned int coap_print_status_t; + +#define COAP_PRINT_STATUS_MASK 0xF0000000u +#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK) +#define COAP_PRINT_STATUS_ERROR 0x80000000u +#define COAP_PRINT_STATUS_TRUNC 0x40000000u + +/** + * Writes a description of this resource in link-format to given text buffer. @p + * len must be initialized to the maximum length of @p buf and will be set to + * the number of characters actually written if successful. This function + * returns @c 1 on success or @c 0 on error. + * + * @param resource The resource to describe. + * @param buf The output buffer to write the description to. + * @param len Must be initialized to the length of @p buf and + * will be set to the length of the printed link description. + * @param offset The offset within the resource description where to + * start writing into @p buf. This is useful for dealing + * with the Block2 option. @p offset is updated during + * output as it is consumed. + * + * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, + * the lower 28 bits will indicate the number of characters that + * have actually been output into @p buffer. The flag + * COAP_PRINT_STATUS_TRUNC indicates that the output has been + * truncated. + */ +coap_print_status_t coap_print_link(const coap_resource_t *resource, + unsigned char *buf, + size_t *len, + size_t *offset); + +/** + * Registers the specified @p handler as message handler for the request type @p + * method + * + * @param resource The resource for which the handler shall be registered. + * @param method The CoAP request method to handle. + * @param handler The handler to register with @p resource. + */ +void coap_register_handler(coap_resource_t *resource, + unsigned char method, + coap_method_handler_t handler); + +/** + * Returns the resource identified by the unique string @p uri_path. If no + * resource was found, this function returns @c NULL. + * + * @param context The context to look for this resource. + * @param uri_path The unique string uri of the resource. + * + * @return A pointer to the resource or @c NULL if not found. + */ +coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context, + coap_str_const_t *uri_path); + +/** + * @addtogroup observe + */ + +/** + * Adds the specified peer as observer for @p resource. The subscription is + * identified by the given @p token. This function returns the registered + * subscription information if the @p observer has been added, or @c NULL on + * error. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription. + * @param query The query string, if any. subscription will + take ownership of the string. + * @param has_block2 If Option Block2 defined. + * @param block2 Contents of Block2 if Block 2 defined. + * @return A pointer to the added/updated subscription + * information or @c NULL on error. + */ +coap_subscription_t *coap_add_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token, + coap_string_t *query, + int has_block2, + coap_block_t block2); + +/** + * Returns a subscription object for given @p peer. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return A valid subscription if exists or @c NULL otherwise. + */ +coap_subscription_t *coap_find_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Marks an observer as alive. + * + * @param context The CoAP context to use. + * @param session The observer's session + * @param token The corresponding token that has been used for the + * subscription. + */ +void coap_touch_observer(coap_context_t *context, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p observer from @p resource and releases the + * allocated storage. The result is @c 1 if an observation relationship with @p + * observer and @p token existed, @c 0 otherwise. + * + * @param resource The observed resource. + * @param session The observer's session. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return @c 1 if the observer has been deleted, @c 0 otherwise. + */ +int coap_delete_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p session and releases the allocated storage. + * + * @param context The CoAP context to use. + * @param session The observer's session. + */ +void coap_delete_observers(coap_context_t *context, coap_session_t *session); + +/** + * Checks for all known resources, if they are dirty and notifies subscribed + * observers. + */ +void coap_check_notify(coap_context_t *context); + +#define RESOURCES_ADD(r, obj) \ + HASH_ADD(hh, (r), uri_path->s[0], (obj)->uri_path->length, (obj)) + +#define RESOURCES_DELETE(r, obj) \ + HASH_DELETE(hh, (r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp, *rtmp; \ + HASH_ITER(hh, (r), tmp, rtmp) + +#define RESOURCES_FIND(r, k, res) { \ + HASH_FIND(hh, (r), (k)->s, (k)->length, (res)); \ + } + +/** @} */ + +coap_print_status_t coap_print_wellknown(coap_context_t *, + unsigned char *, + size_t *, size_t, + coap_opt_t *); + +void +coap_handle_failed_notify(coap_context_t *, + coap_session_t *, + const coap_binary_t *); + +/** + * Set whether a @p resource is observable. If the resource is observable + * and the client has set the COAP_OPTION_OBSERVE in a request packet, then + * whenever the state of the resource changes (a call to + * coap_resource_trigger_observe()), an Observer response will get sent. + * + * @param resource The CoAP resource to use. + * @param mode @c 1 if Observable is to be set, @c 0 otherwise. + * + */ +COAP_STATIC_INLINE void +coap_resource_set_get_observable(coap_resource_t *resource, int mode) { + resource->observable = mode ? 1 : 0; +} + +/** + * Initiate the sending of an Observe packet for all observers of @p resource, + * optionally matching @p query if not NULL + * + * @param resource The CoAP resource to use. + * @param query The Query to match against or NULL + * + * @return @c 1 if the Observe has been triggered, @c 0 otherwise. + */ +int +coap_resource_notify_observers(coap_resource_t *resource, + const coap_string_t *query); + +/** + * Get the UriPath from a @p resource. + * + * @param resource The CoAP resource to check. + * + * @return The UriPath if it exists or @c NULL otherwise. + */ +COAP_STATIC_INLINE coap_str_const_t* +coap_resource_get_uri_path(coap_resource_t *resource) { + if (resource) + return resource->uri_path; + return NULL; +} + +/** + * @deprecated use coap_resource_notify_observers() instead. + */ +COAP_DEPRECATED int +coap_resource_set_dirty(coap_resource_t *r, + const coap_string_t *query); + +#endif /* COAP_RESOURCE_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/str.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/str.h new file mode 100644 index 00000000000..6c1488c982d --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/str.h @@ -0,0 +1,121 @@ +/* + * str.h -- strings to be used in the CoAP library + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_STR_H_ +#define COAP_STR_H_ + +#include + + +/** + * @defgroup string String handling support + * API functions for handling strings + * @{ + */ + +/** + * Coap string data definition + */ +typedef struct coap_string_t { + size_t length; /**< length of string */ + uint8_t *s; /**< string data */ +} coap_string_t; + +/** + * Coap string data definition with const data + */ +typedef struct coap_str_const_t { + size_t length; /**< length of string */ + const uint8_t *s; /**< string data */ +} coap_str_const_t; + +#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); } + +/** + * Coap binary data definition + */ +typedef struct coap_binary_t { + size_t length; /**< length of binary data */ + uint8_t *s; /**< binary data */ +} coap_binary_t; + +/** + * Returns a new string object with at least size+1 bytes storage allocated. + * The string must be released using coap_delete_string(). + * + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_string_t *coap_new_string(size_t size); + +/** + * Deletes the given string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_string(coap_string_t *string); + +/** + * Returns a new const string object with at least size+1 bytes storage + * allocated, and the provided data copied into the string object. + * The string must be released using coap_delete_str_const(). + * + * @param data The data to put in the new string object. + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_str_const_t *coap_new_str_const(const uint8_t *data, size_t size); + +/** + * Deletes the given const string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_str_const(coap_str_const_t *string); + +/** + * Take the specified byte array (text) and create a coap_str_const_t * + * + * WARNING: The byte array must be in the local scope and not a + * parameter in the function call as sizeof() will return the size of the + * pointer, not the size of the byte array, leading to unxepected results. + * + * @param string The const byte array to convert to a coap_str_const_t * + */ +#ifdef __cplusplus +namespace libcoap { + struct CoAPStrConst : coap_str_const_t { + operator coap_str_const_t *() { return this; } + }; +} +#define coap_make_str_const(CStr) \ + libcoap::CoAPStrConst{sizeof(CStr)-1, reinterpret_cast(CStr)} +#else /* __cplusplus */ +#define coap_make_str_const(string) \ + (&(coap_str_const_t){sizeof(string)-1,(const uint8_t *)(string)}) +#endif /* __cplusplus */ + +/** + * Compares the two strings for equality + * + * @param string1 The first string. + * @param string2 The second string. + * + * @return @c 1 if the strings are equal + * @c 0 otherwise. + */ +#define coap_string_equal(string1,string2) \ + ((string1)->length == (string2)->length && ((string1)->length == 0 || \ + memcmp((string1)->s, (string2)->s, (string1)->length) == 0)) + +/** @} */ + +#endif /* COAP_STR_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/subscribe.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/subscribe.h new file mode 100644 index 00000000000..ed635a6182a --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/subscribe.h @@ -0,0 +1,77 @@ +/* + * subscribe.h -- subscription handling for CoAP + * see RFC7641 + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + + +#ifndef COAP_SUBSCRIBE_H_ +#define COAP_SUBSCRIBE_H_ + +#include "address.h" +#include "coap_io.h" +#include "block.h" + +/** + * @defgroup observe Resource observation + * API functions for interfacing with the observe handling (RFC7641) + * @{ + */ + +/** + * The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe + * relationship for (sender address, token) is requested. + */ +#define COAP_OBSERVE_ESTABLISH 0 + +/** + * The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe + * relationship for (sender address, token) must be cancelled. + */ +#define COAP_OBSERVE_CANCEL 1 + +#ifndef COAP_OBS_MAX_NON +/** + * Number of notifications that may be sent non-confirmable before a confirmable + * message is sent to detect if observers are alive. The maximum allowed value + * here is @c 15. + */ +#define COAP_OBS_MAX_NON 5 +#endif /* COAP_OBS_MAX_NON */ + +#ifndef COAP_OBS_MAX_FAIL +/** + * Number of confirmable notifications that may fail (i.e. time out without + * being ACKed) before an observer is removed. The maximum value for + * COAP_OBS_MAX_FAIL is @c 3. + */ +#define COAP_OBS_MAX_FAIL 3 +#endif /* COAP_OBS_MAX_FAIL */ + +/** Subscriber information */ +typedef struct coap_subscription_t { + struct coap_subscription_t *next; /**< next element in linked list */ + coap_session_t *session; /**< subscriber session */ + + unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */ + unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */ + unsigned int dirty:1; /**< set if the notification temporarily could not be + * sent (in that case, the resource's partially + * dirty flag is set too) */ + unsigned int has_block2:1; /**< GET request had Block2 definition */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + coap_block_t block2; /**< GET request Block2 definition */ + size_t token_length; /**< actual length of token */ + unsigned char token[8]; /**< token used for subscription */ + coap_string_t *query; /**< query string used for subscription, if any */ +} coap_subscription_t; + +void coap_subscription_init(coap_subscription_t *); + +/** @} */ + +#endif /* COAP_SUBSCRIBE_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uri.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uri.h new file mode 100644 index 00000000000..4d1670115eb --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uri.h @@ -0,0 +1,147 @@ +/* + * uri.h -- helper functions for URI treatment + * + * Copyright (C) 2010-2011,2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_URI_H_ +#define COAP_URI_H_ + +#include + +#include "str.h" +struct coap_pdu_t; + +/** + * The scheme specifiers. Secure schemes have an odd numeric value, + * others are even. + */ +enum coap_uri_scheme_t { + COAP_URI_SCHEME_COAP=0, + COAP_URI_SCHEME_COAPS=1, + COAP_URI_SCHEME_COAP_TCP=2, + COAP_URI_SCHEME_COAPS_TCP=3 +}; + +/** This mask can be used to check if a parsed URI scheme is secure. */ +#define COAP_URI_SCHEME_SECURE_MASK 0x01 + +/** + * Representation of parsed URI. Components may be filled from a string with + * coap_split_uri() and can be used as input for option-creation functions. + */ +typedef struct { + coap_str_const_t host; /**< host part of the URI */ + uint16_t port; /**< The port in host byte order */ + coap_str_const_t path; /**< Beginning of the first path segment. + Use coap_split_path() to create Uri-Path options */ + coap_str_const_t query; /**< The query part if present */ + + /** The parsed scheme specifier. */ + enum coap_uri_scheme_t scheme; +} coap_uri_t; + +static inline int +coap_uri_scheme_is_secure(const coap_uri_t *uri) { + return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0); +} + +/** + * Creates a new coap_uri_t object from the specified URI. Returns the new + * object or NULL on error. The memory allocated by the new coap_uri_t + * must be released using coap_free(). + * + * @param uri The URI path to copy. + * @param length The length of uri. + * + * @return New URI object or NULL on error. + */ +coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length); + +/** + * Clones the specified coap_uri_t object. Thie function allocates sufficient + * memory to hold the coap_uri_t structure and its contents. The object must + * be released with coap_free(). */ +coap_uri_t *coap_clone_uri(const coap_uri_t *uri); + +/** + * @defgroup uri_parse URI Parsing Functions + * + * CoAP PDUs contain normalized URIs with their path and query split into + * multiple segments. The functions in this module help splitting strings. + * @{ + */ + +/** + * Parses a given string into URI components. The identified syntactic + * components are stored in the result parameter @p uri. Optional URI + * components that are not specified will be set to { 0, 0 }, except for the + * port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if + * parsing succeeded, a value less than zero otherwise. + * + * @param str_var The string to split up. + * @param len The actual length of @p str_var + * @param uri The coap_uri_t object to store the result. + * @return @c 0 on success, or < 0 on error. + * + */ +int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); + +/** + * Splits the given URI path into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective segment after percent-decoding. + * + * @param s The path string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + */ +int coap_split_path(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Splits the given URI query into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective query term. + * + * @param s The query string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + * + * @bug This function does not reserve additional space for delta > 12. + */ +int coap_split_query(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Extract query string from request PDU according to escape rules in 6.5.8. + * @param request Request PDU. + * @return Reconstructed and escaped query string part. + */ +coap_string_t *coap_get_query(const struct coap_pdu_t *request); + +/** + * Extract uri_path string from request PDU + * @param request Request PDU. + * @return Reconstructed and escaped uri path string part. + */ +coap_string_t *coap_get_uri_path(const struct coap_pdu_t *request); + +/** @} */ + +#endif /* COAP_URI_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uthash.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uthash.h new file mode 100644 index 00000000000..156eb8210c1 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/uthash.h @@ -0,0 +1,1108 @@ +/* +Copyright (c) 2003-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.0.2 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_memcmp +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + if (!(head)->hh.tbl->buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (const void *) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE"); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + default: ; /* does not happen */ \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch ((keylen) & 3U) { \ + case 0: break; \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / (tbl)->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], _dst_hh); \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + const void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/utlist.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/utlist.h new file mode 100644 index 00000000000..2f4c08406f4 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap2/utlist.h @@ -0,0 +1,1073 @@ +/* +Copyright (c) 2007-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 2.0.2 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define IF_NO_DECLTYPE(x) x +#define LDECLTYPE(x) char* +#define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) +#define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define UTLIST_PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define IF_NO_DECLTYPE(x) +#define UTLIST_SV(elt,list) +#define UTLIST_NEXT(elt,list,next) ((elt)->next) +#define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define UTLIST_PREV(elt,list,prev) ((elt)->prev) */ +#define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define UTLIST_RS(list) +#define UTLIST_CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if ((_ls_qsize == 0) || (!_ls_q)) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev, _ls_tail); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + UTLIST_CASTASGN(_ls_oldhead,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); \ + if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = UTLIST_NEXT(_ls_q,list,next); \ + } \ + UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev,_ls_tail); \ + UTLIST_CASTASGN(_tmp,list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = (head); \ + (head) = (add); \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = (head1); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = (head); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_INSERT_INORDER(head,add,cmp) \ + LL_INSERT_INORDER2(head,add,cmp,next) + +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + LL_LOWER_BOUND(head, _tmp, add, cmp); \ + LL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define LL_LOWER_BOUND(head,elt,like,cmp) \ + LL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ + do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if (cmp((elt)->next, like) >= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (del)->next; \ + } \ + } \ +} while (0) + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + LL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_REPLACE_ELEM(head, el, add) \ + LL_REPLACE_ELEM2(head, el, add, next) + +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_PREPEND_ELEM(head, el, add) \ + LL_PREPEND_ELEM2(head, el, add, next) + +#define LL_APPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (el)->next = (add); \ + } else { \ + LL_PREPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_APPEND_ELEM(head, el, add) \ + LL_APPEND_ELEM2(head, el, add, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef LL_CONCAT2 +#define LL_CONCAT2(head1,head2,next) \ +do { \ + char *_tmp; \ + if (head1) { \ + _tmp = (char*)(head1); \ + while ((head1)->next) { (head1) = (head1)->next; } \ + (head1)->next = (head2); \ + UTLIST_RS(head1); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#undef LL_APPEND2 +#define LL_APPEND2(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#undef LL_INSERT_INORDER2 +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, add)) >= 0) { \ + (add)->next = (head); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_DELETE2 +#define LL_DELETE2(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + (head) = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_REPLACE_ELEM2 +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = head; \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el)->next; \ +} while (0) + +#undef LL_PREPEND_ELEM2 +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = (head); \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el); \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = (head); \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_INSERT_INORDER(head,add,cmp) \ + DL_INSERT_INORDER2(head,add,cmp,next) + +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + DL_LOWER_BOUND(head, _tmp, add, cmp); \ + DL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_LOWER_BOUND(head,elt,like,cmp) \ + DL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + UTLIST_CASTASGN(_tmp, (head2)->prev); \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + UTLIST_CASTASGN((head1)->prev, _tmp); \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((head) != NULL); \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + DL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_REPLACE_ELEM(head, el, add) \ + DL_REPLACE_ELEM2(head, el, add, prev, next) + +#define DL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ + } else { \ + DL_APPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_PREPEND_ELEM(head, el, add) \ + DL_PREPEND_ELEM2(head, el, add, prev, next) + +#define DL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } else { \ + DL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_APPEND_ELEM(head, el, add) \ + DL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef DL_INSERT_INORDER2 +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = NULL; \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_APPEND(head,add) \ + CDL_APPEND2(head,add,prev,next) + +#define CDL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } \ +} while (0) + +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define CDL_INSERT_INORDER(head,add,cmp) \ + CDL_INSERT_INORDER2(head,add,cmp,next) + +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + CDL_LOWER_BOUND(head, _tmp, add, cmp); \ + CDL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = (head); \ + (head)->prev = (head); \ + } \ +} while (0) + +#define CDL_LOWER_BOUND(head,elt,like,cmp) \ + CDL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if (((head)==(del)) && ((head)->next == (head))) { \ + (head) = NULL; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +do { \ + (counter) = 0; \ + CDL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ + (el) && ((tmp2) = (el)->next, 1); \ + (el) = ((el) == (tmp1) ? NULL : (tmp2))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM(head, el, add) \ + CDL_REPLACE_ELEM2(head, el, add, prev, next) + +#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } else { \ + CDL_APPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ + CDL_PREPEND_ELEM2(head, el, add, prev, next) + +#define CDL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + (add)->next->prev = (add); \ + } else { \ + CDL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_APPEND_ELEM(head, el, add) \ + CDL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef CDL_INSERT_INORDER2 +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (add)->prev->next = (add); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (add)->next->prev = (add); \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +#endif /* UTLIST_H */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_block_internal.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_block_internal.h index 9abe81557fa..b7ad0a554cc 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_block_internal.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_block_internal.h @@ -191,6 +191,9 @@ int coap_handle_response_get_block(coap_context_t *context, void coap_block_delete_lg_xmit(coap_session_t *session, coap_lg_xmit_t *lg_xmit); +coap_tick_t coap_block_check_lg_xmit_timeouts(coap_session_t *session, + coap_tick_t now); + /** * The function that does all the work for the coap_add_data_large*() * functions. diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_dtls.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_dtls.h index cbd369dfce6..fc30445431d 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_dtls.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_dtls.h @@ -27,6 +27,12 @@ typedef struct coap_dtls_pki_t coap_dtls_pki_t; #ifndef COAP_DTLS_HINT_LENGTH #define COAP_DTLS_HINT_LENGTH 128 #endif +#ifndef COAP_DTLS_MAX_PSK_IDENTITY +#define COAP_DTLS_MAX_PSK_IDENTITY 64 +#endif +#ifndef COAP_DTLS_MAX_PSK +#define COAP_DTLS_MAX_PSK 64 +#endif typedef enum coap_dtls_role_t { COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_event.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_event.h index 89b2a63967c..b6ea60524a2 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_event.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_event.h @@ -24,34 +24,34 @@ * Scalar type to represent different events, e.g. DTLS events or * retransmission timeouts. */ - typedef unsigned int coap_event_t; - +typedef enum coap_event_t { /** * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS */ -#define COAP_EVENT_DTLS_CLOSED 0x0000 -#define COAP_EVENT_DTLS_CONNECTED 0x01DE -#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF -#define COAP_EVENT_DTLS_ERROR 0x0200 + COAP_EVENT_DTLS_CLOSED = 0x0000, + COAP_EVENT_DTLS_CONNECTED = 0x01DE, + COAP_EVENT_DTLS_RENEGOTIATE = 0x01DF, + COAP_EVENT_DTLS_ERROR = 0x0200, /** * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS */ -#define COAP_EVENT_TCP_CONNECTED 0x1001 -#define COAP_EVENT_TCP_CLOSED 0x1002 -#define COAP_EVENT_TCP_FAILED 0x1003 + COAP_EVENT_TCP_CONNECTED = 0x1001, + COAP_EVENT_TCP_CLOSED = 0x1002, + COAP_EVENT_TCP_FAILED = 0x1003, /** * CSM exchange events for reliable protocols only */ -#define COAP_EVENT_SESSION_CONNECTED 0x2001 -#define COAP_EVENT_SESSION_CLOSED 0x2002 -#define COAP_EVENT_SESSION_FAILED 0x2003 + COAP_EVENT_SESSION_CONNECTED = 0x2001, + COAP_EVENT_SESSION_CLOSED = 0x2002, + COAP_EVENT_SESSION_FAILED = 0x2003, /** - * BLOCK2 receive errors + * (Q-)BLOCK receive errors */ -#define COAP_EVENT_PARTIAL_BLOCK 0x3001 + COAP_EVENT_PARTIAL_BLOCK = 0x3001 +} coap_event_t; /** * Type for event handler functions that can be registered with a CoAP diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_time.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_time.h index baa8650eaff..99d117a4eb7 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_time.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/coap_time.h @@ -88,7 +88,11 @@ COAP_STATIC_INLINE uint64_t coap_ticks_to_rt_us(coap_tick_t t) { #elif defined(RIOT_VERSION) #include +#ifdef XTIMER_HZ #define COAP_TICKS_PER_SECOND (XTIMER_HZ) +#else /* XTIMER_HZ */ +#define COAP_TICKS_PER_SECOND (XTIMER_HZ_BASE) +#endif /* XTIMER_HZ */ typedef uint64_t coap_tick_t; typedef int64_t coap_tick_diff_t; diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/net.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/net.h index 577a0b5d5a5..ea5a2cba1bb 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/net.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/net.h @@ -15,6 +15,7 @@ #include #include #ifndef _WIN32 +#include #include #endif #include diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/pdu.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/pdu.h index a22869b69ed..8031a1c2c40 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/pdu.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/pdu.h @@ -299,7 +299,6 @@ typedef enum coap_pdu_code_t { COAP_REQUEST_CODE_PATCH = COAP_REQUEST_PATCH, COAP_REQUEST_CODE_IPATCH = COAP_REQUEST_IPATCH, - COAP_RESPONSE_CODE_OK = COAP_RESPONSE_CODE(200), COAP_RESPONSE_CODE_CREATED = COAP_RESPONSE_CODE(201), COAP_RESPONSE_CODE_DELETED = COAP_RESPONSE_CODE(202), COAP_RESPONSE_CODE_VALID = COAP_RESPONSE_CODE(203), diff --git a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/resource.h b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/resource.h index 2cd9aea48fa..5cf7751f67e 100644 --- a/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/resource.h +++ b/tools/sdk/esp32c3/include/coap/libcoap/include/coap3/resource.h @@ -83,7 +83,8 @@ typedef void (*coap_method_handler_t) * variable of coap_str_const_t has to point to constant text, or point to data * within the allocated coap_str_const_t parameter. * - * @param uri_path The string URI path of the new resource. + * @param uri_path The string URI path of the new resource. The leading '/' is + * not normally required - e.g. just "full/path/for/resource". * @param flags Flags for memory management (in particular release of * memory). Possible values:@n * diff --git a/tools/sdk/esp32c3/include/coap/port/include/coap/coap.h b/tools/sdk/esp32c3/include/coap/port/include/coap/coap.h new file mode 100644 index 00000000000..f048ca85714 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/port/include/coap/coap.h @@ -0,0 +1,50 @@ +/* Modify head file implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * define operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_H_ +#define _COAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libcoap.h" + +#include "address.h" +#include "async.h" +#include "bits.h" +#include "block.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_io.h" +#include "coap_time.h" +#include "coap_debug.h" +#include "encode.h" +#include "mem.h" +#include "net.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "resource.h" +#include "str.h" +#include "subscribe.h" +#include "uri.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COAP_H_ */ diff --git a/tools/sdk/esp32c3/include/coap/port/include/coap/coap_dtls.h b/tools/sdk/esp32c3/include/coap/port/include/coap/coap_dtls.h new file mode 100644 index 00000000000..2dd0e88d2e5 --- /dev/null +++ b/tools/sdk/esp32c3/include/coap/port/include/coap/coap_dtls.h @@ -0,0 +1,631 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" +#include "str.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +typedef enum coap_tls_library_t { + COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */ + COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */ + COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */ + COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */ + COAP_TLS_LIBRARY_MBEDTLS, /**< Using MbedTLS library */ +} coap_tls_library_t; + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ + COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI PEM buffer definitions. + */ +typedef struct coap_pki_key_pem_buf_t { + const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */ + const uint8_t *public_cert; /**< PEM buffer Public Cert */ + const uint8_t *private_key; /**< PEM buffer Private Key */ + size_t ca_cert_len; /**< PEM buffer CA Cert length */ + size_t public_cert_len; /**< PEM buffer Public Cert length */ + size_t private_key_len; /**< PEM buffer Private Key length */ +} coap_pki_key_pem_buf_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM file keys */ + coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) file keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t allow_bad_md_hash; /**< 1 if expired certs are allowed */ + uint8_t allow_short_rsa_length; /**< 1 if expired certs are allowed */ + uint8_t reserved[4]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 4 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32c3/include/config/sdkconfig.h b/tools/sdk/esp32c3/include/config/sdkconfig.h index f1f31fdfd3b..3b4c686e319 100644 --- a/tools/sdk/esp32c3/include/config/sdkconfig.h +++ b/tools/sdk/esp32c3/include/config/sdkconfig.h @@ -29,6 +29,7 @@ #define CONFIG_BOOT_ROM_LOG_ALWAYS_ON 1 #define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 #define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1 +#define CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR 1 #define CONFIG_ESPTOOLPY_FLASHMODE "dio" #define CONFIG_ESPTOOLPY_FLASHFREQ_80M 1 #define CONFIG_ESPTOOLPY_FLASHFREQ "80m" @@ -61,7 +62,7 @@ #define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL 1 #define CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT 1 #define CONFIG_ARDUHAL_PARTITION_SCHEME "default" -#define CONFIG_COMPILER_OPTIMIZATION_DEFAULT 1 +#define CONFIG_COMPILER_OPTIMIZATION_SIZE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL 2 #define CONFIG_COMPILER_HIDE_PATHS_MACROS 1 @@ -314,7 +315,6 @@ #define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 #define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 #define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 -#define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1 #define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1 #define CONFIG_FREERTOS_DEBUG_OCDAWARE 1 #define CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT 1 @@ -330,7 +330,7 @@ #define CONFIG_LWIP_LOCAL_HOSTNAME "espressif" #define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1 #define CONFIG_LWIP_TIMERS_ONDEMAND 1 -#define CONFIG_LWIP_MAX_SOCKETS 10 +#define CONFIG_LWIP_MAX_SOCKETS 16 #define CONFIG_LWIP_SO_REUSE 1 #define CONFIG_LWIP_SO_REUSE_RXTOALL 1 #define CONFIG_LWIP_SO_RCVBUF 1 @@ -340,6 +340,7 @@ #define CONFIG_LWIP_GARP_TMR_INTERVAL 60 #define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 #define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1 +#define CONFIG_LWIP_DHCP_OPTIONS_LEN 68 #define CONFIG_LWIP_DHCPS 1 #define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 #define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 @@ -450,6 +451,7 @@ #define CONFIG_MDNS_TASK_AFFINITY 0x0 #define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 2000 #define CONFIG_MDNS_TIMER_PERIOD_MS 100 +#define CONFIG_MDNS_MULTIPLE_INSTANCE 1 #define CONFIG_MQTT_PROTOCOL_311 1 #define CONFIG_MQTT_TRANSPORT_SSL 1 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 @@ -530,7 +532,7 @@ #define CONFIG_BTIF_TRACE_LEVEL_WARNING CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING #define CONFIG_BTM_TRACE_LEVEL_WARNING CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING #define CONFIG_BTU_TASK_STACK_SIZE CONFIG_BT_BTU_TASK_STACK_SIZE -#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT +#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT #define CONFIG_ESP32C3_MEMPROT_FEATURE CONFIG_ESP_SYSTEM_MEMPROT_FEATURE #define CONFIG_ESP32C3_MEMPROT_FEATURE_LOCK CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK @@ -584,7 +586,7 @@ #define CONFIG_MCA_TRACE_LEVEL_WARNING CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING #define CONFIG_MONITOR_BAUD_115200B CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B #define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE -#define CONFIG_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT +#define CONFIG_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_OSI_TRACE_LEVEL_WARNING CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING #define CONFIG_PAN_TRACE_LEVEL_WARNING CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING #define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR @@ -622,5 +624,5 @@ #define CONFIG_TIMER_TASK_STACK_SIZE CONFIG_ESP_TIMER_TASK_STACK_SIZE #define CONFIG_TOOLPREFIX CONFIG_SDK_TOOLPREFIX #define CONFIG_UDP_RECVMBOX_SIZE CONFIG_LWIP_UDP_RECVMBOX_SIZE -#define CONFIG_ARDUINO_IDF_COMMIT "3e370c4296" +#define CONFIG_ARDUINO_IDF_COMMIT "b86fe0c66c" #define CONFIG_ARDUINO_IDF_BRANCH "master" diff --git a/tools/sdk/esp32c3/include/driver/include/driver/rmt.h b/tools/sdk/esp32c3/include/driver/include/driver/rmt.h index a7e2aad5f24..bc07954a080 100644 --- a/tools/sdk/esp32c3/include/driver/include/driver/rmt.h +++ b/tools/sdk/esp32c3/include/driver/include/driver/rmt.h @@ -856,16 +856,35 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT /** - * @brief Set loop count for RMT TX channel + * @brief Set loop count threshold value for RMT TX channel + * + * When tx loop count reaches this value, an ISR callback will notify user * * @param channel RMT channel - * @param count loop count + * @param count loop count, 1 ~ 1023 * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count); -#endif + +/** + * @brief Enable or disable the feature that when loop count reaches the threshold, RMT will stop transmitting. + * + * - When the loop auto-stop feature is enabled will halt RMT transmission after the loop count reaches a certain threshold + * - When disabled, the RMT transmission continue indefinitely until halted by the users + * + * @note The auto-stop feature is implemented in hardware on particular targets (i.e. those with SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP defined). + * Otherwise, the auto-stop feature is implemented in software via the interrupt. + * + * @param channel RMT channel + * @param en enable bit + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + */ +esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en); +#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT /** * @brief Reset RMT TX/RX memory index. diff --git a/tools/sdk/esp32c3/include/esp_https_server/include/esp_https_server.h b/tools/sdk/esp32c3/include/esp_https_server/include/esp_https_server.h index 00565a963ad..efe726e9e70 100644 --- a/tools/sdk/esp32c3/include/esp_https_server/include/esp_https_server.h +++ b/tools/sdk/esp32c3/include/esp_https_server/include/esp_https_server.h @@ -10,6 +10,7 @@ #include #include "esp_err.h" #include "esp_http_server.h" +#include "esp_tls.h" #ifdef __cplusplus extern "C" { @@ -20,6 +21,22 @@ typedef enum { HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled } httpd_ssl_transport_mode_t; +/** + * @brief Callback data struct, contains the ESP-TLS connection handle + */ +typedef struct esp_https_server_user_cb_arg { + const esp_tls_t *tls; +} esp_https_server_user_cb_arg_t; + +/** + * @brief Callback function prototype + * Can be used to get connection or client information (SSL context) + * E.g. Client certificate, Socket FD, Connection state, etc. + * + * @param user_cb Callback data struct + */ +typedef void esp_https_server_user_cb(esp_https_server_user_cb_arg_t *user_cb); + /** * HTTPS server config struct * @@ -66,6 +83,9 @@ struct httpd_ssl_config { /** Enable tls session tickets */ bool session_tickets; + + /** User callback for esp_https_server */ + esp_https_server_user_cb *user_cb; }; typedef struct httpd_ssl_config httpd_ssl_config_t; @@ -113,6 +133,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t; .port_secure = 443, \ .port_insecure = 80, \ .session_tickets = false, \ + .user_cb = NULL, \ } /** diff --git a/tools/sdk/esp32c3/include/esp_hw_support/include/esp_sleep.h b/tools/sdk/esp32c3/include/esp_hw_support/include/esp_sleep.h index cfdfbc04186..75d2f9726c3 100644 --- a/tools/sdk/esp32c3/include/esp_hw_support/include/esp_sleep.h +++ b/tools/sdk/esp32c3/include/esp_hw_support/include/esp_sleep.h @@ -44,6 +44,7 @@ typedef enum { #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core #endif + ESP_PD_DOMAIN_RTC8M, //!< Internal 8M oscillator ESP_PD_DOMAIN_VDDSDIO, //!< VDD_SDIO ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; diff --git a/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_io.h b/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_io.h index eebcabf42b4..330f4d9a165 100644 --- a/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_io.h +++ b/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_io.h @@ -65,6 +65,22 @@ esp_err_t esp_lcd_panel_io_tx_color(esp_lcd_panel_io_handle_t io, int lcd_cmd, c */ esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io); +/** + * @brief Type of LCD panel IO event data + */ +typedef struct { +} esp_lcd_panel_io_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] edata Panel IO event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); + /** * @brief Panel IO configuration structure, for SPI interface */ @@ -74,8 +90,8 @@ typedef struct { int spi_mode; /*!< Traditional SPI mode (0~3) */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Size of internal transaction queue */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { @@ -100,8 +116,8 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p typedef struct { uint32_t dev_addr; /*!< I2C device address */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ size_t control_phase_bytes; /*!< I2C LCD panel will encode control information (e.g. D/C seclection) into control phase, in several bytes */ unsigned int dc_bit_offset; /*!< Offset of the D/C selection bit in control phase */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ @@ -168,8 +184,8 @@ typedef struct { int cs_gpio_num; /*!< GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Transaction queue size, larger queue, higher throughput */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data was tranferred done */ - void *user_data; /*!< User private data, passed directly to on_trans_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data was tranferred done */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { diff --git a/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_rgb.h b/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_rgb.h index 2ddd2b6b9a6..1368bb787f6 100644 --- a/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_rgb.h +++ b/tools/sdk/esp32c3/include/esp_lcd/include/esp_lcd_panel_rgb.h @@ -18,6 +18,37 @@ extern "C" { #if SOC_LCD_RGB_SUPPORTED /** * @brief LCD RGB timing structure + * + * Total Width + * <---------------------------------------------------> + * Hsync width HBP Active Width HFP + * <---><--><--------------------------------------><---> + * ____ ____|_______________________________________|____| + * |___| | | | + * | | | + * __| | | | + * /|\ /|\ | | | | + * | VSYNC| | | | | + * |Width\|/ |__ | | | + * | /|\ | | | | + * | VBP | | | | | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | / / / / / / / / / / / / / / / / / / / | | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Total | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Heigh | | | |/ / / / / / / / / / / / / / / / / / / /| | + * |Active| | |/ / / / / / / / / / / / / / / / / / / /| | + * |Heigh | | |/ / / / / / Active Display Area / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | + * | VFP | | | + * \|/ \|/_____|______________________________________________________| + * */ typedef struct { unsigned int pclk_hz; /*!< Frequency of pixel clock */ @@ -38,6 +69,22 @@ typedef struct { } flags; } esp_lcd_rgb_timing_t; +/** + * @brief Type of RGB LCD panel event data + */ +typedef struct { +} esp_lcd_rgb_panel_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel LCD panel handle, returned from `esp_lcd_new_rgb_panel` + * @param[in] edata Panel event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_rgb_panel_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_rgb_panel_frame_trans_done_cb_t)(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx); + /** * @brief LCD RGB panel configuration structure */ @@ -51,8 +98,8 @@ typedef struct { int pclk_gpio_num; /*!< GPIO used for PCLK signal */ int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; /*!< GPIOs used for data lines */ int disp_gpio_num; /*!< GPIO used for display control signal, set to -1 if it's not used */ - bool (*on_frame_trans_done)(esp_lcd_panel_handle_t panel, void *user_data); /*!< Callback, invoked when one frame buffer has transferred done */ - void *user_data; /*!< User data which would be passed to on_frame_trans_done's user_data */ + esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; /*!< Callback invoked when one frame buffer has transferred done */ + void *user_ctx; /*!< User data which would be passed to on_frame_trans_done's user_ctx */ struct { unsigned int disp_active_low: 1; /*!< If this flag is enabled, a low level of display control signal can turn the screen on; vice versa */ unsigned int relax_on_idle: 1; /*!< If this flag is enabled, the host won't refresh the LCD if nothing changed in host's frame buffer (this is usefull for LCD with built-in GRAM) */ diff --git a/tools/sdk/esp32c3/include/esp_littlefs/include/esp_littlefs.h b/tools/sdk/esp32c3/include/esp_littlefs/include/esp_littlefs.h index dbb1028790d..7b5abe9248f 100644 --- a/tools/sdk/esp32c3/include/esp_littlefs/include/esp_littlefs.h +++ b/tools/sdk/esp32c3/include/esp_littlefs/include/esp_littlefs.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include "sdkconfig.h" diff --git a/tools/sdk/esp32c3/include/esp_rom/include/esp32c3/rom/newlib.h b/tools/sdk/esp32c3/include/esp_rom/include/esp32c3/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32c3/include/esp_rom/include/esp32c3/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32c3/include/esp_rom/include/esp32h2/rom/newlib.h b/tools/sdk/esp32c3/include/esp_rom/include/esp32h2/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32c3/include/esp_rom/include/esp32h2/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist.h b/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist.h index 1ff624d9b55..14b7c9aa506 100644 --- a/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist.h +++ b/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist.h @@ -1,16 +1,8 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_H__ #define __ESP_COEXIST_H__ @@ -32,6 +24,13 @@ typedef enum { ESP_COEX_PREFER_NUM, /*!< Prefer value numbers */ } esp_coex_prefer_t; +typedef enum { + EXTERN_COEX_WIRE_1 = 0, + EXTERN_COEX_WIRE_2, + EXTERN_COEX_WIRE_3, + EXTERN_COEX_WIRE_NUM, +} external_coex_wire_t; + /** * @brief coex status type */ @@ -41,6 +40,36 @@ typedef enum { ESP_COEX_ST_TYPE_BT, } esp_coex_status_type_t; +/** + * @brief external coex gpio pti + */ +typedef struct { + int32_t in_pin0; + int32_t in_pin1; + int32_t out_pin0; +} esp_external_coex_gpio_set_t; + +/** + * @brief external coex pti level + */ +typedef enum { + EXTERN_COEX_PTI_MID = 0, + EXTERN_COEX_PTI_HIGH, + EXTERN_COEX_PTI_NUM, +} esp_coex_pti_level_t; + +/** + * @brief external coex pti + */ +typedef struct { + uint32_t in_pti1; + uint32_t in_pti2; + uint32_t in_pti3; + uint32_t out_pti1; + uint32_t out_pti2; + uint32_t out_pti3; +} esp_external_coex_pti_set_t; + #define ESP_COEX_BLE_ST_MESH_CONFIG 0x08 #define ESP_COEX_BLE_ST_MESH_TRAFFIC 0x10 #define ESP_COEX_BLE_ST_MESH_STANDBY 0x20 @@ -84,6 +113,18 @@ esp_err_t esp_coex_status_bit_set(esp_coex_status_type_t type, uint32_t status); */ esp_err_t esp_coex_status_bit_clear(esp_coex_status_type_t type, uint32_t status); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Setup gpio pin and corresponding pti level, start external coex. + * @param wire_type : to select the whole external coex gpio number. + * @param gpio_pin : gpio pin number to choose. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, + esp_external_coex_gpio_set_t gpio_pin); + +esp_err_t esp_disable_extern_coex_gpio_pin(); +#endif #ifdef __cplusplus } diff --git a/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist_internal.h b/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist_internal.h index 3501f0da6fb..7ba06d4c690 100644 --- a/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist_internal.h +++ b/tools/sdk/esp32c3/include/esp_wifi/include/esp_coexist_internal.h @@ -1,21 +1,14 @@ -// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_INTERNAL_H__ #define __ESP_COEXIST_INTERNAL_H__ #include +#include "esp_coexist.h" #include "esp_coexist_adapter.h" #ifdef __cplusplus @@ -210,6 +203,29 @@ int coex_schm_curr_phase_idx_get(void); */ esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Set external coexistence pti level and enable it. + * + * @param level1 external coex low pti + * @param level2 external coex mid pti + * @param level3 external coex high pti + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_coex_external_set(esp_coex_pti_level_t level1, + esp_coex_pti_level_t level2, esp_coex_pti_level_t level3); + +/** + * @brief Disable external coexist + * + * @return + * - ESP_OK: succeed + */ +void esp_coex_external_stop(void); +#endif /*External Coex*/ + /** * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library * diff --git a/tools/sdk/esp32c3/include/esp_wifi/include/esp_wifi_types.h b/tools/sdk/esp32c3/include/esp_wifi/include/esp_wifi_types.h index 503e8d7bb05..cee23f3fafc 100644 --- a/tools/sdk/esp32c3/include/esp_wifi/include/esp_wifi_types.h +++ b/tools/sdk/esp32c3/include/esp_wifi/include/esp_wifi_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_WIFI_TYPES_H__ @@ -80,6 +72,7 @@ typedef enum { WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, WIFI_REASON_IE_INVALID = 13, WIFI_REASON_MIC_FAILURE = 14, WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, @@ -250,7 +243,8 @@ typedef struct { wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. */ uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ - uint32_t reserved:30; /**< Reserved for future feature set */ + uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ + uint32_t reserved:29; /**< Reserved for future feature set */ } wifi_sta_config_t; /** @brief Configuration data for ESP32 AP or STA. diff --git a/tools/sdk/esp32c3/include/freertos/include/esp_additions/FreeRTOSConfig.h b/tools/sdk/esp32c3/include/freertos/include/esp_additions/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/include/esp_additions/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32c3/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h b/tools/sdk/esp32c3/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h index a01a56e9fd4..675af141ebc 100644 --- a/tools/sdk/esp32c3/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h +++ b/tools/sdk/esp32c3/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h @@ -90,7 +90,6 @@ #define portNUM_PROCESSORS 1 #endif -#define configASSERT_2 0 #define portUSING_MPU_WRAPPERS 0 #define configUSE_MUTEX 1 @@ -206,7 +205,6 @@ #define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ #endif -#define configUSE_TRACE_FACILITY_2 0 #define configBENCHMARK 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 @@ -306,4 +304,9 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + #endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32c3/include/freertos/include/esp_additions/task_snapshot.h b/tools/sdk/esp32c3/include/freertos/include/esp_additions/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/include/esp_additions/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32c3/include/freertos/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/event_groups.h b/tools/sdk/esp32c3/include/freertos/include/freertos/event_groups.h index 84505ddaaa0..9792296e566 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/event_groups.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/event_groups.h @@ -64,7 +64,7 @@ * used to create a synchronisation point between multiple tasks (a * 'rendezvous'). * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroup EventGroup * @endcond */ @@ -78,7 +78,7 @@ * xEventGroupCreate() returns an EventGroupHandle_t variable that can then * be used as a parameter to other event group functions. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroupHandle_t EventGroupHandle_t * @endcond * \ingroup EventGroup @@ -94,7 +94,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, * 32 bits if set to 0. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventBits_t EventBits_t * @endcond * \ingroup EventGroup @@ -102,7 +102,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; typedef TickType_t EventBits_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreate( void ); @@ -152,7 +152,7 @@ typedef TickType_t EventBits_t; * // The event group was created. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupCreate xEventGroupCreate * @endcond * \ingroup EventGroup @@ -162,7 +162,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); @@ -217,7 +217,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, @@ -307,7 +307,7 @@ typedef TickType_t EventBits_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupWaitBits xEventGroupWaitBits * @endcond * \ingroup EventGroup @@ -319,7 +319,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); @@ -372,7 +372,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBits xEventGroupClearBits * @endcond * \ingroup EventGroup @@ -381,7 +381,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -432,7 +432,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * @endcond * \ingroup EventGroup @@ -446,7 +446,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -516,7 +516,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBits xEventGroupSetBits * @endcond * \ingroup EventGroup @@ -525,7 +525,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); @@ -595,7 +595,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * @endcond * \ingroup EventGroup @@ -610,7 +610,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, @@ -732,7 +732,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSync xEventGroupSync * @endcond * \ingroup EventGroup @@ -744,7 +744,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); @@ -758,7 +758,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBits() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBits xEventGroupGetBits * @endcond * \ingroup EventGroup @@ -766,7 +766,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); @@ -779,7 +779,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR * @endcond * \ingroup EventGroup @@ -787,7 +787,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); @@ -802,7 +802,7 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/freertos_tasks_c_additions.h b/tools/sdk/esp32c3/include/freertos/include/freertos/freertos_tasks_c_additions.h new file mode 100644 index 00000000000..464c0b3ffb9 --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/freertos_tasks_c_additions.h @@ -0,0 +1,80 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +/** + * This file will be included in `tasks.c` file, thus, it must NOT be included + * by any (other) file. + * The functions below only consist in getters for the static variables in + * `tasks.c` file. + * The only source files that should call these functions are the ones in + * `/additions` directory. + */ + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + + UBaseType_t pxTCBGetSize ( void ) + { + return sizeof(TCB_t); + } + + ListItem_t* pxTCBGetStateListItem ( void *pxTCB ) + { + return &(((TCB_t*)pxTCB)->xStateListItem); + } + + StackType_t* pxTCBGetStartOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxStack; + } + + StackType_t* pxTCBGetTopOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxTopOfStack; + } + + StackType_t* pxTCBGetEndOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxEndOfStack; + } + + + List_t* pxListGetReadyTask ( UBaseType_t idx ) + { + return &( pxReadyTasksLists[idx] ); + } + + List_t* pxListGetReadyPendingTask ( UBaseType_t idx ) + { + return &( xPendingReadyList[idx] ); + } + + List_t* pxGetDelayedTaskList ( void ) { + return pxDelayedTaskList; + } + + List_t* pxGetOverflowDelayedTaskList ( void ) { + return pxOverflowDelayedTaskList; + } + + List_t* pxGetTasksWaitingTermination ( void ) { + return &xTasksWaitingTermination; + } + + List_t* pxGetSuspendedTaskList ( void ) { + return &xSuspendedTaskList; + } + +#endif diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/message_buffer.h b/tools/sdk/esp32c3/include/freertos/include/freertos/message_buffer.h index e57c589fbac..af5c3290b7c 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/message_buffer.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/message_buffer.h @@ -85,7 +85,7 @@ typedef void * MessageBufferHandle_t; /*-----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -139,7 +139,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreate xMessageBufferCreate * @endcond * \ingroup MessageBufferManagement @@ -148,7 +148,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -210,7 +210,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * @endcond * \ingroup MessageBufferManagement @@ -219,7 +219,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -314,7 +314,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSend xMessageBufferSend * @endcond * \ingroup MessageBufferManagement @@ -323,7 +323,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -423,7 +423,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * @endcond * \ingroup MessageBufferManagement @@ -432,7 +432,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -516,7 +516,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceive xMessageBufferReceive * @endcond * \ingroup MessageBufferManagement @@ -526,7 +526,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -622,7 +622,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * @endcond * \ingroup MessageBufferManagement @@ -631,7 +631,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -654,7 +654,7 @@ typedef void * MessageBufferHandle_t; vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); @@ -674,7 +674,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); @@ -693,7 +693,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); @@ -712,7 +712,7 @@ typedef void * MessageBufferHandle_t; * the message queue to wait for space to become available, or to wait for a * a message to be available, then pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReset xMessageBufferReset * @endcond * \ingroup MessageBufferManagement @@ -722,7 +722,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); @@ -740,7 +740,7 @@ typedef void * MessageBufferHandle_t; * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size * of the largest message that can be written to the message buffer is 6 bytes. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable * @endcond * \ingroup MessageBufferManagement @@ -751,7 +751,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); @@ -767,7 +767,7 @@ typedef void * MessageBufferHandle_t; * @return The length (in bytes) of the next message in the message buffer, or 0 * if the message buffer is empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes * @endcond * \ingroup MessageBufferManagement @@ -776,7 +776,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -811,7 +811,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -820,7 +820,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -856,7 +856,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/queue.h b/tools/sdk/esp32c3/include/freertos/include/freertos/queue.h index 81cccc05df3..05ca7de4546 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/queue.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/queue.h @@ -62,7 +62,7 @@ typedef struct QueueDefinition * QueueSetHandle_t; */ typedef struct QueueDefinition * QueueSetMemberHandle_t; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ #define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) @@ -80,7 +80,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreate( @@ -146,7 +146,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreate xQueueCreate * @endcond * \ingroup QueueManagement @@ -156,7 +156,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreateStatic( @@ -235,7 +235,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreateStatic xQueueCreateStatic * @endcond * \ingroup QueueManagement @@ -245,7 +245,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToToFront( @@ -321,7 +321,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -330,7 +330,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBack( @@ -408,7 +408,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -417,7 +417,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSend( @@ -497,7 +497,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -506,7 +506,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwrite( @@ -585,7 +585,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwrite xQueueOverwrite * @endcond * \ingroup QueueManagement @@ -595,7 +595,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSend( @@ -678,7 +678,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -689,7 +689,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeek( @@ -780,7 +780,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeek xQueuePeek * @endcond * \ingroup QueueManagement @@ -790,7 +790,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeekFromISR( @@ -820,7 +820,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeekFromISR xQueuePeekFromISR * @endcond * \ingroup QueueManagement @@ -829,7 +829,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceive( @@ -917,7 +917,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceive xQueueReceive * @endcond * \ingroup QueueManagement @@ -927,7 +927,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); @@ -940,7 +940,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, * * @return The number of messages available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -948,7 +948,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ); @@ -963,7 +963,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @return The number of spaces available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -971,7 +971,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * void vQueueDelete( QueueHandle_t xQueue ); @@ -983,7 +983,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @param xQueue A handle to the queue to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vQueueDelete vQueueDelete * @endcond * \ingroup QueueManagement @@ -991,7 +991,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToFrontFromISR( @@ -1057,7 +1057,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1067,7 +1067,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBackFromISR( @@ -1133,7 +1133,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1142,7 +1142,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwriteFromISR( @@ -1225,7 +1225,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR * @endcond * \ingroup QueueManagement @@ -1234,7 +1234,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendFromISR( @@ -1304,7 +1304,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1312,10 +1312,10 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; #define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /**@{*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSendFromISR( @@ -1402,7 +1402,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceiveFromISR( @@ -1487,7 +1487,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR * @endcond * \ingroup QueueManagement @@ -1504,7 +1504,7 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * The functions defined above are for passing data to and from tasks. The * functions below are the equivalents for passing data to and from @@ -1778,7 +1778,7 @@ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, */ QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Not public API functions. */ void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/semphr.h b/tools/sdk/esp32c3/include/freertos/include/freertos/semphr.h index 7e99c0b396c..2041641b91d 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/semphr.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/semphr.h @@ -39,7 +39,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * semphr. h * @code{c} @@ -88,7 +88,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -106,7 +106,7 @@ typedef QueueHandle_t SemaphoreHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinary( void ); @@ -163,7 +163,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -173,7 +173,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); @@ -229,7 +229,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // Rest of task code goes here. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic * @endcond * \ingroup Semaphores @@ -239,7 +239,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTake( @@ -304,7 +304,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTake xSemaphoreTake * @endcond * \ingroup Semaphores @@ -312,7 +312,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeRecursive( @@ -403,7 +403,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive * @endcond * \ingroup Semaphores @@ -465,7 +465,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGive xSemaphoreGive * @endcond * \ingroup Semaphores @@ -473,7 +473,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); @@ -555,7 +555,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive * @endcond * \ingroup Semaphores @@ -641,7 +641,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR * @endcond * \ingroup Semaphores @@ -649,7 +649,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeFromISR( @@ -686,7 +686,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutex( void ); @@ -741,7 +741,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex * @endcond * \ingroup Semaphores @@ -751,7 +751,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); @@ -808,7 +808,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // so there is no need to check it. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic * @endcond * \ingroup Semaphores @@ -951,7 +951,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); @@ -1027,7 +1027,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * @endcond * \ingroup Semaphores @@ -1037,7 +1037,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer ); @@ -1118,7 +1118,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // is no need to check its value. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic * @endcond * \ingroup Semaphores @@ -1128,7 +1128,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); @@ -1140,7 +1140,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * * @param xSemaphore A handle to the semaphore to be deleted. * - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * \defgroup vSemaphoreDelete vSemaphoreDelete * @endcond * \ingroup Semaphores @@ -1148,7 +1148,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); @@ -1167,7 +1167,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex ); @@ -1182,7 +1182,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/stream_buffer.h b/tools/sdk/esp32c3/include/freertos/include/freertos/stream_buffer.h index 9e58cff120c..a20dcf0375e 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/stream_buffer.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/stream_buffer.h @@ -71,7 +71,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -134,7 +134,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreate xStreamBufferCreate * @endcond * \ingroup StreamBufferManagement @@ -142,7 +142,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -220,7 +220,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * @endcond * \ingroup StreamBufferManagement @@ -229,7 +229,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -319,7 +319,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSend xStreamBufferSend * @endcond * \ingroup StreamBufferManagement @@ -330,7 +330,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -424,7 +424,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * @endcond * \ingroup StreamBufferManagement @@ -435,7 +435,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -517,7 +517,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceive xStreamBufferReceive * @endcond * \ingroup StreamBufferManagement @@ -528,7 +528,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -607,7 +607,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * @endcond * \ingroup StreamBufferManagement @@ -618,7 +618,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -636,7 +636,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * * @param xStreamBuffer The handle of the stream buffer to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vStreamBufferDelete vStreamBufferDelete * @endcond * \ingroup StreamBufferManagement @@ -644,7 +644,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -660,7 +660,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI * @return If the stream buffer is full then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsFull xStreamBufferIsFull * @endcond * \ingroup StreamBufferManagement @@ -668,7 +668,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -684,7 +684,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ * @return If the stream buffer is empty then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty * @endcond * \ingroup StreamBufferManagement @@ -692,7 +692,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -711,7 +711,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED * a task blocked waiting to send to or read from the stream buffer then the * stream buffer is not reset and pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReset xStreamBufferReset * @endcond * \ingroup StreamBufferManagement @@ -719,7 +719,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -736,7 +736,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F * @return The number of bytes that can be written to the stream buffer before * the stream buffer would be full. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable * @endcond * \ingroup StreamBufferManagement @@ -744,7 +744,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -761,7 +761,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL * @return The number of bytes that can be read from the stream buffer before * the stream buffer would be empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable * @endcond * \ingroup StreamBufferManagement @@ -769,7 +769,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -802,7 +802,7 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE * then the trigger level will be updated and pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * @endcond * \ingroup StreamBufferManagement @@ -811,7 +811,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -846,7 +846,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -855,7 +855,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -891,7 +891,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -899,7 +899,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Functions below here are not part of the public API. */ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/task.h b/tools/sdk/esp32c3/include/freertos/include/freertos/task.h index 9135b76f014..125a924d061 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/task.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/task.h @@ -76,7 +76,7 @@ * returns (via a pointer parameter) an TaskHandle_t variable that can then * be used as a parameter to vTaskDelete to delete the task. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup TaskHandle_t TaskHandle_t * @endcond * \ingroup Tasks @@ -114,7 +114,7 @@ typedef enum eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ } eNotifyAction; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * Used internally only. */ @@ -189,11 +189,13 @@ typedef enum #define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro for forcing a context switch. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskYIELD taskYIELD * @endcond * \ingroup SchedulerControl @@ -201,7 +203,9 @@ typedef enum #define taskYIELD() portYIELD() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the start of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -209,7 +213,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL * @endcond * \ingroup SchedulerControl @@ -228,7 +232,9 @@ typedef enum #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the end of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -236,7 +242,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL * @endcond * \ingroup SchedulerControl @@ -255,11 +261,13 @@ typedef enum #define taskEXIT_CRITICAL_ISR( ) portEXIT_CRITICAL_ISR( ) #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to disable all maskable interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -267,11 +275,13 @@ typedef enum #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to enable microcontroller interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -422,7 +432,7 @@ typedef enum * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreate xTaskCreate * @endcond * \ingroup Tasks @@ -430,14 +440,14 @@ typedef enum #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) static inline IRAM_ATTR BaseType_t xTaskCreate( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pvCreatedTask) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask) PRIVILEGED_FUNCTION { - return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask, tskNO_AFFINITY ); + return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY ); } #endif @@ -599,20 +609,20 @@ typedef enum #if( configSUPPORT_STATIC_ALLOCATION == 1 ) static inline IRAM_ATTR TaskHandle_t xTaskCreateStatic( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const pxStackBuffer, - StaticTask_t * const pxTaskBuffer) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer) PRIVILEGED_FUNCTION { - return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, pxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); + return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); } #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -683,18 +693,18 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks */ #if ( portUSING_MPU_WRAPPERS == 1 ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, - TaskHandle_t * pxCreatedTask ); + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -777,7 +787,7 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic * @endcond * \ingroup Tasks @@ -788,7 +798,7 @@ typedef enum #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); @@ -833,7 +843,7 @@ typedef enum * // defined or shared regions have been declared elsewhere). * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks @@ -842,7 +852,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelete( TaskHandle_t xTask ); @@ -881,7 +891,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, * vTaskDelete( xHandle ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelete vTaskDelete * @endcond * \ingroup Tasks @@ -893,10 +903,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelay( const TickType_t xTicksToDelay ); * @endcode + * @endcond * * Delay a task for a given number of ticks. The actual time that the * task remains blocked depends on the tick rate. The constant @@ -938,7 +950,7 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelay vTaskDelay * @endcond * \ingroup TaskCtrl @@ -946,10 +958,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); * @endcode + * @endcond * * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. * See the configuration section for more information. @@ -1007,7 +1021,7 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskDelayUntil xTaskDelayUntil * @endcond * \ingroup TaskCtrl @@ -1026,7 +1040,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); @@ -1054,7 +1068,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, * @return If the task referenced by xTask was not in the Blocked state then * pdFAIL is returned. Otherwise pdPASS is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskAbortDelay xTaskAbortDelay * @endcond * \ingroup TaskCtrl @@ -1062,7 +1076,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ); @@ -1107,7 +1121,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskPriorityGet uxTaskPriorityGet * @endcond * \ingroup TaskCtrl @@ -1115,7 +1129,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ); @@ -1127,7 +1141,7 @@ UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * eTaskState eTaskGetState( TaskHandle_t xTask ); @@ -1149,7 +1163,7 @@ UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNC eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); @@ -1203,7 +1217,7 @@ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * eInvalid ); // Include the task state in xTaskDetails. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetInfo vTaskGetInfo * @endcond * \ingroup TaskCtrl @@ -1214,7 +1228,7 @@ void vTaskGetInfo( TaskHandle_t xTask, eTaskState eState ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); @@ -1254,7 +1268,7 @@ void vTaskGetInfo( TaskHandle_t xTask, * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskPrioritySet vTaskPrioritySet * @endcond * \ingroup TaskCtrl @@ -1263,7 +1277,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); @@ -1312,7 +1326,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, * // with our handle as the parameter. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspend vTaskSuspend * @endcond * \ingroup TaskCtrl @@ -1320,7 +1334,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskResume( TaskHandle_t xTaskToResume ); @@ -1367,7 +1381,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; * // time in accordance with its priority within the system. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResume vTaskResume * @endcond * \ingroup TaskCtrl @@ -1375,7 +1389,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); @@ -1402,7 +1416,7 @@ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * otherwise pdFALSE. This is used by the ISR to determine if a context switch * may be required following the ISR. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResumeFromISR vTaskResumeFromISR * @endcond * \ingroup TaskCtrl @@ -1412,9 +1426,9 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER CONTROL *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskStartScheduler( void ); @@ -1445,7 +1459,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskStartScheduler vTaskStartScheduler * @endcond * \ingroup SchedulerControl @@ -1453,7 +1467,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskEndScheduler( void ); @@ -1507,7 +1521,7 @@ void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskEndScheduler vTaskEndScheduler * @endcond * \ingroup SchedulerControl @@ -1517,7 +1531,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspendAll( void ); @@ -1566,7 +1580,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspendAll vTaskSuspendAll * @endcond * \ingroup SchedulerControl @@ -1574,7 +1588,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskResumeAll( void ); @@ -1626,7 +1640,7 @@ void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskResumeAll xTaskResumeAll * @endcond * \ingroup SchedulerControl @@ -1638,7 +1652,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCount( void ); @@ -1647,7 +1661,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; * * @return The count of ticks since vTaskStartScheduler was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCount xTaskGetTickCount * @endcond * \ingroup TaskUtils @@ -1655,7 +1669,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCountFromISR( void ); @@ -1669,7 +1683,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; * microcontroller being used or interrupt nesting is either not supported or * not being used. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR * @endcond * \ingroup TaskUtils @@ -1677,7 +1691,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint16_t uxTaskGetNumberOfTasks( void ); @@ -1689,7 +1703,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; * has been deleted but not yet freed by the idle task will also be * included in the count. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * @endcond * \ingroup TaskUtils @@ -1697,7 +1711,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); @@ -1708,7 +1722,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; * xTaskToQuery. A task can query its own name by either passing in its own * handle, or by setting xTaskToQuery to NULL. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetName pcTaskGetName * @endcond * \ingroup TaskUtils @@ -1716,7 +1730,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); @@ -1730,7 +1744,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lin * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetHandle pcTaskGetHandle * @endcond * \ingroup TaskUtils @@ -1813,7 +1827,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #ifdef configUSE_APPLICATION_TASK_TAG #if configUSE_APPLICATION_TASK_TAG == 1 /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); @@ -1830,7 +1844,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTag( TaskHandle_t xTask ); @@ -1844,7 +1858,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ); @@ -1932,7 +1946,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationStackOverflowHook( TaskHandle_t xTask char *pcTaskName); @@ -1952,7 +1966,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configUSE_TICK_HOOK > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationTickHook( void ); @@ -1967,7 +1981,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) @@ -1986,7 +2000,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); @@ -2155,7 +2169,7 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, * enough to contain the generated report. Approximately 40 bytes per * task should be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskList vTaskList * @endcond * \ingroup TaskUtils @@ -2210,7 +2224,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq * contain the generated report. Approximately 40 bytes per task should * be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * @endcond * \ingroup TaskUtils @@ -2218,7 +2232,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code * uint32_t ulTaskGetIdleRunTimeCounter( void ); @@ -2246,7 +2260,7 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and * portGET_RUN_TIME_COUNTER_VALUE() macros. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter * @endcond * \ingroup TaskUtils @@ -2254,11 +2268,13 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction ); * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2359,7 +2375,9 @@ uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, @@ -2373,11 +2391,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2393,7 +2413,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * than when the function returns) in the additional pulPreviousNotifyValue * parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ @@ -2402,11 +2424,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2511,7 +2535,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, @@ -2526,11 +2552,13 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2546,7 +2574,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * function is called rather than at the time the function returns) in the * additional pulPreviousNotifyValue parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ @@ -2555,12 +2585,14 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification to be pending at a given index within * an array of direct to task notifications. @@ -2655,7 +2687,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * already pending when xTaskNotifyWait was called) then pdPASS is * returned. Otherwise pdFAIL is returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, @@ -2669,11 +2703,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ); * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); * @endcode + * @endcond * * Sends a direct to task notification to a particular index in the target * task's notification array in a manner similar to giving a counting semaphore. @@ -2737,7 +2773,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the * eAction parameter set to eIncrement - so pdPASS is always returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyGive( xTaskToNotify ) \ @@ -2746,11 +2784,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ); * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt * service routine (ISR). @@ -2821,7 +2861,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * requested from an ISR is dependent on the port - see the documentation page * for the port in use. * + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR + * @endcond * \ingroup TaskNotifications */ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, @@ -2833,12 +2875,14 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) ); /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification on a particular index in the calling * task's notification array in a manner similar to taking a counting semaphore. @@ -2927,7 +2971,9 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, * @return The task's notification count before it is either cleared to zero or * decremented (see the xClearCountOnExit parameter). * + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, @@ -2939,12 +2985,14 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, ulTaskGenericNotifyTake( ( uxIndexToWaitOn ), ( xClearCountOnExit ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); * * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2992,7 +3040,9 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, * @return pdTRUE if the task's notification state was set to * eNotWaitingNotification, otherwise pdFALSE. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, @@ -3003,12 +3053,14 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ); * * uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -3057,7 +3109,9 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, * * @return The value of the target task's notification value before the bits * specified by ulBitsToClear were cleared. + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, @@ -3069,7 +3123,7 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); @@ -3082,14 +3136,14 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, * is to be captured. The captured time includes the tick count and the number * of times the tick count has overflowed since the system first booted. * \defgroup vTaskSetTimeOutState vTaskSetTimeOutState - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code * BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); @@ -3170,7 +3224,7 @@ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; * return uxReceived; * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCheckForTimeOut xTaskCheckForTimeOut * @endcond * \ingroup TaskCtrl @@ -3179,7 +3233,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ); @@ -3204,7 +3258,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, * blocked state and a context switch being performed. Otherwise pdFALSE. * * \defgroup xTaskCatchUpTicks xTaskCatchUpTicks - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ @@ -3214,7 +3268,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Return the handle of the task running on a certain CPU. Because of * the nature of SMP processing, there is no guarantee that this @@ -3335,8 +3389,8 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, * making the call, otherwise pdFALSE. */ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; -BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, - const TickType_t xItemValue ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, + const TickType_t xItemValue ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY @@ -3399,11 +3453,6 @@ void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, */ UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; -/* - * Get the current core affinity of a task - */ -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; - /* * Set the uxTaskNumber of the task referenced by the xTask parameter to * uxHandle. diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/task_snapshot.h b/tools/sdk/esp32c3/include/freertos/include/freertos/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32c3/include/freertos/include/freertos/timers.h b/tools/sdk/esp32c3/include/freertos/include/freertos/timers.h index a8bc4f38c78..af6dcb23501 100644 --- a/tools/sdk/esp32c3/include/freertos/include/freertos/timers.h +++ b/tools/sdk/esp32c3/include/freertos/include/freertos/timers.h @@ -450,7 +450,7 @@ void vTimerSetTimerID( TimerHandle_t xTimer, BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * @endcond * @@ -1315,7 +1315,7 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; */ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Functions beyond this part are not part of the public API and are intended @@ -1339,7 +1339,7 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) diff --git a/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..a7d534343fb --- /dev/null +++ b/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,105 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_RISCV_H +#define FREERTOS_CONFIG_RISCV_H + +// This file is included in the common FreeRTOSConfig.h. + +#include "sdkconfig.h" + +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 + +#ifndef __ASSEMBLER__ +#if CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" +#endif +#endif // __ASSEMBLER__ + +/* The maximum interrupt priority from which FreeRTOS.org API functions can + be called. Only API functions that end in ...FromISR() can be used within + interrupts. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0 + +#ifndef configISR_STACK_SIZE +#define configISR_STACK_SIZE (CONFIG_FREERTOS_ISR_STACKSIZE) +#endif + +#ifndef __ASSEMBLER__ +#if CONFIG_APPTRACE_SV_ENABLE +extern int xPortSwitchFlag; +#define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag) +#else +#define os_task_switch_is_pended(_cpu_) (false) +#endif +#endif + +#endif // FREERTOS_CONFIG_RISCV_H diff --git a/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/portmacro.h b/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/portmacro.h index cb58b422658..8c09ba7df2f 100644 --- a/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/portmacro.h +++ b/tools/sdk/esp32c3/include/freertos/port/riscv/include/freertos/portmacro.h @@ -24,178 +24,419 @@ * * 1 tab == 4 spaces! */ + #ifndef PORTMACRO_H #define PORTMACRO_H -#ifdef __cplusplus -extern "C" { -#endif - #ifndef __ASSEMBLER__ +#include "sdkconfig.h" #include #include #include #include -#include -#include "esp_timer.h" /* required for FreeRTOS run time stats */ - -#include "sdkconfig.h" +#include "soc/spinlock.h" +#include "soc/interrupt_core0_reg.h" +#include "soc/cpu.h" #include "esp_attr.h" +#include "esp_rom_sys.h" +#include "esp_timer.h" /* required for FreeRTOS run time stats */ #include "esp_heap_caps.h" +#include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */ +#include "esp_newlib.h" +#include "portbenchmark.h" + +/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */ +#include #ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS #include "soc/soc_memory_layout.h" #endif -#include "soc/spinlock.h" -#include "soc/interrupt_core0_reg.h" -#include "esp_rom_sys.h" -#include "soc/cpu.h" -#include "esp_system.h" -#include "esp_newlib.h" -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ +#ifdef __cplusplus +extern "C" { +#endif -/* Type definitions. */ -#define portCHAR uint8_t -#define portFLOAT float -#define portDOUBLE double -#define portLONG int32_t -#define portSHORT int16_t -#define portSTACK_TYPE uint8_t -#define portBASE_TYPE int -// interrupt module will mask interrupt with priority less than threshold -#define RVHAL_EXCM_LEVEL 4 -typedef portSTACK_TYPE StackType_t; -typedef portBASE_TYPE BaseType_t; -typedef unsigned portBASE_TYPE UBaseType_t; -#if( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff +/* --------------------------------------------------- Port Types ------------------------------------------------------ + * - Port specific types. + * - The settings in this file configure FreeRTOS correctly for the given hardware and compiler. + * - These settings should not be altered. + * - The port types must come first as they are used further down in this file + * ------------------------------------------------------------------------------------------------------------------ */ + +#define portCHAR uint8_t +#define portFLOAT float +#define portDOUBLE double +#define portLONG int32_t +#define portSHORT int16_t +#define portSTACK_TYPE uint8_t +#define portBASE_TYPE int + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef unsigned portBASE_TYPE UBaseType_t; + +#if (configUSE_16_BIT_TICKS == 1) +typedef uint16_t TickType_t; +#define portMAX_DELAY (TickType_t) 0xffff #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +typedef uint32_t TickType_t; +#define portMAX_DELAY (TickType_t) 0xffffffffUL #endif -/*------------------------------------------------------*/ -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) (1000 / configTICK_RATE_HZ) ) -#define portBYTE_ALIGNMENT 16 -/*-----------------------------------------------------------*/ -#include "portbenchmark.h" +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters) +#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters) -static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) { - return cpu_hal_get_core_id(); -} +// interrupt module will mask interrupt with priority less than threshold +#define RVHAL_EXCM_LEVEL 4 -static inline bool IRAM_ATTR xPortCanYield(void) -{ - uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG); - /* when enter critical code, freertos will mask threshold to RVHAL_EXCM_LEVEL - * and exit critical code, will recover threshold value (1). so threshold <= 1 - * means not in critical code - */ - return (threshold <= 1); -} +/* ----------------------------------------------- Port Configurations ------------------------------------------------- + * - Configurations values supplied by each port + * - Required by FreeRTOS + * ------------------------------------------------------------------------------------------------------------------ */ -static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) -{ -#if defined(CONFIG_SPIRAM) - compare_and_set_extram(addr, compare, set); -#endif -} +#define portCRITICAL_NESTING_IN_TCB 0 +#define portSTACK_GROWTH (-1) +#define portTICK_PERIOD_MS ((TickType_t) (1000 / configTICK_RATE_HZ)) +#define portBYTE_ALIGNMENT 16 +#define portNOP() __asm volatile (" nop ") -static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { - compare_and_set_native(addr, compare, set); -} -#define portCRITICAL_NESTING_IN_TCB 0 -/* - * Send an interrupt to another core in order to make the task running - * on it yield for a higher-priority task. - */ -void vPortYieldOtherCore( BaseType_t coreid); +/* ---------------------------------------------- Forward Declarations ------------------------------------------------- + * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface + * - These must come before definition/declaration of the FreeRTOS porting interface + * ------------------------------------------------------------------------------------------------------------------ */ -/* - Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack - watchpoint around. - */ -void vPortSetStackWatchpoint( void* pxStackStart ); +// --------------------- Interrupts ------------------------ -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. +/** + * @brief Checks if the current core is in an ISR context + * + * - ISR context consist of Low/Mid priority ISR, or time tick ISR + * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in ISR + * - pdFALSE otherwise */ BaseType_t xPortInIsrContext(void); -/* - * This function will be called in High prio ISRs. Returns true if the current core was in ISR context - * before calling into high prio ISR context. +/** + * @brief Check if in ISR context from High priority ISRs + * + * - Called from High priority ISR + * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority) + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in previous in ISR context + * - pdFALSE otherwise */ BaseType_t xPortInterruptedFromISRContext(void); -/* "mux" data structure (spinlock) */ +/** + * @brief Disable interrupts in a nested manner + * + * - Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. + * - They can be called from interrupts too. + * - WARNING Only applies to current CPU. + * + * @note [refactor-todo] Define this as portSET_INTERRUPT_MASK_FROM_ISR() instead + * @return unsigned Previous interrupt state + */ +static inline unsigned portENTER_CRITICAL_NESTED(void); + +/* ---------------------- Spinlocks ------------------------ + - Spinlocks added to match API with SMP FreeRTOS. Single core RISC-V does not need spin locks + - Because single core does not have a primitive spinlock data type, we have to implement one here + * @note [refactor-todo] Refactor critical section API so that this is no longer required + * ------------------------------------------------------ */ + +/** + * @brief Spinlock object + * Owner: + * - Set to 0 if uninitialized + * - Set to portMUX_FREE_VAL when free + * - Set to CORE_ID_REGVAL_PRO or CORE_ID_REGVAL_AP when locked + * - Any other value indicates corruption + * Count: + * - 0 if unlocked + * - Recursive count if locked + * + * @note Not a true spinlock as single core RISC-V does not have atomic compare and set instruction + * @note Keep portMUX_INITIALIZER_UNLOCKED in sync with this struct + */ typedef struct { - /* owner field values: - * 0 - Uninitialized (invalid) - * portMUX_FREE_VAL - Mux is free, can be locked by either CPU - * CORE_ID_REGVAL_PRO / CORE_ID_REGVAL_APP - Mux is locked to the particular core - * - * - * Any value other than portMUX_FREE_VAL, CORE_ID_REGVAL_PRO, CORE_ID_REGVAL_APP indicates corruption - */ - uint32_t owner; - /* count field: - * If mux is unlocked, count should be zero. - * If mux is locked, count is non-zero & represents the number of recursive locks on the mux. - */ - uint32_t count; + uint32_t owner; + uint32_t count; #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG - const char *lastLockedFn; - int lastLockedLine; + const char *lastLockedFn; + int lastLockedLine; #endif } portMUX_TYPE; +/**< Spinlock initializer */ +#ifndef CONFIG_FREERTOS_PORTMUX_DEBUG +#define portMUX_INITIALIZER_UNLOCKED { \ + .owner = portMUX_FREE_VAL, \ + .count = 0, \ + } +#else +#define portMUX_INITIALIZER_UNLOCKED { \ + .owner = portMUX_FREE_VAL, \ + .count = 0, \ + .lastLockedFn = "(never locked)", \ + .lastLockedLine = -1 \ + } +#endif /* CONFIG_FREERTOS_PORTMUX_DEBUG */ +#define portMUX_FREE_VAL SPINLOCK_FREE /**< Spinlock is free. [refactor-todo] check if this is still required */ +#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */ +#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */ + +/** + * @brief Initialize a spinlock + * + * - Initializes a spinlock that is used by FreeRTOS SMP critical sections + * + * @note [refactor-todo] We can make this inline or consider making it a macro + * @param[in] mux Spinlock + */ +void vPortCPUInitializeMutex(portMUX_TYPE *mux); -#define portMUX_FREE_VAL SPINLOCK_FREE +/** + * @brief Acquire a spinlock + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this should be inlined + * @param[in] mux Spinlock + */ +void vPortCPUAcquireMutex(portMUX_TYPE *mux); -/* Special constants for vPortCPUAcquireMutexTimeout() */ -#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /* When passed for 'timeout_cycles', spin forever if necessary */ -#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /* Try to acquire the spinlock a single time only */ +/** + * @brief Acquire a spinlock but with a specified timeout + * + * @note [refactor-todo] Check if we still need this + * @note [refactor-todo] Check if this should be inlined + * @note [refactor-todo] Check if this function should be renamed (due to bool return type) + * @param[in] mux Spinlock + * @param[in] timeout Timeout in number of CPU cycles + * @return true Spinlock acquired + * @return false Timed out + */ +bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles); -// Keep this in sync with the portMUX_TYPE struct definition please. -#ifndef CONFIG_FREERTOS_PORTMUX_DEBUG -#define portMUX_INITIALIZER_UNLOCKED { \ - .owner = portMUX_FREE_VAL, \ - .count = 0, \ - } -#else -#define portMUX_INITIALIZER_UNLOCKED { \ - .owner = portMUX_FREE_VAL, \ - .count = 0, \ - .lastLockedFn = "(never locked)", \ - .lastLockedLine = -1 \ - } -#endif +/** + * @brief Release a spinlock + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this should be inlined + * @param[in] mux Spinlock + */ +void vPortCPUReleaseMutex(portMUX_TYPE *mux); -/* Scheduler utilities. */ -extern void vPortYield( void ); -extern void vPortYieldFromISR( void ); +/** + * @brief Wrapper for atomic compare-and-set instruction + * + * @note Isn't a real atomic CAS. + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to void return type) + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set); -#define portYIELD() vPortYield() -#define portYIELD_FROM_ISR() vPortYieldFromISR() +/** + * @brief Wrapper for atomic compare-and-set instruction in external RAM + * + * @note Isn't a real atomic CAS. + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to void return type) + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set); + +// ------------------ Critical Sections -------------------- + +/** + * @brief Enter a critical section + * + * - Simply disable interrupts + * - Can be nested + */ +void vPortEnterCritical(void); + +/** + * @brief Exit a critical section + * + * - Reenables interrupts + * - Can be nested + */ +void vPortExitCritical(void); + +// ---------------------- Yielding ------------------------- +/** + * @brief Set interrupt mask and return current interrupt enable register + * + * @note [refactor-todo] Check if this function should be renamed (due to int return type) + * @return int Current interrupt enable register before set + */ +int vPortSetInterruptMask(void); + +/** + * @brief Clear current interrupt mask and set given mask + * + * @param mask Interrupt mask + */ +void vPortClearInterruptMask(int mask); + +/** + * @brief Perform a context switch from a task + * + * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead + */ +void vPortYield(void); + +/** + * @brief Perform a context switch from an ISR + */ +void vPortYieldFromISR(void); + +/** + * @brief Yields the other core + * + * @note Added to be compatible with SMP API + * @note [refactor-todo] Put this into private macros as its only called from task.c and is not public API + * @param coreid ID of core to yield + */ +void vPortYieldOtherCore(BaseType_t coreid); + +/** + * @brief Checks if the current core can yield + * + * - A core cannot yield if its in an ISR or in a critical section + * + * @note [refactor-todo] See if this can be separated from port macro + * @note [refactor-todo] Check if this function should be renamed (due to bool return type) + * @return true Core can yield + * @return false Core cannot yield + */ +static inline bool IRAM_ATTR xPortCanYield(void); + +// ------------------- Hook Functions ---------------------- + +extern void esp_vApplicationIdleHook(void); +extern void esp_vApplicationTickHook(void); + +/** + * @brief Hook function called on entry to tickless idle + * + * - Implemented in pm_impl.c + * + * @param xExpectedIdleTime Expected idle time + */ +void vApplicationSleep(TickType_t xExpectedIdleTime); + +// ----------------------- System -------------------------- + +/** + * @brief Get the tick rate per second + * + * @note [refactor-todo] make this inline + * @note [refactor-todo] Check if this function should be renamed (due to uint return type) + * @return uint32_t Tick rate in Hz + */ +uint32_t xPortGetTickRateHz(void); + +/** + * @brief Set a watchpoint to watch the last 32 bytes of the stack + * + * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint + * around. + * + * @param pxStackStart Pointer to the start of the stack + */ +void vPortSetStackWatchpoint(void *pxStackStart); + +/** + * @brief Get the current core's ID + * + * @note Added to be compatible with SMP API + * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly + * @return BaseType_t Core ID + */ +static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) +{ + return (uint32_t) cpu_hal_get_core_id(); +} + + + +/* ------------------------------------------- FreeRTOS Porting Interface ---------------------------------------------- + * - Contains all the mappings of the macros required by FreeRTOS + * - Most come after forward declare as porting macros map to declared functions + * - Maps to forward declared functions + * ------------------------------------------------------------------------------------------------------------------ */ + +// ----------------------- Memory -------------------------- + +/** + * @brief Task memory allocation macros + * + * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack + * memory to always be internal. + * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes + */ +#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define pvPortMallocTcbMem(size) pvPortMalloc(size) +#define pvPortMallocStackMem(size) pvPortMalloc(size) + +// --------------------- Interrupts ------------------------ + +#define portEXIT_CRITICAL_NESTED(state) do { portCLEAR_INTERRUPT_MASK_FROM_ISR(state);} while(0); +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK_FROM_ISR() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK_FROM_ISR(1) +#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue) + +// ------------------ Critical Sections -------------------- + +#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();} +#define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();} +//In single-core RISC-V, we can use the same critical section API +#define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux) +#define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux) +/* [refactor-todo] on RISC-V, both ISR and non-ISR cases result in the same call. We can redefine this macro */ +#define portENTER_CRITICAL_SAFE(mux) ({ \ + if (xPortInIsrContext()) { \ + portENTER_CRITICAL_ISR(mux); \ + } else { \ + portENTER_CRITICAL(mux); \ + } \ +}) +#define portEXIT_CRITICAL_SAFE(mux) ({ \ + if (xPortInIsrContext()) { \ + portEXIT_CRITICAL_ISR(mux); \ + } else { \ + portEXIT_CRITICAL(mux); \ + } \ +}) + +// ---------------------- Yielding ------------------------- + +#define portYIELD() vPortYield() +#define portYIELD_FROM_ISR() vPortYieldFromISR() +#define portEND_SWITCHING_ISR(xSwitchRequired) if(xSwitchRequired) vPortYield() /* Yielding within an API call (when interrupts are off), means the yield should be delayed until interrupts are re-enabled. To do this, we use the "cross-core" interrupt as a trigger to yield on this core when interrupts are re-enabled.This @@ -203,112 +444,104 @@ extern void vPortYieldFromISR( void ); happening on the same CPU. */ #define portYIELD_WITHIN_API() portYIELD() -/*-----------------------------------------------------------*/ - -/* Critical section management. */ -extern int vPortSetInterruptMask(void); -extern void vPortClearInterruptMask( int ); - -void vPortCPUInitializeMutex(portMUX_TYPE *mux); -void vPortCPUAcquireMutex(portMUX_TYPE *mux); -bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles); -void vPortCPUReleaseMutex(portMUX_TYPE *mux); -extern void vPortEnterCritical( void ); -extern void vPortExitCritical( void ); - -#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK_FROM_ISR() -#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK_FROM_ISR(1) - -#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();} -#define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();} - -#define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux) -#define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux) - -#define portENTER_CRITICAL_SAFE(mux) do { \ - if (xPortInIsrContext()) { \ - portENTER_CRITICAL_ISR(mux); \ - } else { \ - portENTER_CRITICAL(mux); \ - } \ - } while(0) - -#define portEXIT_CRITICAL_SAFE(mux) do { \ - if (xPortInIsrContext()) { \ - portEXIT_CRITICAL_ISR(mux); \ - } else { \ - portEXIT_CRITICAL(mux); \ - } \ - } while(0) - -/*------------------------------------------------------------*/ -#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMask() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMask( uxSavedStatusValue ) -#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield() - -// Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. -// They can be called from interrupts too. -static inline unsigned portENTER_CRITICAL_NESTED(void) { - unsigned state = portSET_INTERRUPT_MASK_FROM_ISR(); - return state; -} +// ------------------- Hook Functions ---------------------- -#define portEXIT_CRITICAL_NESTED(state) do { portCLEAR_INTERRUPT_MASK_FROM_ISR( state );} while(0); -/*-----------------------------------------------------------*/ - -//Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force -//the stack memory to always be internal. -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#ifndef CONFIG_FREERTOS_LEGACY_HOOKS +#define vApplicationIdleHook esp_vApplicationIdleHook +#define vApplicationTickHook esp_vApplicationTickHook +#endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */ +#define portSUPPRESS_TICKS_AND_SLEEP(idleTime) vApplicationSleep(idleTime) -#define pvPortMallocTcbMem(size) pvPortMalloc(size) -#define pvPortMallocStackMem(size) pvPortMalloc(size) +// ------------------- Run Time Stats ---------------------- -/* Fine resolution time */ -#define portGET_RUN_TIME_COUNTER_VALUE() 0 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() - +#define portGET_RUN_TIME_COUNTER_VALUE() 0 #ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER /* Coarse resolution time (us) */ #define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do {x = (uint32_t)esp_timer_get_time();} while(0) #endif -extern void esp_vApplicationIdleHook( void ); -extern void esp_vApplicationTickHook( void ); -#ifndef CONFIG_FREERTOS_LEGACY_HOOKS -#define vApplicationIdleHook esp_vApplicationIdleHook -#define vApplicationTickHook esp_vApplicationTickHook -#endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */ -/* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/* --------------------------------------------- Inline Implementations ------------------------------------------------ + * - Implementation of inline functions of the forward declares + * - Should come after forward declare and FreeRTOS Porting interface, as implementation may use both. + * - For implementation of non-inlined functions, see port.c, port_common.c, or other assembly files + * ------------------------------------------------------------------------------------------------------------------ */ -void vApplicationSleep( TickType_t xExpectedIdleTime ); -#define portSUPPRESS_TICKS_AND_SLEEP( idleTime ) vApplicationSleep( idleTime ) +// --------------------- Interrupts ------------------------ -#define portNOP() __asm volatile ( " nop " ) +static inline unsigned portENTER_CRITICAL_NESTED(void) +{ + unsigned state = portSET_INTERRUPT_MASK_FROM_ISR(); + return state; +} -#define portVALID_TCB_MEM(ptr) esp_ptr_byte_accessible(ptr) -#define portVALID_STACK_MEM(ptr) esp_ptr_byte_accessible(ptr) +// ---------------------- Spinlocks ------------------------ -/* Get tick rate per second */ -uint32_t xPortGetTickRateHz(void); +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ + compare_and_set_native(addr, compare, set); +} -// configASSERT_2 if requested -#if configASSERT_2 -#include -void exit(int); -#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); } +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ +#if defined(CONFIG_SPIRAM) + compare_and_set_extram(addr, compare, set); #endif +} +// ---------------------- Yielding ------------------------- -#endif //__ASSEMBLER__ +static inline bool IRAM_ATTR xPortCanYield(void) +{ + uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG); + /* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL + * and exit critical code, will recover threshold value (1). so threshold <= 1 + * means not in critical code + */ + return (threshold <= 1); +} + + + +/* ------------------------------------------------------ Misc --------------------------------------------------------- + * - Miscellaneous porting macros + * - These are not port of the FreeRTOS porting interface, but are used by other FreeRTOS dependent components + * ------------------------------------------------------------------------------------------------------------------ */ + +// -------------------- Heap Related ----------------------- + +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); + +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) #ifdef __cplusplus } #endif +#endif //__ASSEMBLER__ + #endif /* PORTMACRO_H */ diff --git a/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/i2s_ll.h b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/i2s_ll.h index 670db91616b..0cfb05a266a 100644 --- a/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/i2s_ll.h +++ b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/i2s_ll.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // The LL layer for I2S register operations /******************************************************************************* @@ -86,6 +78,26 @@ static inline void i2s_ll_rx_enable_clock(i2s_dev_t *hw) hw->rx_clkm_conf.rx_clk_active = 1; } +/** + * @brief Disable I2S tx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw) +{ + hw->tx_clkm_conf.tx_clk_active = 0; +} + +/** + * @brief Disable I2S rx module clock + * + * @param hw Peripheral I2S hardware instance address. + */ +static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw) +{ + hw->rx_clkm_conf.rx_clk_active = 0; +} + /** * @brief I2S mclk use tx module clock * diff --git a/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/rmt_ll.h b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/rmt_ll.h index 0f703aebc75..662e63f784e 100644 --- a/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/rmt_ll.h +++ b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -23,6 +16,9 @@ extern "C" { #endif + +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ + #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) diff --git a/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/uhci_types.h b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/uhci_types.h new file mode 100644 index 00000000000..7b7f41d0f94 --- /dev/null +++ b/tools/sdk/esp32c3/include/hal/esp32c3/include/hal/uhci_types.h @@ -0,0 +1,54 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +// Though the UHCI driver hasn't been published, some types are defined here +// for users to develop over the HAL. See example: controller_hci_uart_esp32c3 + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * @brief UHCI escape sequence + */ +typedef struct { + uint8_t seper_chr; /*!< escape sequence character */ + uint8_t sub_chr1; /*!< escape sequence sub-character 1 */ + uint8_t sub_chr2; /*!< escape sequence sub-character 2 */ + bool sub_chr_en; /*!< enable use of sub-chaacter of escape sequence */ +} uhci_seper_chr_t; + +/** + * @brief UHCI software flow control + */ +typedef struct { + uint8_t xon_chr; /*!< character for XON */ + uint8_t xon_sub1; /*!< sub-character 1 for XON */ + uint8_t xon_sub2; /*!< sub-character 2 for XON */ + uint8_t xoff_chr; /*!< character 2 for XOFF */ + uint8_t xoff_sub1; /*!< sub-character 1 for XOFF */ + uint8_t xoff_sub2; /*!< sub-character 2 for XOFF */ + uint8_t flow_en; /*!< enable use of software flow control */ +} uhci_swflow_ctrl_sub_chr_t; + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32c3/include/hal/include/hal/i2s_hal.h b/tools/sdk/esp32c3/include/hal/include/hal/i2s_hal.h index a08813db808..037970fa2b3 100644 --- a/tools/sdk/esp32c3/include/hal/include/hal/i2s_hal.h +++ b/tools/sdk/esp32c3/include/hal/include/hal/i2s_hal.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -176,28 +168,28 @@ void i2s_hal_enable_slave_fd_mode(i2s_hal_context_t *hal); * * @param hal Context of the HAL layer */ -#define i2s_hal_start_tx(hal) i2s_ll_tx_start((hal)->dev) +void i2s_hal_start_tx(i2s_hal_context_t *hal); /** * @brief Start I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_start_rx(hal) i2s_ll_rx_start((hal)->dev) +void i2s_hal_start_rx(i2s_hal_context_t *hal); /** * @brief Stop I2S tx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_tx(hal) i2s_ll_tx_stop((hal)->dev) +void i2s_hal_stop_tx(i2s_hal_context_t *hal); /** * @brief Stop I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_rx(hal) i2s_ll_rx_stop((hal)->dev) +void i2s_hal_stop_rx(i2s_hal_context_t *hal); /** * @brief Set the received data length to trigger `in_suc_eof` interrupt. diff --git a/tools/sdk/esp32c3/include/hal/include/hal/lcd_hal.h b/tools/sdk/esp32c3/include/hal/include/hal/lcd_hal.h index 76e28dda0e4..db255b3d1e4 100644 --- a/tools/sdk/esp32c3/include/hal/include/hal/lcd_hal.h +++ b/tools/sdk/esp32c3/include/hal/include/hal/lcd_hal.h @@ -1,22 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * NOTICE - * The HAL is not public api, don't use in application code. - * See readme.md in soc/README.md - ******************************************************************************/ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/tools/sdk/esp32c3/include/hal/include/hal/lcd_types.h b/tools/sdk/esp32c3/include/hal/include/hal/lcd_types.h index 69dab14801d..01e6d0c2949 100644 --- a/tools/sdk/esp32c3/include/hal/include/hal/lcd_types.h +++ b/tools/sdk/esp32c3/include/hal/include/hal/lcd_types.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -21,15 +13,12 @@ extern "C" { /** * @brief LCD clock source * @note User should select the clock source based on the real requirement: - * ╔═════════════════════╦══════════════════════════╦════════════════════════════╗ - * ║ LCD clock source ║ Features ║ Power Management ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_PLL160M ║ High resolution, fixed ║ ESP_PM_APB_FREQ_MAX lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_APLL ║ Configurable resolution ║ ESP_PM_NO_LIGHT_SLEEP lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_XTAL ║ Medium resolution, fixed ║ No PM lock ║ - * ╚═════════════════════╩══════════════════════════╩════════════════════════════╝ + * + * | LCD clock source | Features | Power Management | + * |---------------------|--------------------------|----------------------------| + * | LCD_CLK_SRC_PLL160M | High resolution, fixed | ESP_PM_APB_FREQ_MAX lock | + * | LCD_CLK_SRC_APLL | Configurable resolution | ESP_PM_NO_LIGHT_SLEEP lock | + * | LCD_CLK_SRC_XTAL | Medium resolution, fixed | No PM lock | */ typedef enum { LCD_CLK_SRC_PLL160M, /*!< Select PLL160M as the source clock */ diff --git a/tools/sdk/esp32c3/include/hal/include/hal/touch_sensor_types.h b/tools/sdk/esp32c3/include/hal/include/hal/touch_sensor_types.h index ec027bf8705..9085f5eecd8 100644 --- a/tools/sdk/esp32c3/include/hal/include/hal/touch_sensor_types.h +++ b/tools/sdk/esp32c3/include/hal/include/hal/touch_sensor_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -155,12 +147,23 @@ typedef enum { TOUCH_PAD_INTR_MASK_INACTIVE = BIT(2), /*! +#include +#include "sdkconfig.h" +#include "esp_err.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#endif +#include "esp_flash.h" +#include "hal/spi_flash_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief To setup Flash chip + */ +esp_err_t spi_flash_init_chip_state(void); + +/** + * @brief Make MSPI work under 20Mhz + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_low_speed_mode(bool control_spi1); + +/** + * @brief Make MSPI work under the frequency as users set + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_high_speed_mode(bool control_spi1); + +/** + * @brief Tune MSPI flash timing to make it work under high frequency + */ +void spi_timing_flash_tuning(void); + +/** + * @brief Tune MSPI psram timing to make it work under high frequency + */ +void spi_timing_psram_tuning(void); + +/** + * @brief To initislize the MSPI pins + */ +void esp_mspi_pin_init(void); + +/** + * @brief Set SPI1 registers to make ROM functions work + * @note This function is used for setting SPI1 registers to the state that ROM SPI functions work + */ +void spi_flash_set_rom_required_regs(void); + +/** + * @brief Initialize main flash + * @param chip Pointer to main SPI flash(SPI1 CS0) chip to use.. + */ +esp_err_t esp_flash_init_main(esp_flash_t *chip); + +/** + * @brief Should be only used by SPI1 Flash driver to know the necessary timing registers + * @param out_timing_config Pointer to timing_tuning parameters. + */ +void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing_config); + +/** + * @brief Judge if the flash in tuned + */ +bool spi_timine_config_flash_is_tuned(void); + +/** + * @brief Set Flash chip specifically required MSPI register settings here + */ +void spi_flash_set_vendor_required_regs(void); + + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h b/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h new file mode 100644 index 00000000000..4292213943f --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ESP_MBO_H +#define _ESP_MBO_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum non_pref_chan_reason: Reason for non preference of channel + */ +enum non_pref_chan_reason { + NON_PREF_CHAN_REASON_UNSPECIFIED = 0, + NON_PREF_CHAN_REASON_RSSI = 1, + NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, + NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, +}; + +/** + * @brief Channel structure for non preferred channel + * + * @param reason: enum non_pref_chan_reason + * @param oper_class: operating class for the channel + * @param chan: channel number + * @param preference: channel preference + */ +struct non_pref_chan { + enum non_pref_chan_reason reason; + uint8_t oper_class; + uint8_t chan; + uint8_t preference; +}; + +/** + * @brief Array structure for non preferred channel struct + * + * @param non_pref_chan_num: channel count + * @param chan: array of non_pref_chan type + */ +struct non_pref_chan_s { + size_t non_pref_chan_num; + struct non_pref_chan chan[]; +}; + +/** + * @brief Update channel preference for MBO IE + * + * @param non_pref_chan: Non preference channel list + * + * @return + * - 0: success else failure + */ +int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h b/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h index a1dcfb655c5..4301385d2cf 100644 --- a/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h +++ b/tools/sdk/esp32c3/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef _ESP_WNM_H @@ -29,11 +19,13 @@ enum btm_query_reason { REASON_UNSPECIFIED = 0, REASON_FRAME_LOSS = 1, REASON_DELAY = 2, - REASON_QOS_CAPACITY = 3, - REASON_FIRST_ASSOC = 4, - REASON_LOAD_BALALNCE = 5, - REASON_BETTER_AP = 6, - REASON_CURRENT_DEAUTH = 7, + REASON_BANDWIDTH = 3, + REASON_LOAD_BALANCE = 4, + REASON_RSSI = 5, + REASON_RETRANSMISSIONS = 6, + REASON_INTERFERENCE = 7, + REASON_GRAY_ZONE = 8, + REASON_PREMIUM_AP = 9, }; /** diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h new file mode 100644 index 00000000000..c6c86bc536f --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h @@ -0,0 +1,116 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_DPP_H +#define ESP_DPP_H + +#include + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ +#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */ +#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ + +/** @brief Types of Bootstrap Methods for DPP. */ +typedef enum dpp_bootstrap_type { + DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ + DPP_BOOTSTRAP_PKEX, /**< Proof of Knowledge Method */ + DPP_BOOTSTRAP_NFC_URI, /**< NFC URI record Method */ +} esp_supp_dpp_bootstrap_t; + +/** @brief Types of Callback Events received from DPP Supplicant. */ +typedef enum { + ESP_SUPP_DPP_URI_READY, /**< URI is ready through Bootstrapping */ + ESP_SUPP_DPP_CFG_RECVD, /**< Config received via DPP Authentication */ + ESP_SUPP_DPP_FAIL, /**< DPP Authentication failure */ +} esp_supp_dpp_event_t; + +/** + * @brief Callback function for receiving DPP Events from Supplicant. + * + * Callback function will be called with DPP related information. + * + * @param evt DPP event ID + * @param data Event data payload + */ +typedef void (*esp_supp_dpp_event_cb_t)(esp_supp_dpp_event_t evt, void *data); + +/** + * @brief Initialize DPP Supplicant + * + * Starts DPP Supplicant and initializes related Data Structures. + * + * @param evt_cb Callback function to receive DPP related events + * + * return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t evt_cb); + +/** + * @brief De-initalize DPP Supplicant + * + * Frees memory from DPP Supplicant Data Structures. + */ +void esp_supp_dpp_deinit(void); + +/** + * @brief Generates Bootstrap Information as an Enrollee. + * + * Generates Out Of Band Bootstrap information as an Enrollee which can be + * used by a DPP Configurator to provision the Enrollee. + * + * @param chan_list List of channels device will be available on for listening + * @param type Bootstrap method type, only QR Code method is supported for now. + * @param key (Optional) Private Key used to generate a Bootstrapping Public Key + * @param info (Optional) Ancilliary Device Information like Serial Number + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t +esp_supp_dpp_bootstrap_gen(const char *chan_list, esp_supp_dpp_bootstrap_t type, + const char *key, const char *info); + +/** + * @brief Start listening on Channels provided during esp_supp_dpp_bootstrap_gen. + * + * Listens on every Channel from Channel List for a pre-defined wait time. + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Generic Failure + * - ESP_ERR_INVALID_STATE: ROC attempted before WiFi is started + * - ESP_ERR_NO_MEM: Memory allocation failed while posting ROC request + */ +esp_err_t esp_supp_dpp_start_listen(void); + +/** + * @brief Stop listening on Channels. + * + * Stops listening on Channels and cancels ongoing listen operation. + */ +void esp_supp_dpp_stop_listen(void); + +#ifdef __cplusplus +} +#endif +#endif /* ESP_DPP_H */ diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h new file mode 100644 index 00000000000..1ffcf180475 --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h @@ -0,0 +1,52 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_RRM_H +#define _ESP_RRM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Callback function type to get neighbor report + * + * @param ctx: neighbor report context + * @param report: neighbor report + * @param report_len: neighbor report length + * + * @return + * - void + */ +typedef void (*neighbor_rep_request_cb)(void *ctx, const uint8_t *report, size_t report_len); + +/** + * @brief Send Radio measurement neighbor report request to connected AP + * + * @param cb: callback function for neighbor report + * @param cb_ctx: callback context + * + * @return + * - 0: success else failure + */ +int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb, + void *cb_ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h new file mode 100644 index 00000000000..a1dcfb655c5 --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h @@ -0,0 +1,56 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_WNM_H +#define _ESP_WNM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum btm_query_reason: Reason code for sending btm query + */ +enum btm_query_reason { + REASON_UNSPECIFIED = 0, + REASON_FRAME_LOSS = 1, + REASON_DELAY = 2, + REASON_QOS_CAPACITY = 3, + REASON_FIRST_ASSOC = 4, + REASON_LOAD_BALALNCE = 5, + REASON_BETTER_AP = 6, + REASON_CURRENT_DEAUTH = 7, +}; + +/** + * @brief Send bss transition query to connected AP + * + * @param query_reason: reason for sending query + * @param btm_candidates: btm candidates list if available + * @param cand_list: whether candidate list to be included from scan results available in supplicant's cache. + * + * @return + * - 0: success else failure + */ +int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, + const char *btm_candidates, + int cand_list); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h new file mode 100644 index 00000000000..f448b737c70 --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h @@ -0,0 +1,79 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPA_H__ +#define __ESP_WPA_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_wifi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPA_APIs WPS APIs + * @brief ESP32 Supplicant APIs + * + */ + +/** @addtogroup WPA_APIs + * @{ + */ +/* Crypto callback functions */ +const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; +/* Mesh crypto callback functions */ +const mesh_crypto_funcs_t g_wifi_default_mesh_crypto_funcs; + +/** + * @brief Supplicant initialization + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_NO_MEM : out of memory + */ +esp_err_t esp_supplicant_init(void); + +/** + * @brief Supplicant deinitialization + * + * @return + * - ESP_OK : succeed + * - others: failed + */ +esp_err_t esp_supplicant_deinit(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPA_H__ */ diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h new file mode 100644 index 00000000000..c6c2930a0fe --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h @@ -0,0 +1,215 @@ +// Hardware crypto support Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_WPA2_H +#define _ESP_WPA2_H + +#include + +#include "esp_err.h" + +typedef enum { + ESP_EAP_TTLS_PHASE2_EAP, + ESP_EAP_TTLS_PHASE2_MSCHAPV2, + ESP_EAP_TTLS_PHASE2_MSCHAP, + ESP_EAP_TTLS_PHASE2_PAP, + ESP_EAP_TTLS_PHASE2_CHAP +} esp_eap_ttls_phase2_types ; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_enable(void); + +/** + * @brief Disable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + */ +esp_err_t esp_wifi_sta_wpa2_ent_disable(void); + +/** + * @brief Set identity for PEAP/TTLS method. + * + * @attention The API only passes the parameter identity to the global pointer variable in wpa2 enterprise module. + * + * @param identity: point to address where stores the identity; + * @param len: length of identity, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len); + +/** + * @brief Clear identity for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_identity(void); + +/** + * @brief Set username for PEAP/TTLS method. + * + * @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module. + * + * @param username: point to address where stores the username; + * @param len: length of username, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len); + +/** + * @brief Clear username for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_username(void); + +/** + * @brief Set password for PEAP/TTLS method.. + * + * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * + * @param password: point to address where stores the password; + * @param len: length of password(len > 0) + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len); + +/** + * @brief Clear password for PEAP/TTLS method.. + */ +void esp_wifi_sta_wpa2_ent_clear_password(void); + +/** + * @brief Set new password for MSCHAPv2 method.. + * + * @attention 1. The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * @attention 2. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. + * + * @param new_password: point to address where stores the password; + * @param len: length of password + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ + +esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len); + +/** + * @brief Clear new password for MSCHAPv2 method.. + */ +void esp_wifi_sta_wpa2_ent_clear_new_password(void); + +/** + * @brief Set CA certificate for PEAP/TTLS method. + * + * @attention 1. The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. + * @attention 2. The ca_cert should be zero terminated. + * + * @param ca_cert: point to address where stores the CA certificate; + * @param ca_cert_len: length of ca_cert + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len); + +/** + * @brief Clear CA certificate for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); + +/** + * @brief Set client certificate and key. + * + * @attention 1. The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. + * @attention 2. The client_cert, private_key and private_key_passwd should be zero terminated. + * + * @param client_cert: point to address where stores the client certificate; + * @param client_cert_len: length of client certificate; + * @param private_key: point to address where stores the private key; + * @param private_key_len: length of private key, limited to 1~2048; + * @param private_key_password: point to address where stores the private key password; + * @param private_key_password_len: length of private key password; + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len); + +/** + * @brief Clear client certificate and key. + */ +void esp_wifi_sta_wpa2_ent_clear_cert_key(void); + +/** + * @brief Set wpa2 enterprise certs time check(disable or not). + * + * @param true: disable wpa2 enterprise certs time check + * @param false: enable wpa2 enterprise certs time check + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); + +/** + * @brief Get wpa2 enterprise certs time check(disable or not). + * + * @param disable: store disable value + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); + +/** + * @brief Set wpa2 enterprise ttls phase2 method + * + * @param type: the type of phase 2 method to be used + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wps.h b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wps.h new file mode 100644 index 00000000000..25c06782ecb --- /dev/null +++ b/tools/sdk/esp32c3/include/wpa_supplicant/include/esp_supplicant/esp_wps.h @@ -0,0 +1,141 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPS_H__ +#define __ESP_WPS_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP32 WPS APIs + * + * WPS can only be used when ESP32 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +#define ESP_ERR_WIFI_REGISTRAR (ESP_ERR_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ +#define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_MAX, +} wps_type_t; + +#define WPS_MAX_MANUFACTURER_LEN 65 +#define WPS_MAX_MODEL_NUMBER_LEN 33 +#define WPS_MAX_MODEL_NAME_LEN 33 +#define WPS_MAX_DEVICE_NAME_LEN 33 + +typedef struct { + char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer, null-terminated string. The default manufcturer is used if the string is empty */ + char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number, null-terminated string. The default model number is used if the string is empty */ + char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name, null-terminated string. The default model name is used if the string is empty */ + char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name, null-terminated string. The default device name is used if the string is empty */ +} wps_factory_information_t; + +typedef struct { + wps_type_t wps_type; + wps_factory_information_t factory_info; +} esp_wps_config_t; + +#define WPS_CONFIG_INIT_DEFAULT(type) { \ + .wps_type = type, \ + .factory_info = { \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP32") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_name, "ESPRESSIF IOT") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(device_name, "ESP STATION") \ + } \ +} + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_enable(const esp_wps_config_t *config); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + */ +esp_err_t esp_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time (not supported in IDF v1.0) + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_start(int timeout_ms); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPS_H__ */ diff --git a/tools/sdk/esp32c3/ld/sections.ld b/tools/sdk/esp32c3/ld/sections.ld index 2338ee8b467..68e195517e9 100644 --- a/tools/sdk/esp32c3/ld/sections.ld +++ b/tools/sdk/esp32c3/ld/sections.ld @@ -1,6 +1,6 @@ /* Automatically generated file; DO NOT EDIT */ /* Espressif IoT Development Framework Linker Script */ -/* Generated from: /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32c3/sections.ld.in */ +/* Generated from: /home/rocorbera/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32c3/sections.ld.in */ /* * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD @@ -163,7 +163,7 @@ SECTIONS *libesp_system.a:esp_system.*(.literal.esp_system_abort .text.esp_system_abort) *libesp_system.a:ubsan.*(.literal .literal.* .text .text.*) *libfreertos.a:(EXCLUDE_FILE(*libfreertos.a:port.* *libfreertos.a:port_common.*) .literal EXCLUDE_FILE(*libfreertos.a:port.* *libfreertos.a:port_common.*) .literal.* EXCLUDE_FILE(*libfreertos.a:port.* *libfreertos.a:port_common.*) .text EXCLUDE_FILE(*libfreertos.a:port.* *libfreertos.a:port_common.*) .text.*) - *libfreertos.a:port.*(.text .text.prvTaskExitError .text.pxPortInitialiseStack .text.vApplicationStackOverflowHook .text.vPortCPUAcquireMutex .text.vPortCPUAcquireMutexTimeout .text.vPortCPUInitializeMutex .text.vPortCPUReleaseMutex .text.vPortClearInterruptMask .text.vPortEndScheduler .text.vPortEnterCritical .text.vPortExitCritical .text.vPortSetInterruptMask .text.vPortSetStackWatchpoint .text.vPortYield .text.vPortYieldFromISR .text.vPortYieldOtherCore .text.xPortGetTickRateHz .text.xPortInIsrContext .text.xPortStartScheduler) + *libfreertos.a:port.*(.text .text.prvTaskExitError .text.pxPortInitialiseStack .text.unlikely.vPortEndScheduler .text.vApplicationStackOverflowHook .text.vPortCPUAcquireMutex .text.vPortCPUAcquireMutexTimeout .text.vPortCPUInitializeMutex .text.vPortCPUReleaseMutex .text.vPortClearInterruptMask .text.vPortEnterCritical .text.vPortExitCritical .text.vPortSetInterruptMask .text.vPortSetStackWatchpoint .text.vPortYield .text.vPortYieldFromISR .text.vPortYieldOtherCore .text.xPortGetTickRateHz .text.xPortInIsrContext .text.xPortStartScheduler) *libfreertos.a:port_common.*(.text .text.esp_startup_start_app_common) *libgcc.a:_divsf3.*(.literal .literal.* .text .text.*) *libgcc.a:lib2funcs.*(.literal .literal.* .text .text.*) @@ -311,8 +311,8 @@ SECTIONS _bss_start = ABSOLUTE(.); *(.bss .bss.*) - *(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem) *(.ext_ram.bss .ext_ram.bss.*) + *(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem) *(COMMON) _bt_bss_start = ABSOLUTE(.); *libbt.a:(.bss .bss.* COMMON) @@ -358,8 +358,8 @@ SECTIONS *(.wifislpiram .wifislpiram.*) *(.wifislprxiram .wifislprxiram.*) *libesp_event.a:default_event_loop.*(.text .text.esp_event_handler_instance_register .text.esp_event_handler_instance_unregister .text.esp_event_handler_register .text.esp_event_handler_unregister .text.esp_event_loop_create_default .text.esp_event_loop_delete_default .text.esp_event_post .text.esp_event_send_to_default_loop) - *libesp_event.a:esp_event.*(.text .text.base_node_add_handler .text.base_node_remove_all_handler .text.base_node_remove_handler .text.esp_event_dump .text.esp_event_handler_instance_register_with .text.esp_event_handler_instance_unregister_with .text.esp_event_handler_register_with .text.esp_event_handler_register_with_internal .text.esp_event_handler_unregister_with .text.esp_event_handler_unregister_with_internal .text.esp_event_loop_create .text.esp_event_loop_delete .text.esp_event_loop_run .text.esp_event_loop_run_task .text.esp_event_post_to .text.handler_execute .text.handler_instances_add .text.handler_instances_remove .text.handler_instances_remove_all .text.loop_node_add_handler .text.loop_node_remove_all_handler .text.loop_node_remove_handler) - *libesp_hw_support.a:rtc_init.*(.text .text.calibrate_ocode .text.get_dig_dbias_by_efuse .text.get_rtc_dbias_by_efuse .text.rtc_init .text.rtc_vddsdio_get_config .text.set_ocode_by_efuse .text.set_rtc_dig_dbias) + *libesp_event.a:esp_event.*(.text .text.base_node_add_handler .text.esp_event_dump .text.esp_event_handler_instance_register_with .text.esp_event_handler_instance_unregister_with .text.esp_event_handler_register_with .text.esp_event_handler_register_with_internal .text.esp_event_handler_unregister_with .text.esp_event_handler_unregister_with_internal .text.esp_event_loop_create .text.esp_event_loop_delete .text.esp_event_loop_run .text.esp_event_loop_run_task .text.esp_event_post_to .text.handler_instances_add.isra.2 .text.handler_instances_remove.isra.3 .text.handler_instances_remove_all.isra.1 .text.loop_node_add_handler) + *libesp_hw_support.a:rtc_init.*(.text .text.get_rtc_dbias_by_efuse .text.rtc_init .text.rtc_vddsdio_get_config) *libesp_system.a:esp_system.*(.text .text.esp_get_free_heap_size .text.esp_get_free_internal_heap_size .text.esp_get_idf_version .text.esp_get_minimum_free_heap_size .text.esp_register_shutdown_handler .text.esp_unregister_shutdown_handler) *libfreertos.a:port.*(.literal.esp_startup_start_app .text.esp_startup_start_app) *libfreertos.a:port_common.*(.literal.main_task .text.main_task) diff --git a/tools/sdk/esp32c3/lib/libapp_trace.a b/tools/sdk/esp32c3/lib/libapp_trace.a index f41ecffbefc..7eff52b81f3 100644 Binary files a/tools/sdk/esp32c3/lib/libapp_trace.a and b/tools/sdk/esp32c3/lib/libapp_trace.a differ diff --git a/tools/sdk/esp32c3/lib/libapp_update.a b/tools/sdk/esp32c3/lib/libapp_update.a index a76a5a0d19e..fda94f29c36 100644 Binary files a/tools/sdk/esp32c3/lib/libapp_update.a and b/tools/sdk/esp32c3/lib/libapp_update.a differ diff --git a/tools/sdk/esp32c3/lib/libasio.a b/tools/sdk/esp32c3/lib/libasio.a index e501be2ec82..7c9a4587b32 100644 Binary files a/tools/sdk/esp32c3/lib/libasio.a and b/tools/sdk/esp32c3/lib/libasio.a differ diff --git a/tools/sdk/esp32c3/lib/libbootloader_support.a b/tools/sdk/esp32c3/lib/libbootloader_support.a index 8dee3407a13..afbe9cd0f23 100644 Binary files a/tools/sdk/esp32c3/lib/libbootloader_support.a and b/tools/sdk/esp32c3/lib/libbootloader_support.a differ diff --git a/tools/sdk/esp32c3/lib/libbt.a b/tools/sdk/esp32c3/lib/libbt.a index 97808822530..f3ef270dece 100644 Binary files a/tools/sdk/esp32c3/lib/libbt.a and b/tools/sdk/esp32c3/lib/libbt.a differ diff --git a/tools/sdk/esp32c3/lib/libcbor.a b/tools/sdk/esp32c3/lib/libcbor.a index a219da6d5a6..4cfba9c3784 100644 Binary files a/tools/sdk/esp32c3/lib/libcbor.a and b/tools/sdk/esp32c3/lib/libcbor.a differ diff --git a/tools/sdk/esp32c3/lib/libcmock.a b/tools/sdk/esp32c3/lib/libcmock.a index 83c28caad7a..41551bf0bc6 100644 Binary files a/tools/sdk/esp32c3/lib/libcmock.a and b/tools/sdk/esp32c3/lib/libcmock.a differ diff --git a/tools/sdk/esp32c3/lib/libcoap.a b/tools/sdk/esp32c3/lib/libcoap.a index 407310ba1cb..681f2c4314b 100644 Binary files a/tools/sdk/esp32c3/lib/libcoap.a and b/tools/sdk/esp32c3/lib/libcoap.a differ diff --git a/tools/sdk/esp32c3/lib/libcoexist.a b/tools/sdk/esp32c3/lib/libcoexist.a index 6f03cab0b8e..de5915cbc2d 100644 Binary files a/tools/sdk/esp32c3/lib/libcoexist.a and b/tools/sdk/esp32c3/lib/libcoexist.a differ diff --git a/tools/sdk/esp32c3/lib/libconsole.a b/tools/sdk/esp32c3/lib/libconsole.a index 91bd32add2d..fbe3a0f478c 100644 Binary files a/tools/sdk/esp32c3/lib/libconsole.a and b/tools/sdk/esp32c3/lib/libconsole.a differ diff --git a/tools/sdk/esp32c3/lib/libcore.a b/tools/sdk/esp32c3/lib/libcore.a index 10e7ca5a83b..38e7e437963 100644 Binary files a/tools/sdk/esp32c3/lib/libcore.a and b/tools/sdk/esp32c3/lib/libcore.a differ diff --git a/tools/sdk/esp32c3/lib/libcxx.a b/tools/sdk/esp32c3/lib/libcxx.a index 9617dd86b74..b199d7aa54c 100644 Binary files a/tools/sdk/esp32c3/lib/libcxx.a and b/tools/sdk/esp32c3/lib/libcxx.a differ diff --git a/tools/sdk/esp32c3/lib/libdriver.a b/tools/sdk/esp32c3/lib/libdriver.a index 71809d7ec58..2b2edd65f2a 100644 Binary files a/tools/sdk/esp32c3/lib/libdriver.a and b/tools/sdk/esp32c3/lib/libdriver.a differ diff --git a/tools/sdk/esp32c3/lib/libefuse.a b/tools/sdk/esp32c3/lib/libefuse.a index f4bb53d7dae..f69ecd5ff9f 100644 Binary files a/tools/sdk/esp32c3/lib/libefuse.a and b/tools/sdk/esp32c3/lib/libefuse.a differ diff --git a/tools/sdk/esp32c3/lib/libesp-tls.a b/tools/sdk/esp32c3/lib/libesp-tls.a index 4e304a6646f..ed5a59d34d0 100644 Binary files a/tools/sdk/esp32c3/lib/libesp-tls.a and b/tools/sdk/esp32c3/lib/libesp-tls.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_adc_cal.a b/tools/sdk/esp32c3/lib/libesp_adc_cal.a index 757dbdaf9da..7d130e58842 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_adc_cal.a and b/tools/sdk/esp32c3/lib/libesp_adc_cal.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_common.a b/tools/sdk/esp32c3/lib/libesp_common.a index 577a8884b7f..28d077f9477 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_common.a and b/tools/sdk/esp32c3/lib/libesp_common.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_eth.a b/tools/sdk/esp32c3/lib/libesp_eth.a index 457368b2747..927204ecbf8 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_eth.a and b/tools/sdk/esp32c3/lib/libesp_eth.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_event.a b/tools/sdk/esp32c3/lib/libesp_event.a index eb12ef2bb70..29283e41d09 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_event.a and b/tools/sdk/esp32c3/lib/libesp_event.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_gdbstub.a b/tools/sdk/esp32c3/lib/libesp_gdbstub.a index e7c39833d73..d6c4c5ef988 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_gdbstub.a and b/tools/sdk/esp32c3/lib/libesp_gdbstub.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_hid.a b/tools/sdk/esp32c3/lib/libesp_hid.a index f976d5ab228..706037a7d5a 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_hid.a and b/tools/sdk/esp32c3/lib/libesp_hid.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_http_client.a b/tools/sdk/esp32c3/lib/libesp_http_client.a index f82ad10086d..37a878524c4 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_http_client.a and b/tools/sdk/esp32c3/lib/libesp_http_client.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_http_server.a b/tools/sdk/esp32c3/lib/libesp_http_server.a index 78a0206aab2..355ec65e0ee 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_http_server.a and b/tools/sdk/esp32c3/lib/libesp_http_server.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_https_ota.a b/tools/sdk/esp32c3/lib/libesp_https_ota.a index e1702191f75..69db16ad2e4 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_https_ota.a and b/tools/sdk/esp32c3/lib/libesp_https_ota.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_https_server.a b/tools/sdk/esp32c3/lib/libesp_https_server.a index 41c852b2f76..ccfd4341439 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_https_server.a and b/tools/sdk/esp32c3/lib/libesp_https_server.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_hw_support.a b/tools/sdk/esp32c3/lib/libesp_hw_support.a index 441d8231622..f4e14f2cbb9 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_hw_support.a and b/tools/sdk/esp32c3/lib/libesp_hw_support.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_ipc.a b/tools/sdk/esp32c3/lib/libesp_ipc.a index cb9181592e1..8830da85b91 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_ipc.a and b/tools/sdk/esp32c3/lib/libesp_ipc.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_lcd.a b/tools/sdk/esp32c3/lib/libesp_lcd.a index d5f9a5d15a7..d2f5536b94b 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_lcd.a and b/tools/sdk/esp32c3/lib/libesp_lcd.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_littlefs.a b/tools/sdk/esp32c3/lib/libesp_littlefs.a index 10ece18e6f5..f6d69d9d15c 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_littlefs.a and b/tools/sdk/esp32c3/lib/libesp_littlefs.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_local_ctrl.a b/tools/sdk/esp32c3/lib/libesp_local_ctrl.a index 79208e5d357..ad7af8ee088 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_local_ctrl.a and b/tools/sdk/esp32c3/lib/libesp_local_ctrl.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_netif.a b/tools/sdk/esp32c3/lib/libesp_netif.a index 3deef9ca7dc..84bf77ab13f 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_netif.a and b/tools/sdk/esp32c3/lib/libesp_netif.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_phy.a b/tools/sdk/esp32c3/lib/libesp_phy.a index b2b9885f59f..c165fd7d275 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_phy.a and b/tools/sdk/esp32c3/lib/libesp_phy.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_pm.a b/tools/sdk/esp32c3/lib/libesp_pm.a index f32146b8ca0..64234aa8c4a 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_pm.a and b/tools/sdk/esp32c3/lib/libesp_pm.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_ringbuf.a b/tools/sdk/esp32c3/lib/libesp_ringbuf.a index d08c234dc5b..0476ba8bb2e 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_ringbuf.a and b/tools/sdk/esp32c3/lib/libesp_ringbuf.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_rom.a b/tools/sdk/esp32c3/lib/libesp_rom.a index b913f014ead..033d9763ba4 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_rom.a and b/tools/sdk/esp32c3/lib/libesp_rom.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_serial_slave_link.a b/tools/sdk/esp32c3/lib/libesp_serial_slave_link.a index 3a5cbd2b6ad..df39e93c9d3 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_serial_slave_link.a and b/tools/sdk/esp32c3/lib/libesp_serial_slave_link.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_system.a b/tools/sdk/esp32c3/lib/libesp_system.a index f8421329011..0a284c99a91 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_system.a and b/tools/sdk/esp32c3/lib/libesp_system.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_timer.a b/tools/sdk/esp32c3/lib/libesp_timer.a index d74a2ac003b..3387b3f582d 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_timer.a and b/tools/sdk/esp32c3/lib/libesp_timer.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_websocket_client.a b/tools/sdk/esp32c3/lib/libesp_websocket_client.a index d02f65a06fa..db82fbe8067 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_websocket_client.a and b/tools/sdk/esp32c3/lib/libesp_websocket_client.a differ diff --git a/tools/sdk/esp32c3/lib/libesp_wifi.a b/tools/sdk/esp32c3/lib/libesp_wifi.a index 3a89f878c94..f13aac369af 100644 Binary files a/tools/sdk/esp32c3/lib/libesp_wifi.a and b/tools/sdk/esp32c3/lib/libesp_wifi.a differ diff --git a/tools/sdk/esp32c3/lib/libespcoredump.a b/tools/sdk/esp32c3/lib/libespcoredump.a index 4af35b8b809..d2cbcdd66c0 100644 Binary files a/tools/sdk/esp32c3/lib/libespcoredump.a and b/tools/sdk/esp32c3/lib/libespcoredump.a differ diff --git a/tools/sdk/esp32c3/lib/libespnow.a b/tools/sdk/esp32c3/lib/libespnow.a index 0d53db2568a..8c792259076 100644 Binary files a/tools/sdk/esp32c3/lib/libespnow.a and b/tools/sdk/esp32c3/lib/libespnow.a differ diff --git a/tools/sdk/esp32c3/lib/libexpat.a b/tools/sdk/esp32c3/lib/libexpat.a index b2c4044a5b2..fe32c54f672 100644 Binary files a/tools/sdk/esp32c3/lib/libexpat.a and b/tools/sdk/esp32c3/lib/libexpat.a differ diff --git a/tools/sdk/esp32c3/lib/libfatfs.a b/tools/sdk/esp32c3/lib/libfatfs.a index 86f197e368c..7488eb97829 100644 Binary files a/tools/sdk/esp32c3/lib/libfatfs.a and b/tools/sdk/esp32c3/lib/libfatfs.a differ diff --git a/tools/sdk/esp32c3/lib/libfb_gfx.a b/tools/sdk/esp32c3/lib/libfb_gfx.a index 814a333e283..fd4538328ec 100644 Binary files a/tools/sdk/esp32c3/lib/libfb_gfx.a and b/tools/sdk/esp32c3/lib/libfb_gfx.a differ diff --git a/tools/sdk/esp32c3/lib/libfreemodbus.a b/tools/sdk/esp32c3/lib/libfreemodbus.a index b46ecaac145..6045742e019 100644 Binary files a/tools/sdk/esp32c3/lib/libfreemodbus.a and b/tools/sdk/esp32c3/lib/libfreemodbus.a differ diff --git a/tools/sdk/esp32c3/lib/libfreertos.a b/tools/sdk/esp32c3/lib/libfreertos.a index ac3c0fd50d1..1ce9b10f06d 100644 Binary files a/tools/sdk/esp32c3/lib/libfreertos.a and b/tools/sdk/esp32c3/lib/libfreertos.a differ diff --git a/tools/sdk/esp32c3/lib/libhal.a b/tools/sdk/esp32c3/lib/libhal.a index 12ad247f09c..b916b32503e 100644 Binary files a/tools/sdk/esp32c3/lib/libhal.a and b/tools/sdk/esp32c3/lib/libhal.a differ diff --git a/tools/sdk/esp32c3/lib/libheap.a b/tools/sdk/esp32c3/lib/libheap.a index 240bbab74e0..72278063dde 100644 Binary files a/tools/sdk/esp32c3/lib/libheap.a and b/tools/sdk/esp32c3/lib/libheap.a differ diff --git a/tools/sdk/esp32c3/lib/libjsmn.a b/tools/sdk/esp32c3/lib/libjsmn.a index 9861f83c0d1..7049385ba07 100644 Binary files a/tools/sdk/esp32c3/lib/libjsmn.a and b/tools/sdk/esp32c3/lib/libjsmn.a differ diff --git a/tools/sdk/esp32c3/lib/libjson.a b/tools/sdk/esp32c3/lib/libjson.a index 4ceb6b0a9a3..dc057de3923 100644 Binary files a/tools/sdk/esp32c3/lib/libjson.a and b/tools/sdk/esp32c3/lib/libjson.a differ diff --git a/tools/sdk/esp32c3/lib/liblibsodium.a b/tools/sdk/esp32c3/lib/liblibsodium.a index 8c9e365ef88..478dff06d96 100644 Binary files a/tools/sdk/esp32c3/lib/liblibsodium.a and b/tools/sdk/esp32c3/lib/liblibsodium.a differ diff --git a/tools/sdk/esp32c3/lib/liblog.a b/tools/sdk/esp32c3/lib/liblog.a index 4be299b20b5..1d7a6bf6570 100644 Binary files a/tools/sdk/esp32c3/lib/liblog.a and b/tools/sdk/esp32c3/lib/liblog.a differ diff --git a/tools/sdk/esp32c3/lib/liblwip.a b/tools/sdk/esp32c3/lib/liblwip.a index 668266754ba..6245b92f84c 100644 Binary files a/tools/sdk/esp32c3/lib/liblwip.a and b/tools/sdk/esp32c3/lib/liblwip.a differ diff --git a/tools/sdk/esp32c3/lib/libmbedcrypto.a b/tools/sdk/esp32c3/lib/libmbedcrypto.a index b1cb253b4d7..02ef0d7de16 100644 Binary files a/tools/sdk/esp32c3/lib/libmbedcrypto.a and b/tools/sdk/esp32c3/lib/libmbedcrypto.a differ diff --git a/tools/sdk/esp32c3/lib/libmbedtls.a b/tools/sdk/esp32c3/lib/libmbedtls.a index 3abdde11dd3..15e48d98ffa 100644 Binary files a/tools/sdk/esp32c3/lib/libmbedtls.a and b/tools/sdk/esp32c3/lib/libmbedtls.a differ diff --git a/tools/sdk/esp32c3/lib/libmbedx509.a b/tools/sdk/esp32c3/lib/libmbedx509.a index 3311a8bc098..615e0de0898 100644 Binary files a/tools/sdk/esp32c3/lib/libmbedx509.a and b/tools/sdk/esp32c3/lib/libmbedx509.a differ diff --git a/tools/sdk/esp32c3/lib/libmdns.a b/tools/sdk/esp32c3/lib/libmdns.a index b3df4d78b13..7ab99129098 100644 Binary files a/tools/sdk/esp32c3/lib/libmdns.a and b/tools/sdk/esp32c3/lib/libmdns.a differ diff --git a/tools/sdk/esp32c3/lib/libmesh.a b/tools/sdk/esp32c3/lib/libmesh.a index ac0bceb375b..caf1f0c2200 100644 Binary files a/tools/sdk/esp32c3/lib/libmesh.a and b/tools/sdk/esp32c3/lib/libmesh.a differ diff --git a/tools/sdk/esp32c3/lib/libmqtt.a b/tools/sdk/esp32c3/lib/libmqtt.a index 7b2acfde2a4..0ccdc763aa4 100644 Binary files a/tools/sdk/esp32c3/lib/libmqtt.a and b/tools/sdk/esp32c3/lib/libmqtt.a differ diff --git a/tools/sdk/esp32c3/lib/libnet80211.a b/tools/sdk/esp32c3/lib/libnet80211.a index 79f91f7f17d..659d0c256b4 100644 Binary files a/tools/sdk/esp32c3/lib/libnet80211.a and b/tools/sdk/esp32c3/lib/libnet80211.a differ diff --git a/tools/sdk/esp32c3/lib/libnewlib.a b/tools/sdk/esp32c3/lib/libnewlib.a index e0ebeacbfd1..11138c8ad4a 100644 Binary files a/tools/sdk/esp32c3/lib/libnewlib.a and b/tools/sdk/esp32c3/lib/libnewlib.a differ diff --git a/tools/sdk/esp32c3/lib/libnghttp.a b/tools/sdk/esp32c3/lib/libnghttp.a index ff7116554b6..285dc3afd2a 100644 Binary files a/tools/sdk/esp32c3/lib/libnghttp.a and b/tools/sdk/esp32c3/lib/libnghttp.a differ diff --git a/tools/sdk/esp32c3/lib/libnvs_flash.a b/tools/sdk/esp32c3/lib/libnvs_flash.a index 72bb887799b..b1c5f94783d 100644 Binary files a/tools/sdk/esp32c3/lib/libnvs_flash.a and b/tools/sdk/esp32c3/lib/libnvs_flash.a differ diff --git a/tools/sdk/esp32c3/lib/libopenssl.a b/tools/sdk/esp32c3/lib/libopenssl.a index 4019e41f7a4..54ca6b1c508 100644 Binary files a/tools/sdk/esp32c3/lib/libopenssl.a and b/tools/sdk/esp32c3/lib/libopenssl.a differ diff --git a/tools/sdk/esp32c3/lib/libpp.a b/tools/sdk/esp32c3/lib/libpp.a index 4891f8b5c92..0da117ad274 100644 Binary files a/tools/sdk/esp32c3/lib/libpp.a and b/tools/sdk/esp32c3/lib/libpp.a differ diff --git a/tools/sdk/esp32c3/lib/libprotobuf-c.a b/tools/sdk/esp32c3/lib/libprotobuf-c.a index 2427732f9a7..119a9e00ecc 100644 Binary files a/tools/sdk/esp32c3/lib/libprotobuf-c.a and b/tools/sdk/esp32c3/lib/libprotobuf-c.a differ diff --git a/tools/sdk/esp32c3/lib/libprotocomm.a b/tools/sdk/esp32c3/lib/libprotocomm.a index b604bd05cd1..587cc430ade 100644 Binary files a/tools/sdk/esp32c3/lib/libprotocomm.a and b/tools/sdk/esp32c3/lib/libprotocomm.a differ diff --git a/tools/sdk/esp32c3/lib/libpthread.a b/tools/sdk/esp32c3/lib/libpthread.a index b16b6ff4e64..3c11d275f0a 100644 Binary files a/tools/sdk/esp32c3/lib/libpthread.a and b/tools/sdk/esp32c3/lib/libpthread.a differ diff --git a/tools/sdk/esp32c3/lib/libriscv.a b/tools/sdk/esp32c3/lib/libriscv.a index fbb3ae7cc3b..50d55e14fe1 100644 Binary files a/tools/sdk/esp32c3/lib/libriscv.a and b/tools/sdk/esp32c3/lib/libriscv.a differ diff --git a/tools/sdk/esp32c3/lib/libsdmmc.a b/tools/sdk/esp32c3/lib/libsdmmc.a index 04cbb827fc5..6fec26d650c 100644 Binary files a/tools/sdk/esp32c3/lib/libsdmmc.a and b/tools/sdk/esp32c3/lib/libsdmmc.a differ diff --git a/tools/sdk/esp32c3/lib/libsmartconfig.a b/tools/sdk/esp32c3/lib/libsmartconfig.a index bd9cc0d4cee..bf215058c15 100644 Binary files a/tools/sdk/esp32c3/lib/libsmartconfig.a and b/tools/sdk/esp32c3/lib/libsmartconfig.a differ diff --git a/tools/sdk/esp32c3/lib/libsoc.a b/tools/sdk/esp32c3/lib/libsoc.a index 77e18e1335a..55e9ee9bb04 100644 Binary files a/tools/sdk/esp32c3/lib/libsoc.a and b/tools/sdk/esp32c3/lib/libsoc.a differ diff --git a/tools/sdk/esp32c3/lib/libspi_flash.a b/tools/sdk/esp32c3/lib/libspi_flash.a index ac3b0ee32af..47929fe9931 100644 Binary files a/tools/sdk/esp32c3/lib/libspi_flash.a and b/tools/sdk/esp32c3/lib/libspi_flash.a differ diff --git a/tools/sdk/esp32c3/lib/libspiffs.a b/tools/sdk/esp32c3/lib/libspiffs.a index 120571b2b86..bd23a13f863 100644 Binary files a/tools/sdk/esp32c3/lib/libspiffs.a and b/tools/sdk/esp32c3/lib/libspiffs.a differ diff --git a/tools/sdk/esp32c3/lib/libtcp_transport.a b/tools/sdk/esp32c3/lib/libtcp_transport.a index 42d386c8e1a..4d002f7f79f 100644 Binary files a/tools/sdk/esp32c3/lib/libtcp_transport.a and b/tools/sdk/esp32c3/lib/libtcp_transport.a differ diff --git a/tools/sdk/esp32c3/lib/libtcpip_adapter.a b/tools/sdk/esp32c3/lib/libtcpip_adapter.a index 316d8562b49..f8e71a389a8 100644 Binary files a/tools/sdk/esp32c3/lib/libtcpip_adapter.a and b/tools/sdk/esp32c3/lib/libtcpip_adapter.a differ diff --git a/tools/sdk/esp32c3/lib/libunity.a b/tools/sdk/esp32c3/lib/libunity.a index d35d93ca03f..3c654589c13 100644 Binary files a/tools/sdk/esp32c3/lib/libunity.a and b/tools/sdk/esp32c3/lib/libunity.a differ diff --git a/tools/sdk/esp32c3/lib/libvfs.a b/tools/sdk/esp32c3/lib/libvfs.a index 4b644d301c0..b9b19dc89f6 100644 Binary files a/tools/sdk/esp32c3/lib/libvfs.a and b/tools/sdk/esp32c3/lib/libvfs.a differ diff --git a/tools/sdk/esp32c3/lib/libwapi.a b/tools/sdk/esp32c3/lib/libwapi.a index 549b78aad96..7fe0160c721 100644 Binary files a/tools/sdk/esp32c3/lib/libwapi.a and b/tools/sdk/esp32c3/lib/libwapi.a differ diff --git a/tools/sdk/esp32c3/lib/libwear_levelling.a b/tools/sdk/esp32c3/lib/libwear_levelling.a index 8e320e50db7..cd06c15607a 100644 Binary files a/tools/sdk/esp32c3/lib/libwear_levelling.a and b/tools/sdk/esp32c3/lib/libwear_levelling.a differ diff --git a/tools/sdk/esp32c3/lib/libwifi_provisioning.a b/tools/sdk/esp32c3/lib/libwifi_provisioning.a index 08e7562e415..ea2006147e3 100644 Binary files a/tools/sdk/esp32c3/lib/libwifi_provisioning.a and b/tools/sdk/esp32c3/lib/libwifi_provisioning.a differ diff --git a/tools/sdk/esp32c3/lib/libwpa_supplicant.a b/tools/sdk/esp32c3/lib/libwpa_supplicant.a index 60617dc9981..3ab5d1284d0 100644 Binary files a/tools/sdk/esp32c3/lib/libwpa_supplicant.a and b/tools/sdk/esp32c3/lib/libwpa_supplicant.a differ diff --git a/tools/sdk/esp32c3/sdkconfig b/tools/sdk/esp32c3/sdkconfig index 85edbebed07..616ed46e954 100644 --- a/tools/sdk/esp32c3/sdkconfig +++ b/tools/sdk/esp32c3/sdkconfig @@ -62,7 +62,6 @@ CONFIG_BOOTLOADER_WDT_TIME_MS=9000 # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Bootloader config # @@ -93,7 +92,6 @@ CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set @@ -234,10 +232,19 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # CONFIG_BT_ENABLED=y +CONFIG_BT_CTRL_ESP32C3=y CONFIG_BT_SOC_SUPPORT_5_0=y +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 # -# Bluetooth controller +# Bluetooth controller(ESP32C3 Bluetooth Low Energy) # CONFIG_BT_CTRL_MODE_EFF=1 CONFIG_BT_CTRL_BLE_MAX_ACT=10 @@ -301,7 +308,12 @@ CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 CONFIG_BT_CTRL_HCI_TL_EFF=1 # CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set -# end of Bluetooth controller +# end of Bluetooth controller(ESP32C3 Bluetooth Low Energy) + +# +# MODEM SLEEP Options +# +# end of MODEM SLEEP Options CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -512,7 +524,11 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_BLE_RPA_SUPPORTED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +CONFIG_BT_RESERVE_DRAM=0xdb5c # end of Bluedroid Options + +CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=y +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y # end of Bluetooth # CONFIG_BLE_MESH is not set @@ -537,12 +553,6 @@ CONFIG_COAP_LOG_DEFAULT_LEVEL=0 CONFIG_ADC_DISABLE_DAC=y # end of ADC configuration -# -# MCPWM configuration -# -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# end of MCPWM configuration - # # SPI configuration # @@ -579,8 +589,6 @@ CONFIG_EFUSE_MAX_BLK_LEN=256 CONFIG_ESP_TLS_USING_MBEDTLS=y CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y CONFIG_ESP_TLS_SERVER=y -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS @@ -704,25 +712,12 @@ CONFIG_ESP32C3_UNIVERSAL_MAC_ADDRESSES=4 # Sleep Config # CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y -# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set # end of Sleep Config # end of Hardware Settings -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -# end of IPC (Inter-Processor Call) - # # LCD and Touch Panel # - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# end of LCD Peripheral Configuration # end of LCD and Touch Panel # @@ -766,11 +761,8 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y # # Memory protection # -CONFIG_ESP_SYSTEM_MEMPROT_DEPCHECK=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y -CONFIG_ESP_SYSTEM_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 -CONFIG_ESP_SYSTEM_MEMPROT_MEM_ALIGN_SIZE=512 # end of Memory protection CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 @@ -793,8 +785,8 @@ CONFIG_ESP_TASK_WDT=y # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y # end of ESP System Settings # @@ -912,8 +904,6 @@ CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 CONFIG_FMB_TIMER_PORT_ENABLED=y CONFIG_FMB_TIMER_GROUP=0 CONFIG_FMB_TIMER_INDEX=0 -CONFIG_FMB_MASTER_TIMER_GROUP=0 -CONFIG_FMB_MASTER_TIMER_INDEX=0 # CONFIG_FMB_TIMER_ISR_IN_IRAM is not set # end of Modbus configuration @@ -922,10 +912,8 @@ CONFIG_FMB_MASTER_TIMER_INDEX=0 # CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y -CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y -# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set -CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y @@ -955,8 +943,6 @@ CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set # end of FreeRTOS # @@ -1019,7 +1005,6 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_LOCAL_HOSTNAME="espressif" # CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # CONFIG_LWIP_L2_TO_L3_COPY is not set # CONFIG_LWIP_IRAM_OPTIMIZATION is not set @@ -1058,6 +1043,7 @@ CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=0 # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1126,8 +1112,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # # SNTP # -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 # end of SNTP @@ -1218,7 +1203,6 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1290,7 +1274,6 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 # CONFIG_MDNS_STRICT_MODE is not set CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set # end of mDNS # @@ -1433,6 +1416,11 @@ CONFIG_WS_BUFFER_SIZE=1024 # end of Websocket # end of TCP Transport +# +# TinyUSB +# +# end of TinyUSB + # # Unity unit testing library # @@ -1554,6 +1542,10 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 CONFIG_BLUEDROID_ENABLED=y # CONFIG_NIMBLE_ENABLED is not set CONFIG_BTC_TASK_STACK_SIZE=3072 @@ -1737,7 +1729,6 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_ESP_SYSTEM_PD_FLASH=y -CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y # CONFIG_ESP32S2_PANIC_PRINT_HALT is not set CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y @@ -1761,6 +1752,7 @@ CONFIG_TASK_WDT=y # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_SW_COEXIST_ENABLE=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/audio/audio.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/audio/audio.h index f99061eaec6..6f9c1a6b582 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/audio/audio.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/audio/audio.h @@ -494,18 +494,6 @@ typedef enum /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification -/// Isochronous End Point Attributes -typedef enum -{ - TUSB_ISO_EP_ATT_NO_SYNC = 0x00, - TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, - TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, - TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, - TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point - TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point - TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback -} tusb_iso_ep_attribute_t; - /// Audio Class-Control Values UAC2 typedef enum { diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc.h index 5df47f70b4a..e345139eab0 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc.h @@ -58,31 +58,32 @@ typedef enum /// Communication Interface Subclass Codes typedef enum { - CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2] - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL , ///< Abstract Control Model [USBPSTN1.2] - CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL , ///< Telephone Control Model [USBPSTN1.2] - CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL , ///< Multi-Channel Control Model [USBISDN1.2] - CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL , ///< CAPI Control Model [USBISDN1.2] - CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL , ///< Ethernet Networking Control Model [USBECM1.2] - CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL , ///< ATM Networking Control Model [USBATM1.2] - CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL , ///< Wireless Handset Control Model [USBWMC1.1] - CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT , ///< Device Management [USBWMC1.1] - CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL , ///< Mobile Direct Line Model [USBWMC1.1] - CDC_COMM_SUBCLASS_OBEX , ///< OBEX [USBWMC1.1] - CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model [USBEEM1.0] + CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL = 0x02 , ///< Abstract Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL = 0x03 , ///< Telephone Control Model [USBPSTN1.2] + CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL = 0x04 , ///< Multi-Channel Control Model [USBISDN1.2] + CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL = 0x05 , ///< CAPI Control Model [USBISDN1.2] + CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL = 0x06 , ///< Ethernet Networking Control Model [USBECM1.2] + CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL = 0x07 , ///< ATM Networking Control Model [USBATM1.2] + CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL = 0x08 , ///< Wireless Handset Control Model [USBWMC1.1] + CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT = 0x09 , ///< Device Management [USBWMC1.1] + CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL = 0x0A , ///< Mobile Direct Line Model [USBWMC1.1] + CDC_COMM_SUBCLASS_OBEX = 0x0B , ///< OBEX [USBWMC1.1] + CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL = 0x0C , ///< Ethernet Emulation Model [USBEEM1.0] + CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL = 0x0D ///< Network Control Model [USBNCM1.0] } cdc_comm_sublcass_type_t; /// Communication Interface Protocol Codes typedef enum { - CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol - CDC_COMM_PROTOCOL_ATCOMMAND , ///< AT Commands: V.250 etc - CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 , ///< AT Commands defined by PCCA-101 - CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO , ///< AT Commands defined by PCCA-101 & Annex O - CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 , ///< AT Commands defined by GSM 07.07 - CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 , ///< AT Commands defined by 3GPP 27.007 - CDC_COMM_PROTOCOL_ATCOMMAND_CDMA , ///< AT Commands defined by TIA for CDMA - CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model + CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol + CDC_COMM_PROTOCOL_ATCOMMAND = 0x01 , ///< AT Commands: V.250 etc + CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 = 0x02 , ///< AT Commands defined by PCCA-101 + CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO = 0x03 , ///< AT Commands defined by PCCA-101 & Annex O + CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 = 0x04 , ///< AT Commands defined by GSM 07.07 + CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 = 0x05 , ///< AT Commands defined by 3GPP 27.007 + CDC_COMM_PROTOCOL_ATCOMMAND_CDMA = 0x06 , ///< AT Commands defined by TIA for CDMA + CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL = 0x07 ///< Ethernet Emulation Model } cdc_comm_protocol_type_t; //------------- SubType Descriptor in COMM Functional Descriptor -------------// @@ -114,7 +115,8 @@ typedef enum CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor - CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 ///< OBEX Service Identifier Functional Descriptor + CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 , ///< OBEX Service Identifier Functional Descriptor + CDC_FUNC_DESC_NCM = 0x1A , ///< NCM Functional Descriptor }cdc_func_desc_type_t; //--------------------------------------------------------------------+ @@ -122,7 +124,8 @@ typedef enum //--------------------------------------------------------------------+ // SUBCLASS code of Data Interface is not used and should/must be zero -/// Data Interface Protocol Codes + +// Data Interface Protocol Codes typedef enum{ CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC @@ -147,7 +150,6 @@ typedef enum { CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. - CDC_REQUEST_SET_COMM_FEATURE = 0x02, CDC_REQUEST_GET_COMM_FEATURE = 0x03, CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04, @@ -194,21 +196,18 @@ typedef enum // Management Elemenent Notification (Notification Endpoint) //--------------------------------------------------------------------+ -/// Communication Interface Management Element Notification Codes +/// 6.3 Notification Codes typedef enum { - NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. - RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. - - AUX_JACK_HOOK_STATE = 0x08, - RING_DETECT = 0x09, - - SERIAL_STATE = 0x20, - - CALL_STATE_CHANGE = 0x28, - LINE_STATE_CHANGE = 0x29, - CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred - MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, + CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. + CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. + CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, + CDC_NOTIF_RING_DETECT = 0x09, + CDC_NOTIF_SERIAL_STATE = 0x20, + CDC_NOTIF_CALL_STATE_CHANGE = 0x28, + CDC_NOTIF_LINE_STATE_CHANGE = 0x29, + CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred + CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, }cdc_notification_request_t; //--------------------------------------------------------------------+ diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc_device.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc_device.h index 7ff757addd6..fbc7162a366 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc_device.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/cdc/cdc_device.h @@ -82,7 +82,7 @@ int32_t tud_cdc_n_read_char (uint8_t itf); void tud_cdc_n_read_flush (uint8_t itf); // Get a byte from FIFO at the specified position without removing it -bool tud_cdc_n_peek (uint8_t itf, uint8_t* u8); +bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8); // Write bytes to TX FIFO, data may remain in the FIFO for a while uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); @@ -116,7 +116,7 @@ static inline uint32_t tud_cdc_available (void); static inline int32_t tud_cdc_read_char (void); static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); static inline void tud_cdc_read_flush (void); -static inline bool tud_cdc_peek (uint8_t* u8); +static inline bool tud_cdc_peek (uint8_t* ui8); static inline uint32_t tud_cdc_write_char (char ch); static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); @@ -206,9 +206,9 @@ static inline void tud_cdc_read_flush (void) tud_cdc_n_read_flush(0); } -static inline bool tud_cdc_peek (uint8_t* u8) +static inline bool tud_cdc_peek (uint8_t* ui8) { - return tud_cdc_n_peek(0, u8); + return tud_cdc_n_peek(0, ui8); } static inline uint32_t tud_cdc_write_char (char ch) diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/ncm.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/ncm.h new file mode 100644 index 00000000000..96ba11fbc5c --- /dev/null +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/ncm.h @@ -0,0 +1,69 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef _TUSB_NCM_H_ +#define _TUSB_NCM_H_ + +#include "common/tusb_common.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; + + +// Table 6.2 Class-Specific Request Codes for Network Control Model subclass +typedef enum +{ + NCM_SET_ETHERNET_MULTICAST_FILTERS = 0x40, + NCM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, + NCM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, + NCM_SET_ETHERNET_PACKET_FILTER = 0x43, + NCM_GET_ETHERNET_STATISTIC = 0x44, + NCM_GET_NTB_PARAMETERS = 0x80, + NCM_GET_NET_ADDRESS = 0x81, + NCM_SET_NET_ADDRESS = 0x82, + NCM_GET_NTB_FORMAT = 0x83, + NCM_SET_NTB_FORMAT = 0x84, + NCM_GET_NTB_INPUT_SIZE = 0x85, + NCM_SET_NTB_INPUT_SIZE = 0x86, + NCM_GET_MAX_DATAGRAM_SIZE = 0x87, + NCM_SET_MAX_DATAGRAM_SIZE = 0x88, + NCM_GET_CRC_MODE = 0x89, + NCM_SET_CRC_MODE = 0x8A, +} ncm_request_code_t; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/net_device.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/net_device.h index f030f3077ac..6e294465b28 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/net_device.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/net/net_device.h @@ -30,14 +30,36 @@ #include "class/cdc/cdc.h" +#if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM +#error "Cannot enable both ECM_RNDIS and NCM network drivers" +#endif + +#include "ncm.h" + /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -/* Maximum Tranmission Unit (in bytes) of the network, including Ethernet header */ +/* Maximum Transmission Unit (in bytes) of the network, including Ethernet header */ #ifndef CFG_TUD_NET_MTU #define CFG_TUD_NET_MTU 1514 #endif +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB +#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#endif + +#ifndef CFG_TUD_NCM_ALIGNMENT +#define CFG_TUD_NCM_ALIGNMENT 4 +#endif + #ifdef __cplusplus extern "C" { #endif @@ -46,8 +68,18 @@ // Application API //--------------------------------------------------------------------+ -// client must provide this: initialize any network state back to the beginning -void tud_network_init_cb(void); +// indicate to network driver that client has finished with the packet provided to network_recv_cb() +void tud_network_recv_renew(void); + +// poll network driver for its ability to accept another packet to transmit +bool tud_network_can_xmit(uint16_t size); + +// if network_can_xmit() returns true, network_xmit() can be called once +void tud_network_xmit(void *ref, uint16_t arg); + +//--------------------------------------------------------------------+ +// Application Callbacks (WEAK is optional) +//--------------------------------------------------------------------+ // client must provide this: return false if the packet buffer was not accepted bool tud_network_recv_cb(const uint8_t *src, uint16_t size); @@ -55,18 +87,19 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size); // client must provide this: copy from network stack packet pointer to dst uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); +//------------- ECM/RNDIS -------------// + +// client must provide this: initialize any network state back to the beginning +void tud_network_init_cb(void); + // client must provide this: 48-bit MAC address // TODO removed later since it is not part of tinyusb stack extern const uint8_t tud_network_mac_address[6]; -// indicate to network driver that client has finished with the packet provided to network_recv_cb() -void tud_network_recv_renew(void); - -// poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(void); +//------------- NCM -------------// -// if network_can_xmit() returns true, network_xmit() can be called once -void tud_network_xmit(void *ref, uint16_t arg); +// callback to client providing optional indication of internal state of network driver +void tud_network_link_state_cb(bool state); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/vendor/vendor_device.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/vendor/vendor_device.h index 844693c68b7..d71c2a3e911 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/vendor/vendor_device.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/vendor/vendor_device.h @@ -44,7 +44,7 @@ bool tud_vendor_n_mounted (uint8_t itf); uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); -bool tud_vendor_n_peek (uint8_t itf, uint8_t* u8); +bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); void tud_vendor_n_read_flush (uint8_t itf); uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); @@ -59,7 +59,7 @@ uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); static inline bool tud_vendor_mounted (void); static inline uint32_t tud_vendor_available (void); static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); -static inline bool tud_vendor_peek (uint8_t* u8); +static inline bool tud_vendor_peek (uint8_t* ui8); static inline void tud_vendor_read_flush (void); static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); @@ -96,9 +96,9 @@ static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) return tud_vendor_n_read(0, buffer, bufsize); } -static inline bool tud_vendor_peek (uint8_t* u8) +static inline bool tud_vendor_peek (uint8_t* ui8) { - return tud_vendor_n_peek(0, u8); + return tud_vendor_n_peek(0, ui8); } static inline void tud_vendor_read_flush(void) diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video.h new file mode 100644 index 00000000000..b24eb0bcc00 --- /dev/null +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video.h @@ -0,0 +1,472 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_VIDEO_H_ +#define TUSB_VIDEO_H_ + +#include "common/tusb_common.h" + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, + VIDEO_COLOR_PRIMARIES_BT709, // sRGB (default) + VIDEO_COLOR_PRIMARIES_BT470_2M, + VIDEO_COLOR_PRIMARIES_BT470_2BG, + VIDEO_COLOR_PRIMARIES_SMPTE170M, + VIDEO_COLOR_PRIMARIES_SMPTE240M, +} video_color_primaries_t; + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_XFER_CH_UNDEFINED = 0x00, + VIDEO_COLOR_XFER_CH_BT709, // default + VIDEO_COLOR_XFER_CH_BT470_2M, + VIDEO_COLOR_XFER_CH_BT470_2BG, + VIDEO_COLOR_XFER_CH_SMPTE170M, + VIDEO_COLOR_XFER_CH_SMPTE240M, + VIDEO_COLOR_XFER_CH_LINEAR, + VIDEO_COLOR_XFER_CH_SRGB, +} video_color_transfer_characteristics_t; + +// Table 3-19 Color Matching Descriptor +typedef enum { + VIDEO_COLOR_COEF_UNDEFINED = 0x00, + VIDEO_COLOR_COEF_BT709, + VIDEO_COLOR_COEF_FCC, + VIDEO_COLOR_COEF_BT470_2BG, + VIDEO_COLOR_COEF_SMPTE170M, // BT.601 default + VIDEO_COLOR_COEF_SMPTE240M, +} video_color_matrix_coefficients_t; + +/* 4.2.1.2 Request Error Code Control */ +typedef enum { + VIDEO_ERROR_NONE = 0, /* The request succeeded. */ + VIDEO_ERROR_NOT_READY, + VIDEO_ERROR_WRONG_STATE, + VIDEO_ERROR_POWER, + VIDEO_ERROR_OUT_OF_RANGE, + VIDEO_ERROR_INVALID_UNIT, + VIDEO_ERROR_INVALID_CONTROL, + VIDEO_ERROR_INVALID_REQUEST, + VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE, + VIDEO_ERROR_UNKNOWN = 0xFF, +} video_error_code_t; + +/* A.2 Interface Subclass */ +typedef enum { + VIDEO_SUBCLASS_UNDEFINED = 0x00, + VIDEO_SUBCLASS_CONTROL, + VIDEO_SUBCLASS_STREAMING, + VIDEO_SUBCLASS_INTERFACE_COLLECTION, +} video_subclass_type_t; + +/* A.3 Interface Protocol */ +typedef enum { + VIDEO_ITF_PROTOCOL_UNDEFINED = 0x00, + VIDEO_ITF_PROTOCOL_15, +} video_interface_protocol_code_t; + +/* A.5 Class-Specific VideoControl Interface Descriptor Subtypes */ +typedef enum { + VIDEO_CS_ITF_VC_UNDEFINED = 0x00, + VIDEO_CS_ITF_VC_HEADER, + VIDEO_CS_ITF_VC_INPUT_TERMINAL, + VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + VIDEO_CS_ITF_VC_SELECTOR_UNIT, + VIDEO_CS_ITF_VC_PROCESSING_UNIT, + VIDEO_CS_ITF_VC_EXTENSION_UNIT, + VIDEO_CS_ITF_VC_ENCODING_UNIT, + VIDEO_CS_ITF_VC_MAX, +} video_cs_vc_interface_subtype_t; + +/* A.6 Class-Specific VideoStreaming Interface Descriptor Subtypes */ +typedef enum { + VIDEO_CS_ITF_VS_UNDEFINED = 0x00, + VIDEO_CS_ITF_VS_INPUT_HEADER = 0x01, + VIDEO_CS_ITF_VS_OUTPUT_HEADER = 0x02, + VIDEO_CS_ITF_VS_STILL_IMAGE_FRAME = 0x03, + VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED = 0x04, + VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED = 0x05, + VIDEO_CS_ITF_VS_FORMAT_MJPEG = 0x06, + VIDEO_CS_ITF_VS_FRAME_MJPEG = 0x07, + VIDEO_CS_ITF_VS_FORMAT_MPEG2TS = 0x0A, + VIDEO_CS_ITF_VS_FORMAT_DV = 0x0C, + VIDEO_CS_ITF_VS_COLORFORMAT = 0x0D, + VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED = 0x10, + VIDEO_CS_ITF_VS_FRAME_FRAME_BASED = 0x11, + VIDEO_CS_ITF_VS_FORMAT_STREAM_BASED = 0x12, + VIDEO_CS_ITF_VS_FORMAT_H264 = 0x13, + VIDEO_CS_ITF_VS_FRAME_H264 = 0x14, + VIDEO_CS_ITF_VS_FORMAT_H264_SIMULCAST = 0x15, + VIDEO_CS_ITF_VS_FORMAT_VP8 = 0x16, + VIDEO_CS_ITF_VS_FRAME_VP8 = 0x17, + VIDEO_CS_ITF_VS_FORMAT_VP8_SIMULCAST = 0x18, +} video_cs_vs_interface_subtype_t; + +/* A.7. Class-Specific Endpoint Descriptor Subtypes */ +typedef enum { + VIDEO_CS_EP_UNDEFINED = 0x00, + VIDEO_CS_EP_GENERAL, + VIDEO_CS_EP_ENDPOINT, + VIDEO_CS_EP_INTERRUPT +} video_cs_ep_subtype_t; + +/* A.8 Class-Specific Request Codes */ +typedef enum { + VIDEO_REQUEST_UNDEFINED = 0x00, + VIDEO_REQUEST_SET_CUR = 0x01, + VIDEO_REQUEST_SET_CUR_ALL = 0x11, + VIDEO_REQUEST_GET_CUR = 0x81, + VIDEO_REQUEST_GET_MIN = 0x82, + VIDEO_REQUEST_GET_MAX = 0x83, + VIDEO_REQUEST_GET_RES = 0x84, + VIDEO_REQUEST_GET_LEN = 0x85, + VIDEO_REQUEST_GET_INFO = 0x86, + VIDEO_REQUEST_GET_DEF = 0x87, + VIDEO_REQUEST_GET_CUR_ALL = 0x91, + VIDEO_REQUEST_GET_MIN_ALL = 0x92, + VIDEO_REQUEST_GET_MAX_ALL = 0x93, + VIDEO_REQUEST_GET_RES_ALL = 0x94, + VIDEO_REQUEST_GET_DEF_ALL = 0x97 +} video_control_request_t; + +/* A.9.1 VideoControl Interface Control Selectors */ +typedef enum { + VIDEO_VC_CTL_UNDEFINED = 0x00, + VIDEO_VC_CTL_VIDEO_POWER_MODE, + VIDEO_VC_CTL_REQUEST_ERROR_CODE, +} video_interface_control_selector_t; + +/* A.9.8 VideoStreaming Interface Control Selectors */ +typedef enum { + VIDEO_VS_CTL_UNDEFINED = 0x00, + VIDEO_VS_CTL_PROBE, + VIDEO_VS_CTL_COMMIT, + VIDEO_VS_CTL_STILL_PROBE, + VIDEO_VS_CTL_STILL_COMMIT, + VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, + VIDEO_VS_CTL_STREAM_ERROR_CODE, + VIDEO_VS_CTL_GENERATE_KEY_FRAME, + VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, + VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, +} video_interface_streaming_selector_t; + +/* B. Terminal Types */ +typedef enum { + // Terminal + VIDEO_TT_VENDOR_SPECIFIC = 0x0100, + VIDEO_TT_STREAMING = 0x0101, + + // Input + VIDEO_ITT_VENDOR_SPECIFIC = 0x0200, + VIDEO_ITT_CAMERA = 0x0201, + VIDEO_ITT_MEDIA_TRANSPORT_INPUT = 0x0202, + + // Output + VIDEO_OTT_VENDOR_SPECIFIC = 0x0300, + VIDEO_OTT_DISPLAY = 0x0301, + VIDEO_OTT_MEDIA_TRANSPORT_OUTPUT = 0x0302, + + // External + VIDEO_ETT_VENDOR_SPEIFIC = 0x0400, + VIDEO_ETT_COMPOSITE_CONNECTOR = 0x0401, + VIDEO_ETT_SVIDEO_CONNECTOR = 0x0402, + VIDEO_ETT_COMPONENT_CONNECTOR = 0x0403, +} video_terminal_type_t; + +//--------------------------------------------------------------------+ +// Descriptors +//--------------------------------------------------------------------+ + +/* 2.3.4.2 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint16_t bcdUVC; + uint16_t wTotalLength; + uint32_t dwClockFrequency; + uint8_t bInCollection; + uint8_t baInterfaceNr[]; +} tusb_desc_cs_video_ctl_itf_hdr_t; + +/* 2.4.3.3 */ +typedef struct TU_ATTR_PACKED { + uint8_t bHeaderLength; + union { + uint8_t bmHeaderInfo; + struct { + uint8_t FrameID: 1; + uint8_t EndOfFrame: 1; + uint8_t PresentationTime: 1; + uint8_t SourceClockReference: 1; + uint8_t PayloadSpecific: 1; + uint8_t StillImage: 1; + uint8_t Error: 1; + uint8_t EndOfHeader: 1; + }; + }; +} tusb_video_payload_header_t; + +/* 3.9.2.1 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + uint8_t bmInfo; + uint8_t bTerminalLink; + uint8_t bStillCaptureMethod; + uint8_t bTriggerSupport; + uint8_t bTriggerUsage; + uint8_t bControlSize; + uint8_t bmaControls[]; +} tusb_desc_cs_video_stm_itf_in_hdr_t; + +/* 3.9.2.2 */ +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + uint8_t bTerminalLink; + uint8_t bControlSize; + uint8_t bmaControls[]; +} tusb_desc_cs_video_stm_itf_out_hdr_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumFormats; + uint16_t wTotalLength; + uint8_t bEndpointAddress; + union { + struct { + uint8_t bmInfo; + uint8_t bTerminalLink; + uint8_t bStillCaptureMethod; + uint8_t bTriggerSupport; + uint8_t bTriggerUsage; + uint8_t bControlSize; + uint8_t bmaControls[]; + } input; + struct { + uint8_t bEndpointAddress; + uint8_t bTerminalLink; + uint8_t bControlSize; + uint8_t bmaControls[]; + } output; + }; +} tusb_desc_cs_video_stm_itf_hdr_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptors; + uint8_t guidFormat[16]; + uint8_t bBitsPerPixel; + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bmInterlaceFlags; + uint8_t bCopyProtect; +} tusb_desc_cs_video_fmt_uncompressed_t; + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwFrameInterval[]; +} tusb_desc_cs_video_frm_uncompressed_t; + +//--------------------------------------------------------------------+ +// Requests +//--------------------------------------------------------------------+ + +/* 4.3.1.1 */ +typedef struct TU_ATTR_PACKED { + union { + uint8_t bmHint; + struct TU_ATTR_PACKED { + uint16_t dwFrameInterval: 1; + uint16_t wKeyFrameRatel : 1; + uint16_t wPFrameRate : 1; + uint16_t wCompQuality : 1; + uint16_t wCompWindowSize: 1; + uint16_t : 0; + } Hint; + }; + uint8_t bFormatIndex; + uint8_t bFrameIndex; + uint32_t dwFrameInterval; + uint16_t wKeyFrameRate; + uint16_t wPFrameRate; + uint16_t wCompQuality; + uint16_t wCompWindowSize; + uint16_t wDelay; + uint32_t dwMaxVideoFrameSize; + uint32_t dwMaxPayloadTransferSize; + uint32_t dwClockFrequency; + union { + uint8_t bmFramingInfo; + struct TU_ATTR_PACKED { + uint8_t FrameID : 1; + uint8_t EndOfFrame: 1; + uint8_t EndOfSlice: 1; + uint8_t : 0; + } FramingInfo; + }; + uint8_t bPreferedVersion; + uint8_t bMinVersion; + uint8_t bMaxVersion; + uint8_t bUsage; + uint8_t bBitDepthLuma; + uint8_t bmSettings; + uint8_t bMaxNumberOfRefFramesPlus1; + uint16_t bmRateControlModes; + uint64_t bmLayoutPerStream; +} video_probe_and_commit_control_t; + +TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not correct"); + +#define TUD_VIDEO_DESC_IAD_LEN 8 +#define TUD_VIDEO_DESC_STD_VC_LEN 9 +#define TUD_VIDEO_DESC_CS_VC_LEN 12 +#define TUD_VIDEO_DESC_INPUT_TERM_LEN 8 +#define TUD_VIDEO_DESC_OUTPUT_TERM_LEN 9 +#define TUD_VIDEO_DESC_STD_VS_LEN 9 +#define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 +#define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 +#define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN 27 +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN 38 +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN 26 +#define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 + +/* 2.2 compression formats */ +#define TUD_VIDEO_GUID_YUY2 0x59,0x55,0x59,0x32,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 +#define TUD_VIDEO_GUID_NV12 0x4E,0x56,0x31,0x32,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 +#define TUD_VIDEO_GUID_M420 0x4D,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 +#define TUD_VIDEO_GUID_I420 0x49,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x00,0x80,0x71,0x9B,0x38,0x00,0xAA,0x00 + +#define TUD_VIDEO_DESC_IAD(_firstitfs, _nitfs, _stridx) \ + TUD_VIDEO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, \ + _firstitfs, _nitfs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_INTERFACE_COLLECTION, \ + VIDEO_ITF_PROTOCOL_UNDEFINED, _stridx + +#define TUD_VIDEO_DESC_STD_VC(_itfnum, _nEPs, _stridx) \ + TUD_VIDEO_DESC_STD_VC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, \ + _nEPs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_CONTROL, VIDEO_ITF_PROTOCOL_15, _stridx + +/* 3.7.2 */ +#define TUD_VIDEO_DESC_CS_VC(_bcdUVC, _totallen, _clkfreq, ...) \ + TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_HEADER, \ + U16_TO_U8S_LE(_bcdUVC), U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__))), \ + U32_TO_U8S_LE(_clkfreq), TU_ARGS_NUM(__VA_ARGS__), __VA_ARGS__ + +/* 3.7.2.1 */ +#define TUD_VIDEO_DESC_INPUT_TERM(_tid, _tt, _at, _stridx) \ + TUD_VIDEO_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(_tt), _at, _stridx + +/* 3.7.2.2 */ +#define TUD_VIDEO_DESC_OUTPUT_TERM(_tid, _tt, _at, _srcid, _stridx) \ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, \ + _tid, U16_TO_U8S_LE(_tt), _at, _srcid, _stridx + +/* 3.9.1 */ +#define TUD_VIDEO_DESC_STD_VS(_itfnum, _alt, _epn, _stridx) \ + TUD_VIDEO_DESC_STD_VS_LEN, TUSB_DESC_INTERFACE, _itfnum, _alt, \ + _epn, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_STREAMING, VIDEO_ITF_PROTOCOL_15, _stridx + +/* 3.9.2.1 */ +#define TUD_VIDEO_DESC_CS_VS_INPUT(_numfmt, _totallen, _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, ...) \ + TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ + VIDEO_CS_ITF_VS_INPUT_HEADER, _numfmt, \ + U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ + _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* 3.9.2.2 */ +#define TUD_VIDEO_DESC_CS_VS_OUTPUT(_numfmt, _totallen, _ep, _inf, _termlnk, ...) \ + TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ + VIDEO_CS_ITF_VS_OUTPUT_HEADER, _numfmt, \ + U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ + _ep, _inf, _termlnk, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* Uncompressed 3.1.1 */ +#define TUD_VIDEO_GUID(_g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15) _g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15 + +#define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfrmdesc, \ + _guid, _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, \ + _fmtidx, _numfrmdesc, TUD_VIDEO_GUID(_guid), \ + _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp + +/* Uncompressed 3.1.2 Table 3-3 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ + U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) + +/* Uncompressed 3.1.2 Table 3-4 */ +#define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ + _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ + U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ + +/* 3.9.2.6 */ +#define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(_color, _trns, _mat) \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_COLORFORMAT, \ + _color, _trns, _mat + +/* 3.10.1.1 */ +#define TUD_VIDEO_DESC_EP_ISO(_ep, _epsize, _ep_interval) \ + 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS,\ + U16_TO_U8S_LE(_epsize), _ep_interval + +/* 3.10.1.2 */ +#define TUD_VIDEO_DESC_EP_BULK(_ep, _epsize, _ep_interval) \ + 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), _ep_interval + +#endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video_device.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video_device.h new file mode 100644 index 00000000000..ee2fcb9d513 --- /dev/null +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/video/video_device.h @@ -0,0 +1,97 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2021 Koji KITAYAMA + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_VIDEO_DEVICE_H_ +#define TUSB_VIDEO_DEVICE_H_ + +#include "common/tusb_common.h" +#include "video.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Application API (Multiple Ports) +// CFG_TUD_VIDEO > 1 +//--------------------------------------------------------------------+ + +/** Return true if streaming + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index */ +bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); + +/** Transfer a frame + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @param[in] buffer Frame buffer. The caller must not use this buffer until the operation is completed. + * @param[in] bufsize Byte size of the frame buffer */ +bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize); + +/*------------- Optional callbacks -------------*/ +/** Invoked when compeletion of a frame transfer + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index */ +TU_ATTR_WEAK void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +/** Invoked when SET_POWER_MODE request received + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @return video_error_code_t */ +TU_ATTR_WEAK int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod); + +/** Invoked when VS_COMMIT_CONTROL(SET_CUR) request received + * + * @param[in] ctl_idx Destination control interface index + * @param[in] stm_idx Destination streaming interface index + * @param[in] parameters Video streaming parameters + * @return video_error_code_t */ +TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const *parameters); + +//--------------------------------------------------------------------+ +// INTERNAL USBD-CLASS DRIVER API +//--------------------------------------------------------------------+ +void videod_init (void); +void videod_reset (uint8_t rhport); +uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool videod_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_common.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_common.h index 1899b35cc3d..fc4d3bc62d3 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_common.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_common.h @@ -38,18 +38,18 @@ #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) -#define TU_U16_HIGH(u16) ((uint8_t) (((u16) >> 8) & 0x00ff)) -#define TU_U16_LOW(u16) ((uint8_t) ((u16) & 0x00ff)) -#define U16_TO_U8S_BE(u16) TU_U16_HIGH(u16), TU_U16_LOW(u16) -#define U16_TO_U8S_LE(u16) TU_U16_LOW(u16), TU_U16_HIGH(u16) +#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) +#define TU_U16_LOW(_u16) ((uint8_t) ((_u16) & 0x00ff)) +#define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16) +#define U16_TO_U8S_LE(_u16) TU_U16_LOW(_u16), TU_U16_HIGH(_u16) -#define TU_U32_BYTE3(u32) ((uint8_t) ((((uint32_t) u32) >> 24) & 0x000000ff)) // MSB -#define TU_U32_BYTE2(u32) ((uint8_t) ((((uint32_t) u32) >> 16) & 0x000000ff)) -#define TU_U32_BYTE1(u32) ((uint8_t) ((((uint32_t) u32) >> 8) & 0x000000ff)) -#define TU_U32_BYTE0(u32) ((uint8_t) (((uint32_t) u32) & 0x000000ff)) // LSB +#define TU_U32_BYTE3(_u32) ((uint8_t) ((((uint32_t) _u32) >> 24) & 0x000000ff)) // MSB +#define TU_U32_BYTE2(_u32) ((uint8_t) ((((uint32_t) _u32) >> 16) & 0x000000ff)) +#define TU_U32_BYTE1(_u32) ((uint8_t) ((((uint32_t) _u32) >> 8) & 0x000000ff)) +#define TU_U32_BYTE0(_u32) ((uint8_t) (((uint32_t) _u32) & 0x000000ff)) // LSB -#define U32_TO_U8S_BE(u32) TU_U32_BYTE3(u32), TU_U32_BYTE2(u32), TU_U32_BYTE1(u32), TU_U32_BYTE0(u32) -#define U32_TO_U8S_LE(u32) TU_U32_BYTE0(u32), TU_U32_BYTE1(u32), TU_U32_BYTE2(u32), TU_U32_BYTE3(u32) +#define U32_TO_U8S_BE(_u32) TU_U32_BYTE3(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE0(_u32) +#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32) #define TU_BIT(n) (1UL << (n)) @@ -105,16 +105,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) return (uint16_t) ((((uint16_t) high) << 8) | low); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t u32) { return TU_U32_BYTE3(u32); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t u32) { return TU_U32_BYTE2(u32); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t u32) { return TU_U32_BYTE1(u32); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t u32) { return TU_U32_BYTE0(u32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t ui32) { return TU_U32_BYTE3(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_U32_BYTE2(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t u32) { return (uint16_t) (u32 >> 16); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t u32) { return (uint16_t) (u32 & 0x0000ffffu); } - -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t u16) { return TU_U16_HIGH(u16); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t u16) { return TU_U16_LOW(u16); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); } +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } //------------- Bits -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); } diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_types.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_types.h index f26983a7483..897e89b3943 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_types.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/common/tusb_types.h @@ -69,6 +69,18 @@ typedef enum TUSB_DIR_IN_MASK = 0x80 }tusb_dir_t; +/// Isochronous End Point Attributes +typedef enum +{ + TUSB_ISO_EP_ATT_NO_SYNC = 0x00, + TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, + TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, + TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, + TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point + TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point + TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback +}tusb_iso_ep_attribute_t; + /// USB Descriptor Types typedef enum { diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/dcd_attr.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/dcd_attr.h index a35fc0ac502..44f2cc1d6d0 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/dcd_attr.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/dcd_attr.h @@ -63,6 +63,9 @@ #elif TU_CHECK_MCU(MKL25ZXX) || TU_CHECK_MCU(K32L2BXX) #define DCD_ATTR_ENDPOINT_MAX 16 +#elif TU_CHECK_MCU(MM32F327X) + #define DCD_ATTR_ENDPOINT_MAX 16 + //------------- Nordic -------------// #elif TU_CHECK_MCU(NRF5X) // 8 CBI + 1 ISO diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/usbd.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/usbd.h index 638d9309470..8d02de1ff1f 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/usbd.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/device/usbd.h @@ -178,17 +178,18 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F //--------------------------------------------------------------------+ -// Configuration & Interface Descriptor Templates +// Configuration Descriptor Templates //--------------------------------------------------------------------+ -//------------- Configuration -------------// #define TUD_CONFIG_DESC_LEN (9) // Config number, interface count, string index, total length, attribute, power in mA #define TUD_CONFIG_DESCRIPTOR(config_num, _itfcount, _stridx, _total_len, _attribute, _power_ma) \ 9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2 -//------------- CDC -------------// +//--------------------------------------------------------------------+ +// CDC Descriptor Templates +//--------------------------------------------------------------------+ // Length of template descriptor: 66 bytes #define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7) @@ -217,7 +218,9 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 -//------------- MSC -------------// +//--------------------------------------------------------------------+ +// MSC Descriptor Templates +//--------------------------------------------------------------------+ // Length of template descriptor: 23 bytes #define TUD_MSC_DESC_LEN (9 + 7 + 7) @@ -231,7 +234,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 -//------------- HID -------------// + +//--------------------------------------------------------------------+ +// HID Descriptor Templates +//--------------------------------------------------------------------+ // Length of template descriptor: 25 bytes #define TUD_HID_DESC_LEN (9 + 9 + 7) @@ -261,8 +267,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval -//------------- MIDI -------------// -// MIDI v1.0 is based on Audio v1.0 +//--------------------------------------------------------------------+ +// MIDI Descriptor Templates +// Note: MIDI v1.0 is based on Audio v1.0 +//--------------------------------------------------------------------+ #define TUD_MIDI_DESC_HEAD_LEN (9 + 9 + 9 + 7) #define TUD_MIDI_DESC_HEAD(_itfnum, _stridx, _numcables) \ @@ -319,7 +327,9 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1) -//------------- AUDIO -------------// +//--------------------------------------------------------------------+ +// Audio v2.0 Descriptor Templates +//--------------------------------------------------------------------+ /* Standard Interface Association Descriptor (IAD) */ #define TUD_AUDIO_DESC_IAD_LEN 8 @@ -551,7 +561,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb ((((_maxFrequency + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 7999 : 999)) / ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) -//------------- TUD_USBTMC/USB488 -------------// +//--------------------------------------------------------------------+ +// USBTMC/USB488 Descriptor Templates +//--------------------------------------------------------------------+ + #define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) #define TUD_USBTMC_APP_SUBCLASS 0x03u @@ -581,8 +594,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb #define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) +//--------------------------------------------------------------------+ +// Vendor Descriptor Templates +//--------------------------------------------------------------------+ -//------------- Vendor -------------// #define TUD_VENDOR_DESC_LEN (9+7+7) // Interface number, string index, EP Out & IN address, EP size @@ -594,7 +609,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 -//------------- DFU Runtime -------------// +//--------------------------------------------------------------------+ +// DFU Runtime Descriptor Templates +//--------------------------------------------------------------------+ + #define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) #define TUD_DFU_APP_SUBCLASS (APP_SUBCLASS_DFU_RUNTIME) @@ -609,6 +627,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) +//--------------------------------------------------------------------+ +// DFU Descriptor Templates +//--------------------------------------------------------------------+ + // Length of template descriptor: 9 bytes + number of alternatives * 9 #define TUD_DFU_DESC_LEN(_alt_count) (9 + (_alt_count) * 9) @@ -654,8 +676,9 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb _TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ _TUD_DFU_ALT_7(_itfnum, _alt_count+1, _stridx+1) - -//------------- CDC-ECM -------------// +//--------------------------------------------------------------------+ +// CDC-ECM Descriptor Templates +//--------------------------------------------------------------------+ // Length of template descriptor: 71 bytes #define TUD_CDC_ECM_DESC_LEN (8+9+5+5+13+7+9+9+7+7) @@ -684,8 +707,9 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 - -//------------- RNDIS -------------// +//--------------------------------------------------------------------+ +// RNDIS Descriptor Templates +//--------------------------------------------------------------------+ #if 0 /* Windows XP */ @@ -726,7 +750,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 -//------------- BT Radio -------------// +//--------------------------------------------------------------------+ +// Bluetooth Radio Descriptor Templates +//--------------------------------------------------------------------+ + #define TUD_BT_APP_CLASS (TUSB_CLASS_WIRELESS_CONTROLLER) #define TUD_BT_APP_SUBCLASS 0x01 #define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01 @@ -777,10 +804,44 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // BT Primary controller descriptor // Interface number, string index, attributes, event endpoint, event endpoint size, interval, data in, data out, data endpoint size, iso endpoint sizes +// TODO BTH should also use IAD like CDC for composite device #define TUD_BTH_DESCRIPTOR(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size,...) \ TUD_BTH_PRI_ITF(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size) \ TUD_BTH_ISO_ITFS(_itfnum + 1, _ep_in + 1, _ep_out + 1, __VA_ARGS__) +//--------------------------------------------------------------------+ +// CDC-NCM Descriptor Templates +//--------------------------------------------------------------------+ + +// Length of template descriptor +#define TUD_CDC_NCM_DESC_LEN (8+9+5+5+13+6+7+9+9+7+7) + +// CDC-ECM Descriptor Template +// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. +#define TUD_CDC_NCM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \ + /* Interface Association */\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, 0,\ + /* CDC Control Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, _desc_stridx,\ + /* CDC-NCM Header */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\ + /* CDC-NCM Union */\ + 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ + /* CDC-NCM Functional Descriptor */\ + 13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0, \ + /* CDC-NCM Functional Descriptor */\ + 6, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_NCM, U16_TO_U8S_LE(0x0100), 0, \ + /* Endpoint Notification */\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 50,\ + /* CDC Data Interface (default inactive) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ + /* CDC Data Interface (alternative active) */\ + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + #ifdef __cplusplus } #endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/host/usbh_hcd.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/host/usbh_hcd.h new file mode 100644 index 00000000000..b3856d6b779 --- /dev/null +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/host/usbh_hcd.h @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + +/** \ingroup Group_HCD + * @{ */ + +#ifndef _TUSB_USBH_HCD_H_ +#define _TUSB_USBH_HCD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "osal/osal.h" + +#ifndef CFG_TUH_EP_MAX +#define CFG_TUH_EP_MAX 9 +#endif + +//--------------------------------------------------------------------+ +// USBH-HCD common data structure +//--------------------------------------------------------------------+ + +// TODO move to usbh.c +typedef struct { + //------------- port -------------// + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; + + //------------- device descriptor -------------// + uint16_t vendor_id; + uint16_t product_id; + uint8_t ep0_packet_size; + + //------------- configuration descriptor -------------// + // uint8_t interface_count; // bNumInterfaces alias + + //------------- device -------------// + struct TU_ATTR_PACKED + { + uint8_t connected : 1; + uint8_t addressed : 1; + uint8_t configured : 1; + uint8_t suspended : 1; + }; + + volatile uint8_t state; // device state, value from enum tusbh_device_state_t + + uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t ep2drv[CFG_TUH_EP_MAX][2]; // map endpoint to driver ( 0xff is invalid ) + + struct TU_ATTR_PACKED + { + volatile bool busy : 1; + volatile bool stalled : 1; + volatile bool claimed : 1; + + // TODO merge ep2drv here, 4-bit should be sufficient + }ep_status[CFG_TUH_EP_MAX][2]; + + // Mutex for claiming endpoint, only needed when using with preempted RTOS +#if CFG_TUSB_OS != OPT_OS_NONE + osal_mutex_def_t mutexdef; + osal_mutex_t mutex; +#endif + +} usbh_device_t; + +extern usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1]; // including zero-address + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_USBH_HCD_H_ */ + +/** @} */ diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/portable/ehci/hcd_ehci.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/portable/ehci/hcd_ehci.h new file mode 100644 index 00000000000..480d11eda02 --- /dev/null +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/portable/ehci/hcd_ehci.h @@ -0,0 +1,53 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_HCD_EHCI_H_ +#define _TUSB_HCD_EHCI_H_ + +#ifdef __cplusplus + extern "C" { +#endif + + +//--------------------------------------------------------------------+ +// API Implemented by HCD +//--------------------------------------------------------------------+ + +// Get operational address i.e EHCI Command register +uint32_t hcd_ehci_register_addr(uint8_t rhport); + +//--------------------------------------------------------------------+ +// API Implemented by EHCI +//--------------------------------------------------------------------+ + +// Initialize EHCI driver +extern bool hcd_ehci_init (uint8_t rhport); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb.h index b52f8839ac8..0d29e106c9b 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb.h @@ -76,9 +76,13 @@ #include "class/msc/msc_device.h" #endif -#if CFG_TUD_AUDIO - #include "class/audio/audio_device.h" -#endif + #if CFG_TUD_AUDIO + #include "class/audio/audio_device.h" + #endif + + #if CFG_TUD_VIDEO + #include "class/video/video_device.h" + #endif #if CFG_TUD_MIDI #include "class/midi/midi_device.h" @@ -100,7 +104,7 @@ #include "class/dfu/dfu_device.h" #endif - #if CFG_TUD_NET + #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM #include "class/net/net_device.h" #endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb_option.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb_option.h index ad2a26a6654..b2ebfdf66de 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb_option.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/tusb_option.h @@ -241,6 +241,10 @@ #define CFG_TUD_AUDIO 0 #endif +#ifndef CFG_TUD_VIDEO + #define CFG_TUD_VIDEO 0 +#endif + #ifndef CFG_TUD_MIDI #define CFG_TUD_MIDI 0 #endif @@ -261,14 +265,23 @@ #define CFG_TUD_DFU 0 #endif -#ifndef CFG_TUD_NET - #define CFG_TUD_NET 0 -#endif - #ifndef CFG_TUD_BTH #define CFG_TUD_BTH 0 #endif +#ifndef CFG_TUD_ECM_RNDIS + #ifdef CFG_TUD_NET + #warning "CFG_TUD_NET is renamed to CFG_TUD_ECM_RNDIS" + #define CFG_TUD_ECM_RNDIS CFG_TUD_NET + #else + #define CFG_TUD_ECM_RNDIS 0 + #endif +#endif + +#ifndef CFG_TUD_NCM + #define CFG_TUD_NCM 0 +#endif + //-------------------------------------------------------------------- // HOST OPTIONS //-------------------------------------------------------------------- @@ -280,10 +293,34 @@ #ifndef CFG_TUH_ENUMERATION_BUFSIZE #define CFG_TUH_ENUMERATION_BUFSIZE 256 #endif - - //------------- CLASS -------------// #endif // TUSB_OPT_HOST_ENABLED +//------------- CLASS -------------// + +#ifndef CFG_TUH_HUB +#define CFG_TUH_HUB 0 +#endif + +#ifndef CFG_TUH_CDC +#define CFG_TUH_CDC 0 +#endif + +#ifndef CFG_TUH_HID +#define CFG_TUH_HID 0 +#endif + +#ifndef CFG_TUH_MIDI +#define CFG_TUH_MIDI 0 +#endif + +#ifndef CFG_TUH_MSC +#define CFG_TUH_MSC 0 +#endif + +#ifndef CFG_TUH_VENDOR +#define CFG_TUH_VENDOR 0 +#endif + //--------------------------------------------------------------------+ // Port Specific // TUP stand for TinyUSB Port (can be renamed) diff --git a/tools/sdk/esp32s2/include/asio/port/include/esp_asio_config.h b/tools/sdk/esp32s2/include/asio/port/include/esp_asio_config.h index cba316527e6..3f3a9b03ed4 100644 --- a/tools/sdk/esp32s2/include/asio/port/include/esp_asio_config.h +++ b/tools/sdk/esp32s2/include/asio/port/include/esp_asio_config.h @@ -18,6 +18,11 @@ # define ASIO_NO_TYPEID # endif // CONFIG_COMPILER_RTTI +// +// Supress OpenSSL deprecation warning, when building ASIO +// +#define ESP_OPENSSL_SUPPRESS_LEGACY_WARNING + // // LWIP compatibility inet and address macros/functions // diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/address.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/address.h new file mode 100644 index 00000000000..a51236d5a60 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/address.h @@ -0,0 +1,177 @@ +/* + * address.h -- representation of network addresses + * + * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file address.h + * @brief Representation of network addresses + */ + +#ifndef COAP_ADDRESS_H_ +#define COAP_ADDRESS_H_ + +#include +#include +#include +#include +#include "libcoap.h" + +#if defined(WITH_LWIP) + +#include + +typedef struct coap_address_t { + uint16_t port; + ip_addr_t addr; +} coap_address_t; + +#define _coap_address_equals_impl(A, B) \ + ((A)->port == (B)->port \ + && (!!ip_addr_cmp(&(A)->addr,&(B)->addr))) + +#define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) + +#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr) + +#elif defined(WITH_CONTIKI) + +#include "uip.h" + +typedef struct coap_address_t { + uip_ipaddr_t addr; + uint16_t port; +} coap_address_t; + +#define _coap_address_equals_impl(A,B) \ + ((A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) + +/** @todo implementation of _coap_address_isany_impl() for Contiki */ +#define _coap_address_isany_impl(A) 0 + +#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) + +#else /* WITH_LWIP || WITH_CONTIKI */ + + /** multi-purpose address abstraction */ +typedef struct coap_address_t { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +} coap_address_t; + +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +int coap_address_equals(const coap_address_t *a, const coap_address_t *b); + +COAP_STATIC_INLINE int +_coap_address_isany_impl(const coap_address_t *a) { + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return a->addr.sin.sin_addr.s_addr == INADDR_ANY; + case AF_INET6: + return memcmp(&in6addr_any, + &a->addr.sin6.sin6_addr, + sizeof(in6addr_any)) == 0; + default: + ; + } + + return 0; +} +#endif /* WITH_LWIP || WITH_CONTIKI */ + +/** + * Resets the given coap_address_t object @p addr to its default values. In + * particular, the member size must be initialized to the available size for + * storing addresses. + * + * @param addr The coap_address_t object to initialize. + */ +COAP_STATIC_INLINE void +coap_address_init(coap_address_t *addr) { + assert(addr); + memset(addr, 0, sizeof(coap_address_t)); +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + /* lwip and Contiki have constant address sizes and doesn't need the .size part */ + addr->size = sizeof(addr->addr); +#endif +} + +/* Convenience function to copy IPv6 addresses without garbage. */ + +COAP_STATIC_INLINE void +coap_address_copy( coap_address_t *dst, const coap_address_t *src ) { +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) + memcpy( dst, src, sizeof( coap_address_t ) ); +#else + memset( dst, 0, sizeof( coap_address_t ) ); + dst->size = src->size; + if ( src->addr.sa.sa_family == AF_INET6 ) { + dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family; + dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr; + dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port; + dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id; + } else if ( src->addr.sa.sa_family == AF_INET ) { + dst->addr.sin = src->addr.sin; + } else { + memcpy( &dst->addr, &src->addr, src->size ); + } +#endif +} + +#if defined(WITH_LWIP) || defined(WITH_CONTIKI) +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_equals(const coap_address_t *a, const coap_address_t *b) { + assert(a); assert(b); + return _coap_address_equals_impl(a, b); +} +#endif + +/** + * Checks if given address object @p a denotes the wildcard address. This + * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p + * a must not be @c NULL; + */ +COAP_STATIC_INLINE int +coap_address_isany(const coap_address_t *a) { + assert(a); + return _coap_address_isany_impl(a); +} + +#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) + +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +int coap_is_mcast(const coap_address_t *a); +#else /* !WITH_LWIP && !WITH_CONTIKI */ +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +coap_is_mcast(const coap_address_t *a) { + return a && _coap_is_mcast_impl(a); +} +#endif /* !WITH_LWIP && !WITH_CONTIKI */ + +#endif /* COAP_ADDRESS_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/async.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/async.h new file mode 100644 index 00000000000..e399929677d --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/async.h @@ -0,0 +1,148 @@ +/* + * async.h -- state management for asynchronous messages + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file async.h + * @brief State management for asynchronous messages + */ + +#ifndef COAP_ASYNC_H_ +#define COAP_ASYNC_H_ + +#include "net.h" + +#ifndef WITHOUT_ASYNC + +/** + * @defgroup coap_async Asynchronous Messaging + * @{ + * Structure for managing asynchronous state of CoAP resources. A + * coap_resource_t object holds a list of coap_async_state_t objects that can be + * used to generate a separate response in case a result of an operation cannot + * be delivered in time, or the resource has been explicitly subscribed to with + * the option @c observe. + */ +typedef struct coap_async_state_t { + unsigned char flags; /**< holds the flags to control behaviour */ + + /** + * Holds the internal time when the object was registered with a + * resource. This field will be updated whenever + * coap_register_async() is called for a specific resource. + */ + coap_tick_t created; + + /** + * This field can be used to register opaque application data with the + * asynchronous state object. + */ + void *appdata; + coap_session_t *session; /**< transaction session */ + coap_tid_t id; /**< transaction id */ + struct coap_async_state_t *next; /**< internally used for linking */ + size_t tokenlen; /**< length of the token */ + uint8_t token[8]; /**< the token to use in a response */ +} coap_async_state_t; + +/* Definitions for Async Status Flags These flags can be used to control the + * behaviour of asynchronous response generation. + */ +#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */ +#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */ +#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */ + +/** release application data on destruction */ +#define COAP_ASYNC_RELEASE_DATA 0x08 + +/** + * Allocates a new coap_async_state_t object and fills its fields according to + * the given @p request. The @p flags are used to control generation of empty + * ACK responses to stop retransmissions and to release registered @p data when + * the resource is deleted by coap_free_async(). This function returns a pointer + * to the registered coap_async_t object or @c NULL on error. Note that this + * function will return @c NULL in case that an object with the same identifier + * is already registered. + * + * @param context The context to use. + * @param session The session that is used for asynchronous transmissions. + * @param request The request that is handled asynchronously. + * @param flags Flags to control state management. + * @param data Opaque application data to register. Note that the + * storage occupied by @p data is released on destruction + * only if flag COAP_ASYNC_RELEASE_DATA is set. + * + * @return A pointer to the registered coap_async_state_t object or @c + * NULL in case of an error. + */ +coap_async_state_t * +coap_register_async(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request, + unsigned char flags, + void *data); + +/** + * Removes the state object identified by @p id from @p context. The removed + * object is returned in @p s, if found. Otherwise, @p s is undefined. This + * function returns @c 1 if the object was removed, @c 0 otherwise. Note that + * the storage allocated for the stored object is not released by this + * functions. You will have to call coap_free_async() to do so. + * + * @param context The context where the async object is registered. + * @param session The session that is used for asynchronous transmissions. + * @param id The identifier of the asynchronous transaction. + * @param s Will be set to the object identified by @p id after removal. + * + * @return @c 1 if object was removed and @p s updated, or @c 0 if no + * object was found with the given id. @p s is valid only if the + * return value is @c 1. + */ +int coap_remove_async(coap_context_t *context, + coap_session_t *session, + coap_tid_t id, + coap_async_state_t **s); + +/** + * Releases the memory that was allocated by coap_async_state_init() for the + * object @p s. The registered application data will be released automatically + * if COAP_ASYNC_RELEASE_DATA is set. + * + * @param state The object to delete. + */ +void +coap_free_async(coap_async_state_t *state); + +/** + * Retrieves the object identified by @p id from the list of asynchronous + * transactions that are registered with @p context. This function returns a + * pointer to that object or @c NULL if not found. + * + * @param context The context where the asynchronous objects are registered + * with. + * @param session The session that is used for asynchronous transmissions. + * @param id The id of the object to retrieve. + * + * @return A pointer to the object identified by @p id or @c NULL if + * not found. + */ +coap_async_state_t *coap_find_async(coap_context_t *context, coap_session_t *session, coap_tid_t id); + +/** + * Updates the time stamp of @p s. + * + * @param s The state object to update. + */ +COAP_STATIC_INLINE void +coap_touch_async(coap_async_state_t *s) { coap_ticks(&s->created); } + +/** @} */ + +#endif /* WITHOUT_ASYNC */ + +#endif /* COAP_ASYNC_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/bits.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/bits.h new file mode 100644 index 00000000000..3b1871487c9 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/bits.h @@ -0,0 +1,78 @@ +/* + * bits.h -- bit vector manipulation + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file bits.h + * @brief Bit vector manipulation + */ + +#ifndef COAP_BITS_H_ +#define COAP_BITS_H_ + +#include + +/** + * Sets the bit @p bit in bit-vector @p vec. This function returns @c 1 if bit + * was set or @c -1 on error (i.e. when the given bit does not fit in the + * vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to set in @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_setb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07)); + return 1; +} + +/** + * Clears the bit @p bit from bit-vector @p vec. This function returns @c 1 if + * bit was cleared or @c -1 on error (i.e. when the given bit does not fit in + * the vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to clear from @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +COAP_STATIC_INLINE int +bits_clrb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + *(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07))); + return 1; +} + +/** + * Gets the status of bit @p bit from bit-vector @p vec. This function returns + * @c 1 if the bit is set, @c 0 otherwise (even in case of an error). + * + * @param vec The bit-vector to read from. + * @param size The size of @p vec in bytes. + * @param bit The bit to get from @p vec. + * + * @return @c 1 if the bit is set, @c 0 otherwise. + */ +COAP_STATIC_INLINE int +bits_getb(const uint8_t *vec, size_t size, uint8_t bit) { + if (size <= ((size_t)bit >> 3)) + return -1; + + return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0; +} + +#endif /* COAP_BITS_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/block.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/block.h new file mode 100644 index 00000000000..848897639c9 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/block.h @@ -0,0 +1,173 @@ +/* + * block.h -- block transfer + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_BLOCK_H_ +#define COAP_BLOCK_H_ + +#include "encode.h" +#include "option.h" +#include "pdu.h" + +struct coap_resource_t; +struct coap_session_t; + +/** + * @defgroup block Block Transfer + * API functions for handling PDUs using CoAP BLOCK options + * @{ + */ + +#ifndef COAP_MAX_BLOCK_SZX +/** + * The largest value for the SZX component in a Block option. + */ +#define COAP_MAX_BLOCK_SZX 6 +#endif /* COAP_MAX_BLOCK_SZX */ + +/** + * Structure of Block options. + */ +typedef struct { + unsigned int num; /**< block number */ + unsigned int m:1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx:3; /**< block size */ +} coap_block_t; + +/** + * Returns the value of the least significant byte of a Block option @p opt. + * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST + * returns @c NULL. + */ +#define COAP_OPT_BLOCK_LAST(opt) \ + (coap_opt_length(opt) ? (coap_opt_value(opt) + (coap_opt_length(opt)-1)) : 0) + +/** Returns the value of the More-bit of a Block option @p opt. */ +#define COAP_OPT_BLOCK_MORE(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0) + +/** Returns the value of the SZX-field of a Block option @p opt. */ +#define COAP_OPT_BLOCK_SZX(opt) \ + (coap_opt_length(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0) + +/** + * Returns the value of field @c num in the given block option @p block_opt. + */ +unsigned int coap_opt_block_num(const coap_opt_t *block_opt); + +/** + * Checks if more than @p num blocks are required to deliver @p data_len + * bytes of data for a block size of 1 << (@p szx + 4). + */ +COAP_STATIC_INLINE int +coap_more_blocks(size_t data_len, unsigned int num, uint16_t szx) { + return ((num+1) << (szx + 4)) < data_len; +} + +#if 0 +/** Sets the More-bit in @p block_opt */ +COAP_STATIC_INLINE void +coap_opt_block_set_m(coap_opt_t *block_opt, int m) { + if (m) + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) |= 0x08; + else + *(coap_opt_value(block_opt) + (coap_opt_length(block_opt) - 1)) &= ~0x08; +} +#endif + +/** + * Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1 + * or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block is + * initialized with values from this option and the function returns the value + * @c 1. Otherwise, @c 0 is returned. + * + * @param pdu The pdu to search for option @p type. + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * COAP_OPTION_BLOCK2). + * @param block The block structure to initilize. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_get_block(coap_pdu_t *pdu, uint16_t type, coap_block_t *block); + +/** + * Writes a block option of type @p type to message @p pdu. If the requested + * block size is too large to fit in @p pdu, it is reduced accordingly. An + * exception is made for the final block when less space is required. The actual + * length of the resource is specified in @p data_length. + * + * This function may change *block to reflect the values written to @p pdu. As + * the function takes into consideration the remaining space @p pdu, no more + * options should be added after coap_write_block_opt() has returned. + * + * @param block The block structure to use. On return, this object is + * updated according to the values that have been written to + * @p pdu. + * @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2. + * @param pdu The message where the block option should be written. + * @param data_length The length of the actual data that will be added the @p + * pdu by calling coap_add_block(). + * + * @return @c 1 on success, or a negative value on error. + */ +int coap_write_block_opt(coap_block_t *block, + uint16_t type, + coap_pdu_t *pdu, + size_t data_length); + +/** + * Adds the @p block_num block of size 1 << (@p block_szx + 4) from source @p + * data to @p pdu. + * + * @param pdu The message to add the block. + * @param len The length of @p data. + * @param data The source data to fill the block with. + * @param block_num The actual block number. + * @param block_szx Encoded size of block @p block_number. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_add_block(coap_pdu_t *pdu, + unsigned int len, + const uint8_t *data, + unsigned int block_num, + unsigned char block_szx); + +/** + * Adds the appropriate part of @p data to the @p response pdu. If blocks are + * required, then the appropriate block will be added to the PDU and sent. + * Adds a ETAG option that is the hash of the entire data if the data is to be + * split into blocks + * Used by a GET request handler. + * + * @param resource The resource the data is associated with. + * @param session The coap session. + * @param request The requesting pdu. + * @param response The response pdu. + * @param token The token taken from the (original) requesting pdu. + * @param media_type The format of the data. + * @param maxage The maxmimum life of the data. If @c -1, then there + * is no maxage. + * @param length The total length of the data. + * @param data The entire data block to transmit. + * + */ +void +coap_add_data_blocked_response(struct coap_resource_t *resource, + struct coap_session_t *session, + coap_pdu_t *request, + coap_pdu_t *response, + const coap_binary_t *token, + uint16_t media_type, + int maxage, + size_t length, + const uint8_t* data); + +/**@}*/ + +#endif /* COAP_BLOCK_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_debug.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_debug.h new file mode 100644 index 00000000000..e4631b71f2b --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_debug.h @@ -0,0 +1,209 @@ +/* + * coap_debug.h -- debug utilities + * + * Copyright (C) 2010-2011,2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DEBUG_H_ +#define COAP_DEBUG_H_ + +/** + * @defgroup logging Logging Support + * API functions for logging support + * @{ + */ + +#ifndef COAP_DEBUG_FD +/** + * Used for output for @c LOG_DEBUG to @c LOG_ERR. + */ +#define COAP_DEBUG_FD stdout +#endif + +#ifndef COAP_ERR_FD +/** + * Used for output for @c LOG_CRIT to @c LOG_EMERG. + */ +#define COAP_ERR_FD stderr +#endif + +#ifdef HAVE_SYSLOG_H +#include +/** + * Logging type. One of LOG_* from @b syslog. + */ +typedef short coap_log_t; +#else +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { + LOG_EMERG=0, /**< Emergency */ + LOG_ALERT, /**< Alert */ + LOG_CRIT, /**< Critical */ + LOG_ERR, /**< Error */ + LOG_WARNING, /**< Warning */ + LOG_NOTICE, /**< Notice */ + LOG_INFO, /**< Information */ + LOG_DEBUG /**< Debug */ +} coap_log_t; +#endif + +/** + * Get the current logging level. + * + * @return One of the LOG_* values. + */ +coap_log_t coap_get_log_level(void); + +/** + * Sets the log level to the specified value. + * + * @param level One of the LOG_* values. + */ +void coap_set_log_level(coap_log_t level); + +/** + * Logging call-back handler definition. + * + * @param level One of the LOG_* values. + * @param message Zero-terminated string message to log. + */ +typedef void (*coap_log_handler_t) (coap_log_t level, const char *message); + +/** + * Add a custom log callback handler. + * + * @param handler The logging handler to use or @p NULL to use default handler. + */ +void coap_set_log_handler(coap_log_handler_t handler); + +/** + * Get the library package name. + * + * @return Zero-terminated string with the name of this library. + */ +const char *coap_package_name(void); + +/** + * Get the library package version. + * + * @return Zero-terminated string with the library version. + */ +const char *coap_package_version(void); + +/** + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * Internal function. + * + * @param level One of the LOG_* values. + & @param format The format string to use. + */ +#if (defined(__GNUC__)) +void coap_log_impl(coap_log_t level, + const char *format, ...) __attribute__ ((format(printf, 2, 3))); +#else +void coap_log_impl(coap_log_t level, const char *format, ...); +#endif + +#ifndef coap_log +/** + * Logging function. + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_ERR). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + * + * @param level One of the LOG_* values. + */ +#define coap_log(level, ...) do { \ + if ((int)((level))<=(int)coap_get_log_level()) \ + coap_log_impl((level), __VA_ARGS__); \ +} while(0) +#endif + +#include "pdu.h" + +/** + * Defines the output mode for the coap_show_pdu() function. + * + * @param use_fprintf @p 1 if the output is to use fprintf() (the default) + * @p 0 if the output is to use coap_log(). + */ +void coap_set_show_pdu_output(int use_fprintf); + +/** + * Display the contents of the specified @p pdu. + * Note: The output method of coap_show_pdu() is dependent on the setting of + * coap_set_show_pdu_output(). + * + * @param level The required minimum logging level. + * @param pdu The PDU to decode. + */ +void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu); + +/** + * Display the current (D)TLS library linked with and built for version. + * + * @param level The required minimum logging level. + */ +void coap_show_tls_version(coap_log_t level); + +/** + * Build a string containing the current (D)TLS library linked with and + * built for version. + * + * @param buffer The buffer to put the string into. + * @param bufsize The size of the buffer to put the string into. + * + * @return A pointer to the provided buffer. + */ +char *coap_string_tls_version(char *buffer, size_t bufsize); + +struct coap_address_t; + +/** + * Print the address into the defined buffer. + * + * Internal Function. + * + * @param address The address to print. + * @param buffer The buffer to print into. + * @param size The size of the buffer to print into. + * + * @return The amount written into the buffer. + */ +size_t coap_print_addr(const struct coap_address_t *address, + unsigned char *buffer, size_t size); + +/** @} */ + +/** + * Set the packet loss level for testing. This can be in one of two forms. + * + * Percentage : 0% to 100%. Use the specified probability. + * 0% is send all packets, 100% is drop all packets. + * + * List: A comma separated list of numbers or number ranges that are the + * packets to drop. + * + * @param loss_level The defined loss level (percentage or list). + * + * @return @c 1 If loss level set, @c 0 if there is an error. + */ +int coap_debug_set_packet_loss(const char *loss_level); + +/** + * Check to see whether a packet should be sent or not. + * + * Internal function + * + * @return @c 1 if packet is to be sent, @c 0 if packet is to be dropped. + */ +int coap_debug_send_packet(void); + + +#endif /* COAP_DEBUG_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_dtls.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_dtls.h new file mode 100644 index 00000000000..f0554f3dfea --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_dtls.h @@ -0,0 +1,611 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +#define COAP_TLS_LIBRARY_NOTLS 0 /**< No DTLS library */ +#define COAP_TLS_LIBRARY_TINYDTLS 1 /**< Using TinyDTLS library */ +#define COAP_TLS_LIBRARY_OPENSSL 2 /**< Using OpenSSL library */ +#define COAP_TLS_LIBRARY_GNUTLS 3 /**< Using GnuTLS library */ + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + int type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t reserved[6]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 6 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_event.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_event.h new file mode 100644 index 00000000000..81a3b0511fd --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_event.h @@ -0,0 +1,102 @@ +/* + * coap_event.h -- libcoap Event API + * + * Copyright (C) 2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_EVENT_H_ +#define COAP_EVENT_H_ + +#include "libcoap.h" + +struct coap_context_t; +struct coap_session_t; + +/** + * @defgroup events Event API + * API functions for event delivery from lower-layer library functions. + * @{ + */ + +/** + * Scalar type to represent different events, e.g. DTLS events or + * retransmission timeouts. + */ + typedef unsigned int coap_event_t; + +/** + * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS + */ +#define COAP_EVENT_DTLS_CLOSED 0x0000 +#define COAP_EVENT_DTLS_CONNECTED 0x01DE +#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF +#define COAP_EVENT_DTLS_ERROR 0x0200 + +/** + * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS + */ +#define COAP_EVENT_TCP_CONNECTED 0x1001 +#define COAP_EVENT_TCP_CLOSED 0x1002 +#define COAP_EVENT_TCP_FAILED 0x1003 + +/** + * CSM exchange events for reliable protocols only + */ +#define COAP_EVENT_SESSION_CONNECTED 0x2001 +#define COAP_EVENT_SESSION_CLOSED 0x2002 +#define COAP_EVENT_SESSION_FAILED 0x2003 + +/** + * Type for event handler functions that can be registered with a CoAP + * context using the unction coap_set_event_handler(). When called by + * the library, the first argument will be the coap_context_t object + * where the handler function has been registered. The second argument + * is the event type that may be complemented by event-specific data + * passed as the third argument. + */ +typedef int (*coap_event_handler_t)(struct coap_context_t *, + coap_event_t event, + struct coap_session_t *session); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. @c NULL if to be + * de-registered. + */ +void coap_register_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Registers the function @p hnd as callback for events from the given + * CoAP context @p context. Any event handler that has previously been + * registered with @p context will be overwritten by this operation. + * + * @deprecated Use coap_register_event_handler() instead. + * + * @param context The CoAP context to register the event handler with. + * @param hnd The event handler to be registered. + */ +COAP_DEPRECATED +void coap_set_event_handler(struct coap_context_t *context, + coap_event_handler_t hnd); + +/** + * Clears the event handler registered with @p context. + * + * @deprecated Use coap_register_event_handler() instead with NULL for hnd. + * + * @param context The CoAP context whose event handler is to be removed. + */ +COAP_DEPRECATED +void coap_clear_event_handler(struct coap_context_t *context); + +/** @} */ + +#endif /* COAP_EVENT_H */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_hashkey.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_hashkey.h new file mode 100644 index 00000000000..252f34822d4 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_hashkey.h @@ -0,0 +1,59 @@ +/* + * coap_hashkey.h -- definition of hash key type and helper functions + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_hashkey.h + * @brief definition of hash key type and helper functions + */ + +#ifndef COAP_HASHKEY_H_ +#define COAP_HASHKEY_H_ + +#include "libcoap.h" +#include "uthash.h" +#include "str.h" + +typedef unsigned char coap_key_t[4]; + +#ifndef coap_hash +/** + * Calculates a fast hash over the given string @p s of length @p len and stores + * the result into @p h. Depending on the exact implementation, this function + * cannot be used as one-way function to check message integrity or simlar. + * + * @param s The string used for hash calculation. + * @param len The length of @p s. + * @param h The result buffer to store the calculated hash key. + */ +void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); + +#define coap_hash(String,Length,Result) \ + coap_hash_impl((String),(Length),(Result)) + +/* This is used to control the pre-set hash-keys for resources. */ +#define COAP_DEFAULT_HASH +#else +#undef COAP_DEFAULT_HASH +#endif /* coap_hash */ + +/** + * Calls coap_hash() with given @c coap_string_t object as parameter. + * + * @param Str Must contain a pointer to a coap string object. + * @param H A coap_key_t object to store the result. + * + * @hideinitializer + */ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((Str)->s, (Str)->length, (H)); \ + } + +#endif /* COAP_HASHKEY_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_io.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_io.h new file mode 100644 index 00000000000..1854501be89 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_io.h @@ -0,0 +1,210 @@ +/* + * coap_io.h -- Default network I/O functions for libcoap + * + * Copyright (C) 2012-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_IO_H_ +#define COAP_IO_H_ + +#include +#include + +#include "address.h" + +#ifndef COAP_RXBUFFER_SIZE +#define COAP_RXBUFFER_SIZE 1472 +#endif /* COAP_RXBUFFER_SIZE */ + +#ifdef _WIN32 +typedef SOCKET coap_fd_t; +#define coap_closesocket closesocket +#define COAP_SOCKET_ERROR SOCKET_ERROR +#define COAP_INVALID_SOCKET INVALID_SOCKET +#else +typedef int coap_fd_t; +#define coap_closesocket close +#define COAP_SOCKET_ERROR (-1) +#define COAP_INVALID_SOCKET (-1) +#endif + +struct coap_packet_t; +struct coap_session_t; +struct coap_pdu_t; + +typedef uint16_t coap_socket_flags_t; + +typedef struct coap_socket_t { +#if defined(WITH_LWIP) + struct udp_pcb *pcb; +#elif defined(WITH_CONTIKI) + void *conn; +#else + coap_fd_t fd; +#endif /* WITH_LWIP */ + coap_socket_flags_t flags; +} coap_socket_t; + +/** + * coap_socket_flags_t values + */ +#define COAP_SOCKET_EMPTY 0x0000 /**< the socket is not used */ +#define COAP_SOCKET_NOT_EMPTY 0x0001 /**< the socket is not empty */ +#define COAP_SOCKET_BOUND 0x0002 /**< the socket is bound */ +#define COAP_SOCKET_CONNECTED 0x0004 /**< the socket is connected */ +#define COAP_SOCKET_WANT_READ 0x0010 /**< non blocking socket is waiting for reading */ +#define COAP_SOCKET_WANT_WRITE 0x0020 /**< non blocking socket is waiting for writing */ +#define COAP_SOCKET_WANT_ACCEPT 0x0040 /**< non blocking server socket is waiting for accept */ +#define COAP_SOCKET_WANT_CONNECT 0x0080 /**< non blocking client socket is waiting for connect */ +#define COAP_SOCKET_CAN_READ 0x0100 /**< non blocking socket can now read without blocking */ +#define COAP_SOCKET_CAN_WRITE 0x0200 /**< non blocking socket can now write without blocking */ +#define COAP_SOCKET_CAN_ACCEPT 0x0400 /**< non blocking server socket can now accept without blocking */ +#define COAP_SOCKET_CAN_CONNECT 0x0800 /**< non blocking client socket can now connect without blocking */ +#define COAP_SOCKET_MULTICAST 0x1000 /**< socket is used for multicast communication */ + +struct coap_endpoint_t *coap_malloc_endpoint( void ); +void coap_mfree_endpoint( struct coap_endpoint_t *ep ); + +int +coap_socket_connect_udp(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_udp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr ); + +int +coap_socket_connect_tcp1(coap_socket_t *sock, + const coap_address_t *local_if, + const coap_address_t *server, + int default_port, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_connect_tcp2(coap_socket_t *sock, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +int +coap_socket_bind_tcp(coap_socket_t *sock, + const coap_address_t *listen_addr, + coap_address_t *bound_addr); + +int +coap_socket_accept_tcp(coap_socket_t *server, + coap_socket_t *new_client, + coap_address_t *local_addr, + coap_address_t *remote_addr); + +void coap_socket_close(coap_socket_t *sock); + +ssize_t +coap_socket_send( coap_socket_t *sock, struct coap_session_t *session, + const uint8_t *data, size_t data_len ); + +ssize_t +coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len); + +ssize_t +coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len); + +#ifdef WITH_LWIP +ssize_t +coap_socket_send_pdu( coap_socket_t *sock, struct coap_session_t *session, + struct coap_pdu_t *pdu ); +#endif + +const char *coap_socket_strerror( void ); + +/** + * Function interface for data transmission. This function returns the number of + * bytes that have been transmitted, or a value less than zero on error. + * + * @param sock Socket to send data with + * @param session Addressing information for unconnected sockets, or NULL + * @param data The data to send. + * @param datalen The actual length of @p data. + * + * @return The number of bytes written on success, or a value + * less than zero on error. + */ +ssize_t coap_network_send( coap_socket_t *sock, const struct coap_session_t *session, const uint8_t *data, size_t datalen ); + +/** + * Function interface for reading data. This function returns the number of + * bytes that have been read, or a value less than zero on error. In case of an + * error, @p *packet is set to NULL. + * + * @param sock Socket to read data from + * @param packet Received packet metadata and payload. src and dst should be preset. + * + * @return The number of bytes received on success, or a value less than + * zero on error. + */ +ssize_t coap_network_read( coap_socket_t *sock, struct coap_packet_t *packet ); + +#ifndef coap_mcast_interface +# define coap_mcast_interface(Local) 0 +#endif + +/** + * Given a packet, set msg and msg_len to an address and length of the packet's + * data in memory. + * */ +void coap_packet_get_memmapped(struct coap_packet_t *packet, + unsigned char **address, + size_t *length); + +#ifdef WITH_LWIP +/** + * Get the pbuf of a packet. The caller takes over responsibility for freeing + * the pbuf. + */ +struct pbuf *coap_packet_extract_pbuf(struct coap_packet_t *packet); +#endif + +#if defined(WITH_LWIP) +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in lwippools.h. + * Simple carry-over of the incoming pbuf that is later turned into a node. + * + * Source address data is currently side-banded via ip_current_dest_addr & co + * as the packets have limited lifetime anyway. + */ +struct coap_packet_t { + struct pbuf *pbuf; + const struct coap_endpoint_t *local_interface; + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ +// uint16_t srcport; +}; +#else +struct coap_packet_t { + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + int ifindex; /**< the interface index */ + size_t length; /**< length of payload */ + unsigned char payload[COAP_RXBUFFER_SIZE]; /**< payload */ +}; +#endif +typedef struct coap_packet_t coap_packet_t; + +typedef enum { + COAP_NACK_TOO_MANY_RETRIES, + COAP_NACK_NOT_DELIVERABLE, + COAP_NACK_RST, + COAP_NACK_TLS_FAILED +} coap_nack_reason_t; + +#endif /* COAP_IO_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_mutex.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_mutex.h new file mode 100644 index 00000000000..99d7d335e47 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_mutex.h @@ -0,0 +1,50 @@ +/* + * coap_mutex.h -- mutex utilities + * + * Copyright (C) 2019 Jon Shallow + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_mutex.h + * @brief COAP mutex mechanism wrapper + */ + +#ifndef COAP_MUTEX_H_ +#define COAP_MUTEX_H_ + +#if defined(RIOT_VERSION) + +#include + +typedef mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER MUTEX_INIT +#define coap_mutex_lock(a) mutex_lock(a) +#define coap_mutex_trylock(a) mutex_trylock(a) +#define coap_mutex_unlock(a) mutex_unlock(a) + +#elif defined(WITH_CONTIKI) + +/* CONTIKI does not support mutex */ + +typedef int coap_mutex_t; +#define COAP_MUTEX_INITIALIZER 0 +#define coap_mutex_lock(a) *(a) = 1 +#define coap_mutex_trylock(a) *(a) = 1 +#define coap_mutex_unlock(a) *(a) = 0 + +#else /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#include + +typedef pthread_mutex_t coap_mutex_t; +#define COAP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define coap_mutex_lock(a) pthread_mutex_lock(a) +#define coap_mutex_trylock(a) pthread_mutex_trylock(a) +#define coap_mutex_unlock(a) pthread_mutex_unlock(a) + +#endif /* ! RIOT_VERSION && ! WITH_CONTIKI */ + +#endif /* COAP_MUTEX_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_session.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_session.h new file mode 100644 index 00000000000..1dc0103e3e7 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_session.h @@ -0,0 +1,492 @@ +/* coap_session.h -- Session management for libcoap +* +* Copyright (C) 2017 Jean-Claue Michelou +* +* This file is part of the CoAP library libcoap. Please see +* README for terms of use. +*/ + +#ifndef COAP_SESSION_H_ +#define COAP_SESSION_H_ + + +#include "coap_io.h" +#include "coap_time.h" +#include "pdu.h" + +struct coap_endpoint_t; +struct coap_context_t; +struct coap_queue_t; + +/** +* Abstraction of a fixed point number that can be used where necessary instead +* of a float. 1,000 fractional bits equals one integer +*/ +typedef struct coap_fixed_point_t { + uint16_t integer_part; /**< Integer part of fixed point variable */ + uint16_t fractional_part; /**< Fractional part of fixed point variable + 1/1000 (3 points) precision */ +} coap_fixed_point_t; + +#define COAP_DEFAULT_SESSION_TIMEOUT 300 +#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND) +#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100 + +#define COAP_PROTO_NOT_RELIABLE(p) ((p)==COAP_PROTO_UDP || (p)==COAP_PROTO_DTLS) +#define COAP_PROTO_RELIABLE(p) ((p)==COAP_PROTO_TCP || (p)==COAP_PROTO_TLS) + +typedef uint8_t coap_session_type_t; +/** + * coap_session_type_t values + */ +#define COAP_SESSION_TYPE_CLIENT 1 /**< client-side */ +#define COAP_SESSION_TYPE_SERVER 2 /**< server-side */ +#define COAP_SESSION_TYPE_HELLO 3 /**< server-side ephemeral session for responding to a client hello */ + +typedef uint8_t coap_session_state_t; +/** + * coap_session_state_t values + */ +#define COAP_SESSION_STATE_NONE 0 +#define COAP_SESSION_STATE_CONNECTING 1 +#define COAP_SESSION_STATE_HANDSHAKE 2 +#define COAP_SESSION_STATE_CSM 3 +#define COAP_SESSION_STATE_ESTABLISHED 4 + +typedef struct coap_session_t { + struct coap_session_t *next; + coap_proto_t proto; /**< protocol used */ + coap_session_type_t type; /**< client or server side socket */ + coap_session_state_t state; /**< current state of relationaship with peer */ + unsigned ref; /**< reference count from queues */ + unsigned tls_overhead; /**< overhead of TLS layer */ + unsigned mtu; /**< path or CSM mtu */ + coap_address_t local_if; /**< optional local interface address */ + coap_address_t remote_addr; /**< remote address and port */ + coap_address_t local_addr; /**< local address and port */ + int ifindex; /**< interface index */ + coap_socket_t sock; /**< socket object for the session, if any */ + struct coap_endpoint_t *endpoint; /**< session's endpoint */ + struct coap_context_t *context; /**< session's context */ + void *tls; /**< security parameters */ + uint16_t tx_mid; /**< the last message id that was used in this session */ + uint8_t con_active; /**< Active CON request sent */ + struct coap_queue_t *delayqueue; /**< list of delayed messages waiting to be sent */ + size_t partial_write; /**< if > 0 indicates number of bytes already written from the pdu at the head of sendqueue */ + uint8_t read_header[8]; /**< storage space for header of incoming message header */ + size_t partial_read; /**< if > 0 indicates number of bytes already read for an incoming message */ + coap_pdu_t *partial_pdu; /**< incomplete incoming pdu */ + coap_tick_t last_rx_tx; + coap_tick_t last_tx_rst; + coap_tick_t last_ping; + coap_tick_t last_pong; + coap_tick_t csm_tx; + uint8_t *psk_identity; + size_t psk_identity_len; + uint8_t *psk_key; + size_t psk_key_len; + void *app; /**< application-specific data */ + unsigned int max_retransmit; /**< maximum re-transmit count (default 4) */ + coap_fixed_point_t ack_timeout; /**< timeout waiting for ack (default 2 secs) */ + coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default 1.5) */ + unsigned int dtls_timeout_count; /**< dtls setup retry counter */ + int dtls_event; /**< Tracking any (D)TLS events on this sesison */ +} coap_session_t; + +/** +* Increment reference counter on a session. +* +* @param session The CoAP session. +* @return same as session +*/ +coap_session_t *coap_session_reference(coap_session_t *session); + +/** +* Decrement reference counter on a session. +* Note that the session may be deleted as a result and should not be used +* after this call. +* +* @param session The CoAP session. +*/ +void coap_session_release(coap_session_t *session); + +/** +* Stores @p data with the given session. This function overwrites any value +* that has previously been stored with @p session. +*/ +void coap_session_set_app_data(coap_session_t *session, void *data); + +/** +* Returns any application-specific data that has been stored with @p +* session using the function coap_session_set_app_data(). This function will +* return @c NULL if no data has been stored. +*/ +void *coap_session_get_app_data(const coap_session_t *session); + +/** +* Notify session that it has failed. +* +* @param session The CoAP session. +* @param reason The reason why the session was disconnected. +*/ +void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason); + +/** +* Notify session transport has just connected and CSM exchange can now start. +* +* @param session The CoAP session. +*/ +void coap_session_send_csm(coap_session_t *session); + +/** +* Notify session that it has just connected or reconnected. +* +* @param session The CoAP session. +*/ +void coap_session_connected(coap_session_t *session); + +/** +* Set the session MTU. This is the maximum message size that can be sent, +* excluding IP and UDP overhead. +* +* @param session The CoAP session. +* @param mtu maximum message size +*/ +void coap_session_set_mtu(coap_session_t *session, unsigned mtu); + +/** + * Get maximum acceptable PDU size + * + * @param session The CoAP session. + * @return maximum PDU size, not including header (but including token). + */ +size_t coap_session_max_pdu_size(const coap_session_t *session); + +/** +* Creates a new client session to the designated server. +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto +); + +/** +* Creates a new client session to the designated server with PSK credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to let the operating system choose a suitable local interface. If an address is specified, the port number should be zero, which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default port for the protocol will be used. +* @param proto Protocol. +* @param identity PSK client identity +* @param key PSK shared key +* @param key_len PSK shared key length +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_client_session_psk( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + const char *identity, + const uint8_t *key, + unsigned key_len +); + +struct coap_dtls_pki_t; + +/** +* Creates a new client session to the designated server with PKI credentials +* @param ctx The CoAP context. +* @param local_if Address of local interface. It is recommended to use NULL to +* let the operating system choose a suitable local interface. +* If an address is specified, the port number should be zero, +* which means that a free port is automatically selected. +* @param server The server's address. If the port number is zero, the default +* port for the protocol will be used. +* @param proto CoAP Protocol. +* @param setup_data PKI parameters. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release() +* to free. +*/ +coap_session_t *coap_new_client_session_pki( + struct coap_context_t *ctx, + const coap_address_t *local_if, + const coap_address_t *server, + coap_proto_t proto, + struct coap_dtls_pki_t *setup_data +); + +/** +* Creates a new server session for the specified endpoint. +* @param ctx The CoAP context. +* @param ep An endpoint where an incoming connection request is pending. +* +* @return A new CoAP session or NULL if failed. Call coap_session_release to free. +*/ +coap_session_t *coap_new_server_session( + struct coap_context_t *ctx, + struct coap_endpoint_t *ep +); + +/** +* Function interface for datagram data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Function interface for stream data transmission. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. The number of bytes written may be less than datalen because of +* congestion control. +* +* @param session Session to send data on. +* @param data The data to send. +* @param datalen The actual length of @p data. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_write(coap_session_t *session, + const uint8_t *data, size_t datalen); + +/** +* Send a pdu according to the session's protocol. This function returns +* the number of bytes that have been transmitted, or a value less than zero +* on error. +* +* @param session Session to send pdu on. +* @param pdu The pdu to send. +* +* @return The number of bytes written on success, or a value +* less than zero on error. +*/ +ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu); + + +/** + * @ingroup logging + * Get session description. + * + * @param session The CoAP session. + * @return description string. + */ +const char *coap_session_str(const coap_session_t *session); + +ssize_t +coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, + struct coap_queue_t *node); +/** +* Abstraction of virtual endpoint that can be attached to coap_context_t. The +* tuple (handle, addr) must uniquely identify this endpoint. +*/ +typedef struct coap_endpoint_t { + struct coap_endpoint_t *next; + struct coap_context_t *context; /**< endpoint's context */ + coap_proto_t proto; /**< protocol used on this interface */ + uint16_t default_mtu; /**< default mtu for this interface */ + coap_socket_t sock; /**< socket object for the interface, if any */ + coap_address_t bind_addr; /**< local interface address */ + coap_session_t *sessions; /**< list of active sessions */ +} coap_endpoint_t; + +/** +* Create a new endpoint for communicating with peers. +* +* @param context The coap context that will own the new endpoint +* @param listen_addr Address the endpoint will listen for incoming requests on or originate outgoing requests from. Use NULL to specify that no incoming request will be accepted and use a random endpoint. +* @param proto Protocol used on this endpoint +*/ + +coap_endpoint_t *coap_new_endpoint(struct coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto); + +/** +* Set the endpoint's default MTU. This is the maximum message size that can be +* sent, excluding IP and UDP overhead. +* +* @param endpoint The CoAP endpoint. +* @param mtu maximum message size +*/ +void coap_endpoint_set_default_mtu(coap_endpoint_t *endpoint, unsigned mtu); + +void coap_free_endpoint(coap_endpoint_t *ep); + + +/** + * @ingroup logging +* Get endpoint description. +* +* @param endpoint The CoAP endpoint. +* @return description string. +*/ +const char *coap_endpoint_str(const coap_endpoint_t *endpoint); + +/** +* Lookup the server session for the packet received on an endpoint, or create +* a new one. +* +* @param endpoint Active endpoint the packet was received on. +* @param packet Received packet. +* @param now The current time in ticks. +* @return The CoAP session or @c NULL if error. +*/ +coap_session_t *coap_endpoint_get_session(coap_endpoint_t *endpoint, + const struct coap_packet_t *packet, coap_tick_t now); + +/** + * Create a new DTLS session for the @p session. + * Note: the @p session is released if no DTLS server session can be created. + * + * @ingroup dtls_internal + * + * @param session Session to add DTLS session to + * @param now The current time in ticks. + * + * @return CoAP session or @c NULL if error. + */ +coap_session_t *coap_session_new_dtls_session(coap_session_t *session, + coap_tick_t now); + +coap_session_t *coap_session_get_by_peer(struct coap_context_t *ctx, + const struct coap_address_t *remote_addr, int ifindex); + +void coap_session_free(coap_session_t *session); +void coap_session_mfree(coap_session_t *session); + + /** + * @defgroup cc Rate Control + * The transmission parameters for CoAP rate control ("Congestion + * Control" in stream-oriented protocols) are defined in + * https://tools.ietf.org/html/rfc7252#section-4.8 + * @{ + */ + + /** + * Number of seconds when to expect an ACK or a response to an + * outstanding CON message. + * RFC 7252, Section 4.8 Default value of ACK_TIMEOUT is 2 + */ +#define COAP_DEFAULT_ACK_TIMEOUT ((coap_fixed_point_t){2,0}) + + /** + * A factor that is used to randomize the wait time before a message + * is retransmitted to prevent synchronization effects. + * RFC 7252, Section 4.8 Default value of ACK_RANDOM_FACTOR is 1.5 + */ +#define COAP_DEFAULT_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1,500}) + + /** + * Number of message retransmissions before message sending is stopped + * RFC 7252, Section 4.8 Default value of MAX_RETRANSMIT is 4 + */ +#define COAP_DEFAULT_MAX_RETRANSMIT 4 + + /** + * The number of simultaneous outstanding interactions that a client + * maintains to a given server. + * RFC 7252, Section 4.8 Default value of NSTART is 1 + */ +#define COAP_DEFAULT_NSTART 1 + + /** @} */ + +/** +* Set the CoAP maximum retransmit count before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* @param value The value to set to. The default is 4 and should not normally +* get changed. +*/ +void coap_session_set_max_retransmit(coap_session_t *session, + unsigned int value); + +/** +* Set the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 2 and should not normally +* get changed. +*/ +void coap_session_set_ack_timeout(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Set the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* @param value The value to set to. The default is 1.5 and should not normally +* get changed. +*/ +void coap_session_set_ack_random_factor(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Get the CoAP maximum retransmit before failure +* +* Number of message retransmissions before message sending is stopped +* +* @param session The CoAP session. +* +* @return Current maximum retransmit value +*/ +unsigned int coap_session_get_max_transmit(coap_session_t *session); + +/** +* Get the CoAP initial ack response timeout before the next re-transmit +* +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* +* @param session The CoAP session. +* +* @return Current ack response timeout value +*/ +coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t *session); + +/** +* Get the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* +* @param session The CoAP session. +* +* @return Current ack randomize value +*/ +coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t *session); + +/** + * Send a ping message for the session. + * @param session The CoAP session. + * + * @return COAP_INVALID_TID if there is an error + */ +coap_tid_t coap_session_send_ping(coap_session_t *session); + +#endif /* COAP_SESSION_H */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_time.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_time.h new file mode 100644 index 00000000000..e4a8e7c7c73 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/coap_time.h @@ -0,0 +1,162 @@ +/* + * coap_time.h -- Clock Handling + * + * Copyright (C) 2010-2019 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_time.h + * @brief Clock Handling + */ + +#ifndef COAP_TIME_H_ +#define COAP_TIME_H_ + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. + * @{ + */ + +#if defined(WITH_LWIP) + +#include +#include + +/* lwIP provides ms in sys_now */ +#define COAP_TICKS_PER_SECOND 1000 + +typedef uint32_t coap_tick_t; +typedef uint32_t coap_time_t; +typedef int32_t coap_tick_diff_t; + +COAP_STATIC_INLINE void coap_ticks_impl(coap_tick_t *t) { + *t = sys_now(); +} + +COAP_STATIC_INLINE void coap_clock_init_impl(void) { +} + +#define coap_clock_init coap_clock_init_impl +#define coap_ticks coap_ticks_impl + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#elif defined(WITH_CONTIKI) + +#include "clock.h" + +typedef clock_time_t coap_tick_t; +typedef clock_time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int coap_tick_diff_t; + +#define COAP_TICKS_PER_SECOND CLOCK_SECOND + +COAP_STATIC_INLINE void coap_clock_init(void) { + clock_init(); +} + +COAP_STATIC_INLINE void coap_ticks(coap_tick_t *t) { + *t = clock_time(); +} + +COAP_STATIC_INLINE coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} + +#else +#include + +/** + * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND + * resolution. + */ +typedef uint64_t coap_tick_t; + +/** + * CoAP time in seconds since epoch. + */ +typedef time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int64_t coap_tick_diff_t; + +/** Use ms resolution on POSIX systems */ +#define COAP_TICKS_PER_SECOND ((coap_tick_t)(1000U)) + +/** + * Initializes the internal clock. + */ +void coap_clock_init(void); + +/** + * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. + */ +void coap_ticks(coap_tick_t *t); + +/** + * Helper function that converts coap ticks to wallclock time. On POSIX, this + * function returns the number of seconds since the epoch. On other systems, it + * may be the calculated number of seconds since last reboot or so. + * + * @param t Internal system ticks. + * + * @return The number of seconds that has passed since a specific reference + * point (seconds since epoch on POSIX). + */ +coap_time_t coap_ticks_to_rt(coap_tick_t t); + +/** +* Helper function that converts coap ticks to POSIX wallclock time in us. +* +* @param t Internal system ticks. +* +* @return The number of seconds that has passed since a specific reference +* point (seconds since epoch on POSIX). +*/ +uint64_t coap_ticks_to_rt_us(coap_tick_t t); + +/** +* Helper function that converts POSIX wallclock time in us to coap ticks. +* +* @param t POSIX time is us +* +* @return coap ticks +*/ +coap_tick_t coap_ticks_from_rt_us(uint64_t t); +#endif + +/** + * Returns @c 1 if and only if @p a is less than @p b where less is defined on a + * signed data type. + */ +COAP_STATIC_INLINE int coap_time_lt(coap_tick_t a, coap_tick_t b) { + return ((coap_tick_diff_t)(a - b)) < 0; +} + +/** + * Returns @c 1 if and only if @p a is less than or equal @p b where less is + * defined on a signed data type. + */ +COAP_STATIC_INLINE int coap_time_le(coap_tick_t a, coap_tick_t b) { + return a == b || coap_time_lt(a,b); +} + +/** @} */ + +#endif /* COAP_TIME_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/encode.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/encode.h new file mode 100644 index 00000000000..b6d1524443c --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/encode.h @@ -0,0 +1,96 @@ +/* + * encode.h -- encoding and decoding of CoAP data types + * + * Copyright (C) 2010-2012 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_ENCODE_H_ +#define COAP_ENCODE_H_ + +#if (BSD >= 199103) || defined(WITH_CONTIKI) || defined(_WIN32) +# include +#else +# include +#endif + +#include + +#define Nn 8 /* duplicate definition of N if built on sky motes */ +#define ENCODE_HEADER_SIZE 4 +#define HIBIT (1 << (Nn - 1)) +#define EMASK ((1 << ENCODE_HEADER_SIZE) - 1) +#define MMASK ((1 << Nn) - 1 - EMASK) +#define MAX_VALUE ( (1 << Nn) - (1 << ENCODE_HEADER_SIZE) ) * (1 << ((1 << ENCODE_HEADER_SIZE) - 1)) + +#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK)) + +#ifndef HAVE_FLS +/* include this only if fls() is not available */ +extern int coap_fls(unsigned int i); +#else +#define coap_fls(i) fls(i) +#endif + +#ifndef HAVE_FLSLL + /* include this only if flsll() is not available */ +extern int coap_flsll(long long i); +#else +#define coap_flsll(i) flsll(i) +#endif + +/* ls and s must be integer variables */ +#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls) +#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls)) + +/** + * Decodes multiple-length byte sequences. @p buf points to an input byte + * sequence of length @p length. Returns the decoded value. + * + * @param buf The input byte sequence to decode from + * @param length The length of the input byte sequence + * + * @return The decoded value + */ +unsigned int coap_decode_var_bytes(const uint8_t *buf, unsigned int length); + +/** + * Encodes multiple-length byte sequences. @p buf points to an output buffer of + * sufficient length to store the encoded bytes. @p value is the value to + * encode. + * Returns the number of bytes used to encode @p value or 0 on error. + * + * @param buf The output buffer to decode into + * @param length The output buffer size to encode into (must be sufficient) + * @param value The value to encode into the buffer + * + * @return The number of bytes used to encode @p value or @c 0 on error. + */ +unsigned int coap_encode_var_safe(uint8_t *buf, + size_t length, + unsigned int value); + +/** + * @deprecated Use coap_encode_var_safe() instead. + * Provided for backward compatibility. As @p value has a + * maximum value of 0xffffffff, and buf is usually defined as an array, it + * is unsafe to continue to use this variant if buf[] is less than buf[4]. + * + * For example + * char buf[1],oops; + * .. + * coap_encode_var_bytes(buf, 0xfff); + * would cause oops to get overwritten. This error can only be found by code + * inspection. + * coap_encode_var_safe(buf, sizeof(buf), 0xfff); + * would catch this error at run-time and should be used instead. + */ +COAP_STATIC_INLINE COAP_DEPRECATED int +coap_encode_var_bytes(uint8_t *buf, unsigned int value +) { + return (int)coap_encode_var_safe(buf, sizeof(value), value); +} + +#endif /* COAP_ENCODE_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/libcoap.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/libcoap.h new file mode 100644 index 00000000000..77ba5db23e2 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/libcoap.h @@ -0,0 +1,54 @@ +/* + * libcoap.h -- platform specific header file for CoAP stack + * + * Copyright (C) 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_LIBCOAP_H_ +#define COAP_LIBCOAP_H_ + +/* The non posix embedded platforms like Contiki, TinyOS, RIOT, ... doesn't have + * a POSIX compatible header structure so we have to slightly do some platform + * related things. Currently there is only Contiki available so we check for a + * CONTIKI environment and do *not* include the POSIX related network stuff. If + * there are other platforms in future there need to be analogous environments. + * + * The CONTIKI variable is within the Contiki build environment! */ + +#if defined(_WIN32) +#pragma comment(lib,"Ws2_32.lib") +#include +typedef SSIZE_T ssize_t; +typedef USHORT in_port_t; +#elif !defined (CONTIKI) +#include +#include +#endif /* CONTIKI */ + +#ifndef COAP_STATIC_INLINE +# if defined(__cplusplus) +# define COAP_STATIC_INLINE inline +# else +# if defined(_MSC_VER) +# define COAP_STATIC_INLINE static __inline +# else +# define COAP_STATIC_INLINE static inline +# endif +# endif +#endif +#ifndef COAP_DEPRECATED +# if defined(_MSC_VER) +# define COAP_DEPRECATED __declspec(deprecated) +# else +# define COAP_DEPRECATED __attribute__ ((deprecated)) +# endif +#endif + +void coap_startup(void); + +void coap_cleanup(void); + +#endif /* COAP_LIBCOAP_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/lwippools.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/lwippools.h new file mode 100644 index 00000000000..cb90d8099db --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/lwippools.h @@ -0,0 +1,81 @@ +/* + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/* Memory pool definitions for the libcoap when used with lwIP (which has its + * own mechanism for quickly allocating chunks of data with known sizes). Has + * to be findable by lwIP (ie. an #include must either directly + * include this or include something more generic which includes this), and + * MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */ + +#include "coap_config.h" +#include +#include +#include + +#ifndef MEMP_NUM_COAPCONTEXT +#define MEMP_NUM_COAPCONTEXT 1 +#endif + +#ifndef MEMP_NUM_COAPENDPOINT +#define MEMP_NUM_COAPENDPOINT 1 +#endif + +/* 1 is sufficient as this is very short-lived */ +#ifndef MEMP_NUM_COAPPACKET +#define MEMP_NUM_COAPPACKET 1 +#endif + +#ifndef MEMP_NUM_COAPNODE +#define MEMP_NUM_COAPNODE 4 +#endif + +#ifndef MEMP_NUM_COAPPDU +#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE +#endif + +#ifndef MEMP_NUM_COAPSESSION +#define MEMP_NUM_COAPSESSION 2 +#endif + +#ifndef MEMP_NUM_COAP_SUBSCRIPTION +#define MEMP_NUM_COAP_SUBSCRIPTION 4 +#endif + +#ifndef MEMP_NUM_COAPRESOURCE +#define MEMP_NUM_COAPRESOURCE 10 +#endif + +#ifndef MEMP_NUM_COAPRESOURCEATTR +#define MEMP_NUM_COAPRESOURCEATTR 20 +#endif + +#ifndef MEMP_NUM_COAPOPTLIST +#define MEMP_NUM_COAPOPTLIST 1 +#endif + +#ifndef MEMP_LEN_COAPOPTLIST +#define MEMP_LEN_COAPOPTLIST 12 +#endif + +#ifndef MEMP_NUM_COAPSTRING +#define MEMP_NUM_COAPSTRING 10 +#endif + +#ifndef MEMP_LEN_COAPSTRING +#define MEMP_LEN_COAPSTRING 32 +#endif + +LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") +LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") +LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") +LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") +LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION") +LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") +LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") +LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") +LWIP_MEMPOOL(COAP_OPTLIST, MEMP_NUM_COAPOPTLIST, sizeof(coap_optlist_t)+MEMP_LEN_COAPOPTLIST, "COAP_OPTLIST") +LWIP_MEMPOOL(COAP_STRING, MEMP_NUM_COAPSTRING, sizeof(coap_string_t)+MEMP_LEN_COAPSTRING, "COAP_STRING") + diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/mem.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/mem.h new file mode 100644 index 00000000000..ea3c619fd30 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/mem.h @@ -0,0 +1,116 @@ +/* + * mem.h -- CoAP memory handling + * + * Copyright (C) 2010-2011,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_MEM_H_ +#define COAP_MEM_H_ + +#include + +#ifndef WITH_LWIP +/** + * Initializes libcoap's memory management. + * This function must be called once before coap_malloc() can be used on + * constrained devices. + */ +void coap_memory_init(void); +#endif /* WITH_LWIP */ + +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed to + * facilitate arrays of type objects to be used instead of dynamic memory + * management on constrained devices. + */ +typedef enum { + COAP_STRING, + COAP_ATTRIBUTE_NAME, + COAP_ATTRIBUTE_VALUE, + COAP_PACKET, + COAP_NODE, + COAP_CONTEXT, + COAP_ENDPOINT, + COAP_PDU, + COAP_PDU_BUF, + COAP_RESOURCE, + COAP_RESOURCEATTR, +#ifdef HAVE_LIBTINYDTLS + COAP_DTLS_SESSION, +#endif + COAP_SESSION, + COAP_OPTLIST, +} coap_memory_tag_t; + +#ifndef WITH_LWIP + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the newly + * allocated memory. The @p type is used to select the appropriate storage + * container on constrained devices. The storage allocated by coap_malloc_type() + * must be released with coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). The type tag @p + * type must be the same that was used for allocating the object pointed to by + * @p . + * + * @param type The type of the object to release. + * @param p A pointer to memory that was allocated by coap_malloc_type(). + */ +void coap_free_type(coap_memory_tag_t type, void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +COAP_STATIC_INLINE void coap_free(void *object) { + coap_free_type(COAP_STRING, object); +} + +#endif /* not WITH_LWIP */ + +#ifdef WITH_LWIP + +#include + +/* no initialization needed with lwip (or, more precisely: lwip must be + * completely initialized anyway by the time coap gets active) */ +COAP_STATIC_INLINE void coap_memory_init(void) {} + +/* It would be nice to check that size equals the size given at the memp + * declaration, but i currently don't see a standard way to check that without + * sourcing the custom memp pools and becoming dependent of its syntax + */ +#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_free_type(type, p) memp_free(MEMP_ ## type, p) + +/* Those are just here to make uri.c happy where string allocation has not been + * made conditional. + */ +COAP_STATIC_INLINE void *coap_malloc(size_t size) { + LWIP_ASSERT("coap_malloc must not be used in lwIP", 0); +} + +COAP_STATIC_INLINE void coap_free(void *pointer) { + LWIP_ASSERT("coap_free must not be used in lwIP", 0); +} + +#endif /* WITH_LWIP */ + +#endif /* COAP_MEM_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/net.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/net.h new file mode 100644 index 00000000000..7fccf3326c7 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/net.h @@ -0,0 +1,746 @@ +/* + * net.h -- CoAP network interface + * + * Copyright (C) 2010-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_NET_H_ +#define COAP_NET_H_ + +#include +#include +#include +#ifndef _WIN32 +#include +#endif +#include + +#ifdef WITH_LWIP +#include +#endif + +#include "coap_io.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_time.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "coap_session.h" + +struct coap_queue_t; + +/** + * Queue entry + */ +typedef struct coap_queue_t { + struct coap_queue_t *next; + coap_tick_t t; /**< when to send PDU for the next time */ + unsigned char retransmit_cnt; /**< retransmission counter, will be removed + * when zero */ + unsigned int timeout; /**< the randomized timeout value */ + coap_session_t *session; /**< the CoAP session */ + coap_tid_t id; /**< CoAP transaction id */ + coap_pdu_t *pdu; /**< the CoAP PDU to send */ +} coap_queue_t; + +/** + * Adds @p node to given @p queue, ordered by variable t in @p node. + * + * @param queue Queue to add to. + * @param node Node entry to add to Queue. + * + * @return @c 1 added to queue, @c 0 failure. + */ +int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); + +/** + * Destroys specified @p node. + * + * @param node Node entry to remove. + * + * @return @c 1 node deleted from queue, @c 0 failure. + */ +int coap_delete_node(coap_queue_t *node); + +/** + * Removes all items from given @p queue and frees the allocated storage. + * + * @param queue The queue to delete. + */ +void coap_delete_all(coap_queue_t *queue); + +/** + * Creates a new node suitable for adding to the CoAP sendqueue. + * + * @return New node entry, or @c NULL if failure. + */ +coap_queue_t *coap_new_node(void); + +struct coap_resource_t; +struct coap_context_t; +#ifndef WITHOUT_ASYNC +struct coap_async_state_t; +#endif + +/** + * Response handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_response_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Negative Acknowedge handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param sent The PDU that was transmitted. + * @param reason The reason for the NACK. + * @param id CoAP transaction ID. + */ +typedef void (*coap_nack_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *sent, + coap_nack_reason_t reason, + const coap_tid_t id); + +/** + * Recieved Ping handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_ping_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * Recieved Pong handler that is used as call-back in coap_context_t. + * + * @param context CoAP session. + * @param session CoAP session. + * @param received The PDU that was received. + * @param id CoAP transaction ID. + */ +typedef void (*coap_pong_handler_t)(struct coap_context_t *context, + coap_session_t *session, + coap_pdu_t *received, + const coap_tid_t id); + +/** + * The CoAP stack's global state is stored in a coap_context_t object. + */ +typedef struct coap_context_t { + coap_opt_filter_t known_options; + struct coap_resource_t *resources; /**< hash table or list of known + resources */ + struct coap_resource_t *unknown_resource; /**< can be used for handling + unknown resources */ + +#ifndef WITHOUT_ASYNC + /** + * list of asynchronous transactions */ + struct coap_async_state_t *async_state; +#endif /* WITHOUT_ASYNC */ + + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue; + coap_endpoint_t *endpoint; /**< the endpoints used for listening */ + coap_session_t *sessions; /**< client sessions */ + +#ifdef WITH_CONTIKI + struct uip_udp_conn *conn; /**< uIP connection object */ + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ + struct etimer notify_timer; /**< used to check resources periodically */ +#endif /* WITH_CONTIKI */ + +#ifdef WITH_LWIP + uint8_t timer_configured; /**< Set to 1 when a retransmission is + * scheduled using lwIP timers for this + * context, otherwise 0. */ +#endif /* WITH_LWIP */ + + coap_response_handler_t response_handler; + coap_nack_handler_t nack_handler; + coap_ping_handler_t ping_handler; + coap_pong_handler_t pong_handler; + + /** + * Callback function that is used to signal events to the + * application. This field is set by coap_set_event_handler(). + */ + coap_event_handler_t handle_event; + + ssize_t (*network_send)(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen); + + ssize_t (*network_read)(coap_socket_t *sock, struct coap_packet_t *packet); + + size_t(*get_client_psk)(const coap_session_t *session, const uint8_t *hint, size_t hint_len, uint8_t *identity, size_t *identity_len, size_t max_identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_psk)(const coap_session_t *session, const uint8_t *identity, size_t identity_len, uint8_t *psk, size_t max_psk_len); + size_t(*get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len); + + void *dtls_context; + uint8_t *psk_hint; + size_t psk_hint_len; + uint8_t *psk_key; + size_t psk_key_len; + + unsigned int session_timeout; /**< Number of seconds of inactivity after which an unused session will be closed. 0 means use default. */ + unsigned int max_idle_sessions; /**< Maximum number of simultaneous unused sessions per endpoint. 0 means no maximum. */ + unsigned int max_handshake_sessions; /**< Maximum number of simultaneous negotating sessions per endpoint. 0 means use default. */ + unsigned int ping_timeout; /**< Minimum inactivity time before sending a ping message. 0 means disabled. */ + unsigned int csm_timeout; /**< Timeout for waiting for a CSM from the remote side. 0 means disabled. */ + + void *app; /**< application-specific data */ +} coap_context_t; + +/** + * Registers a new message handler that is called whenever a response was + * received that matches an ongoing transaction. + * + * @param context The context to register the handler for. + * @param handler The response handler to register. + */ +COAP_STATIC_INLINE void +coap_register_response_handler(coap_context_t *context, + coap_response_handler_t handler) { + context->response_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a confirmable + * message (request or response) is dropped after all retries have been + * exhausted, or a rst message was received, or a network or TLS level + * event was received that indicates delivering the message is not possible. + * + * @param context The context to register the handler for. + * @param handler The nack handler to register. + */ +COAP_STATIC_INLINE void +coap_register_nack_handler(coap_context_t *context, + coap_nack_handler_t handler) { + context->nack_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Ping + * message is received. + * + * @param context The context to register the handler for. + * @param handler The ping handler to register. + */ +COAP_STATIC_INLINE void +coap_register_ping_handler(coap_context_t *context, + coap_ping_handler_t handler) { + context->ping_handler = handler; +} + +/** + * Registers a new message handler that is called whenever a CoAP Pong + * message is received. + * + * @param context The context to register the handler for. + * @param handler The pong handler to register. + */ +COAP_STATIC_INLINE void +coap_register_pong_handler(coap_context_t *context, + coap_pong_handler_t handler) { + context->pong_handler = handler; +} + +/** + * Registers the option type @p type with the given context object @p ctx. + * + * @param ctx The context to use. + * @param type The option type to register. + */ +COAP_STATIC_INLINE void +coap_register_option(coap_context_t *ctx, uint16_t type) { + coap_option_setb(ctx->known_options, type); +} + +/** + * Set sendqueue_basetime in the given context object @p ctx to @p now. This + * function returns the number of elements in the queue head that have timed + * out. + */ +unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); + +/** + * Returns the next pdu to send without removing from sendqeue. + */ +coap_queue_t *coap_peek_next( coap_context_t *context ); + +/** + * Returns the next pdu to send and removes it from the sendqeue. + */ +coap_queue_t *coap_pop_next( coap_context_t *context ); + +/** + * Creates a new coap_context_t object that will hold the CoAP stack status. + */ +coap_context_t *coap_new_context(const coap_address_t *listen_addr); + +/** + * Set the context's default PSK hint and/or key for a server. + * + * @param context The current coap_context_t object. + * @param hint The default PSK server hint sent to a client. If @p NULL, PSK + * authentication is disabled. Empty string is a valid hint. + * @param key The default PSK key. If @p NULL, PSK authentication will fail. + * @param key_len The default PSK key's length. If @p 0, PSK authentication will + * fail. + * + * @return @c 1 if successful, else @c 0. + */ +int coap_context_set_psk( coap_context_t *context, const char *hint, + const uint8_t *key, size_t key_len ); + +/** + * Set the context's default PKI information for a server. + * + * @param context The current coap_context_t object. + * @param setup_data If @p NULL, PKI authentication will fail. Certificate + * information required. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki(coap_context_t *context, + coap_dtls_pki_t *setup_data); + +/** + * Set the context's default Root CA information for a client or server. + * + * @param context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ +int +coap_context_set_pki_root_cas(coap_context_t *context, + const char *ca_file, + const char *ca_dir); + +/** + * Set the context keepalive timer for sessions. + * A keepalive message will be sent after if a session has been inactive, + * i.e. no packet sent or received, for the given number of seconds. + * For reliable protocols, a PING message will be sent. If a PONG has not + * been received before the next PING is due to be sent, the session will + * considered as disconnected. + * + * @param context The coap_context_t object. + * @param seconds Number of seconds for the inactivity timer, or zero + * to disable CoAP-level keepalive messages. + * + * @return 1 if successful, else 0 + */ +void coap_context_set_keepalive(coap_context_t *context, unsigned int seconds); + +/** + * Returns a new message id and updates @p session->tx_mid accordingly. The + * message id is returned in network byte order to make it easier to read in + * tracing tools. + * + * @param session The current coap_session_t object. + * + * @return Incremented message id in network byte order. + */ +COAP_STATIC_INLINE uint16_t +coap_new_message_id(coap_session_t *session) { + return ++session->tx_mid; +} + +/** + * CoAP stack context must be released with coap_free_context(). This function + * clears all entries from the receive queue and send queue and deletes the + * resources that have been registered with @p context, and frees the attached + * endpoints. + * + * @param context The current coap_context_t object to free off. + */ +void coap_free_context(coap_context_t *context); + +/** + * Stores @p data with the given CoAP context. This function + * overwrites any value that has previously been stored with @p + * context. + * + * @param context The CoAP context. + * @param data The data to store with wih the context. Note that this data + * must be valid during the lifetime of @p context. + */ +void coap_set_app_data(coap_context_t *context, void *data); + +/** + * Returns any application-specific data that has been stored with @p + * context using the function coap_set_app_data(). This function will + * return @c NULL if no data has been stored. + * + * @param context The CoAP context. + * + * @return The data previously stored or @c NULL if not data stored. + */ +void *coap_get_app_data(const coap_context_t *context); + +/** + * Creates a new ACK PDU with specified error @p code. The options specified by + * the filter expression @p opts will be copied from the original request + * contained in @p request. Unless @c SHORT_ERROR_RESPONSE was defined at build + * time, the textual reason phrase for @p code will be added as payload, with + * Content-Type @c 0. + * This function returns a pointer to the new response message, or @c NULL on + * error. The storage allocated for the new message must be relased with + * coap_free(). + * + * @param request Specification of the received (confirmable) request. + * @param code The error code to set. + * @param opts An option filter that specifies which options to copy from + * the original request in @p node. + * + * @return A pointer to the new message or @c NULL on error. + */ +coap_pdu_t *coap_new_error_response(coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Sends an error response with code @p code for request @p request to @p dst. + * @p opts will be passed to coap_new_error_response() to copy marked options + * from the request. This function returns the transaction id if the message was + * sent, or @c COAP_INVALID_TID otherwise. + * + * @param session The CoAP session. + * @param request The original request to respond to. + * @param code The response code. + * @param opts A filter that specifies the options to copy from the + * @p request. + * + * @return The transaction id if the message was sent, or @c + * COAP_INVALID_TID otherwise. + */ +coap_tid_t coap_send_error(coap_session_t *session, + coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Helper funktion to create and send a message with @p type (usually ACK or + * RST). This function returns @c COAP_INVALID_TID when the message was not + * sent, a valid transaction id otherwise. + * + * @param session The CoAP session. + * @param request The request that should be responded to. + * @param type Which type to set. + * @return transaction id on success or @c COAP_INVALID_TID + * otherwise. + */ +coap_tid_t +coap_send_message_type(coap_session_t *session, coap_pdu_t *request, unsigned char type); + +/** + * Sends an ACK message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be acknowledged. + * + * @return The transaction id if ACK was sent or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_ack(coap_session_t *session, coap_pdu_t *request); + +/** + * Sends an RST message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param session The CoAP session. + * @param request The request to be reset. + * + * @return The transaction id if RST was sent or @c + * COAP_INVALID_TID on error. + */ +COAP_STATIC_INLINE coap_tid_t +coap_send_rst(coap_session_t *session, coap_pdu_t *request) { + return coap_send_message_type(session, request, COAP_MESSAGE_RST); +} + +/** +* Sends a CoAP message to given peer. The memory that is +* allocated by pdu will be released by coap_send(). +* The caller must not use the pdu after calling coap_send(). +* +* @param session The CoAP session. +* @param pdu The CoAP PDU to send. +* +* @return The message id of the sent message or @c +* COAP_INVALID_TID on error. +*/ +coap_tid_t coap_send( coap_session_t *session, coap_pdu_t *pdu ); + +/** + * Handles retransmissions of confirmable messages + * + * @param context The CoAP context. + * @param node The node to retransmit. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); + +/** +* For applications with their own message loop, send all pending retransmits and +* return the list of sockets with events to wait for and the next timeout +* The application should call coap_read, then coap_write again when any condition below is true: +* - data is available on any of the sockets with the COAP_SOCKET_WANT_READ +* - an incoming connection is pending in the listen queue and the COAP_SOCKET_WANT_ACCEPT flag is set +* - at least some data can be written without blocking on any of the sockets with the COAP_SOCKET_WANT_WRITE flag set +* - a connection event occured (success or failure) and the COAP_SOCKET_WANT_CONNECT flag is set +* - the timeout has expired +* Before calling coap_read or coap_write again, the application should position COAP_SOCKET_CAN_READ and COAP_SOCKET_CAN_WRITE flags as applicable. +* +* @param ctx The CoAP context +* @param sockets array of socket descriptors, filled on output +* @param max_sockets size of socket array. +* @param num_sockets pointer to the number of valid entries in the socket arrays on output +* @param now Current time. +* +* @return timeout as maxmimum number of milliseconds that the application should wait for network events or 0 if the application should wait forever. +*/ + +unsigned int +coap_write(coap_context_t *ctx, + coap_socket_t *sockets[], + unsigned int max_sockets, + unsigned int *num_sockets, + coap_tick_t now +); + +/** + * For applications with their own message loop, reads all data from the network. + * + * @param ctx The CoAP context + * @param now Current time + */ +void coap_read(coap_context_t *ctx, coap_tick_t now); + +/** + * The main message processing loop. + * + * @param ctx The CoAP context + * @param timeout_ms Minimum number of milliseconds to wait for new messages before returning. If zero the call will block until at least one packet is sent or received. + * + * @return number of milliseconds spent or @c -1 if there was an error + */ + +int coap_run_once( coap_context_t *ctx, unsigned int timeout_ms ); + +/** + * Parses and interprets a CoAP datagram with context @p ctx. This function + * returns @c 0 if the datagram was handled, or a value less than zero on + * error. + * + * @param ctx The current CoAP context. + * @param session The current CoAP session. + * @param data The received packet'd data. + * @param data_len The received packet'd data length. + * + * @return @c 0 if message was handled successfully, or less than zero on + * error. + */ +int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *data, size_t data_len); + +/** + * Invokes the event handler of @p context for the given @p event and + * @p data. + * + * @param context The CoAP context whose event handler is to be called. + * @param event The event to deliver. + * @param session The session related to @p event. + * @return The result from the associated event handler or 0 if none was + * registered. + */ +int coap_handle_event(coap_context_t *context, + coap_event_t event, + coap_session_t *session); +/** + * This function removes the element with given @p id from the list given list. + * If @p id was found, @p node is updated to point to the removed element. Note + * that the storage allocated by @p node is @b not released. The caller must do + * this manually using coap_delete_node(). This function returns @c 1 if the + * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, + * the contents of @p node is undefined. + * + * @param queue The queue to search for @p id. + * @param session The session to look for. + * @param id The transaction id to look for. + * @param node If found, @p node is updated to point to the removed node. You + * must release the storage pointed to by @p node manually. + * + * @return @c 1 if @p id was found, @c 0 otherwise. + */ +int coap_remove_from_queue(coap_queue_t **queue, + coap_session_t *session, + coap_tid_t id, + coap_queue_t **node); + +coap_tid_t +coap_wait_ack( coap_context_t *context, coap_session_t *session, + coap_queue_t *node); + +/** + * Retrieves transaction from the queue. + * + * @param queue The transaction queue to be searched. + * @param session The session to find. + * @param id The transaction id to find. + * + * @return A pointer to the transaction object or @c NULL if not found. + */ +coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_session_t *session, coap_tid_t id); + +/** + * Cancels all outstanding messages for session @p session that have the specified + * token. + * + * @param context The context in use. + * @param session Session of the messages to remove. + * @param token Message token. + * @param token_length Actual length of @p token. + */ +void coap_cancel_all_messages(coap_context_t *context, + coap_session_t *session, + const uint8_t *token, + size_t token_length); + +/** +* Cancels all outstanding messages for session @p session. +* +* @param context The context in use. +* @param session Session of the messages to remove. +* @param reason The reasion for the session cancellation +*/ +void +coap_cancel_session_messages(coap_context_t *context, + coap_session_t *session, + coap_nack_reason_t reason); + +/** + * Dispatches the PDUs from the receive queue in given context. + */ +void coap_dispatch(coap_context_t *context, coap_session_t *session, + coap_pdu_t *pdu); + +/** + * Returns 1 if there are no messages to send or to dispatch in the context's + * queues. */ +int coap_can_exit(coap_context_t *context); + +/** + * Returns the current value of an internal tick counter. The counter counts \c + * COAP_TICKS_PER_SECOND ticks every second. + */ +void coap_ticks(coap_tick_t *); + +/** + * Verifies that @p pdu contains no unknown critical options. Options must be + * registered at @p ctx, using the function coap_register_option(). A basic set + * of options is registered automatically by coap_new_context(). This function + * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p + * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT + * options can be signalled this way, remaining options must be examined + * manually. + * + * @code + coap_opt_filter_t f = COAP_OPT_NONE; + coap_opt_iterator_t opt_iter; + + if (coap_option_check_critical(ctx, pdu, f) == 0) { + coap_option_iterator_init(pdu, &opt_iter, f); + + while (coap_option_next(&opt_iter)) { + if (opt_iter.type & 0x01) { + ... handle unknown critical option in opt_iter ... + } + } + } + @endcode + * + * @param ctx The context where all known options are registered. + * @param pdu The PDU to check. + * @param unknown The output filter that will be updated to indicate the + * unknown critical options found in @p pdu. + * + * @return @c 1 if everything was ok, @c 0 otherwise. + */ +int coap_option_check_critical(coap_context_t *ctx, + coap_pdu_t *pdu, + coap_opt_filter_t unknown); + +/** + * Creates a new response for given @p request with the contents of @c + * .well-known/core. The result is NULL on error or a newly allocated PDU that + * must be either sent with coap_sent() or released by coap_delete_pdu(). + * + * @param context The current coap context to use. + * @param session The CoAP session. + * @param request The request for @c .well-known/core . + * + * @return A new 2.05 response for @c .well-known/core or NULL on error. + */ +coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_session_t *session, + coap_pdu_t *request); + +/** + * Calculates the initial timeout based on the session CoAP transmission + * parameters 'ack_timeout', 'ack_random_factor', and COAP_TICKS_PER_SECOND. + * The calculation requires 'ack_timeout' and 'ack_random_factor' to be in + * Qx.FRAC_BITS fixed point notation, whereas the passed parameter @p r + * is interpreted as the fractional part of a Q0.MAX_BITS random value. + * + * @param session session timeout is associated with + * @param r random value as fractional part of a Q0.MAX_BITS fixed point + * value + * @return COAP_TICKS_PER_SECOND * 'ack_timeout' * + * (1 + ('ack_random_factor' - 1) * r) + */ +unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r); + +/** + * Function interface for joining a multicast group for listening + * + * @param ctx The current context + * @param groupname The name of the group that is to be joined for listening + * + * @return 0 on success, -1 on error + */ +int +coap_join_mcast_group(coap_context_t *ctx, const char *groupname); + +#endif /* COAP_NET_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/option.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/option.h new file mode 100644 index 00000000000..3af9e71e706 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/option.h @@ -0,0 +1,461 @@ +/* + * option.h -- helpers for handling options in CoAP PDUs + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file option.h + * @brief Helpers for handling options in CoAP PDUs + */ + +#ifndef COAP_OPTION_H_ +#define COAP_OPTION_H_ + +#include "bits.h" +#include "pdu.h" + +/** + * Use byte-oriented access methods here because sliding a complex struct + * coap_opt_t over the data buffer may cause bus error on certain platforms. + */ +typedef uint8_t coap_opt_t; +#define PCHAR(p) ((coap_opt_t *)(p)) + +/** + * Representation of CoAP options. + */ +typedef struct { + uint16_t delta; + size_t length; + const uint8_t *value; +} coap_option_t; + +/** + * Parses the option pointed to by @p opt into @p result. This function returns + * the number of bytes that have been parsed, or @c 0 on error. An error is + * signaled when illegal delta or length values are encountered or when option + * parsing would result in reading past the option (i.e. beyond opt + length). + * + * @param opt The beginning of the option to parse. + * @param length The maximum length of @p opt. + * @param result A pointer to the coap_option_t structure that is filled with + * actual values iff coap_opt_parse() > 0. + * @return The number of bytes parsed or @c 0 on error. + */ +size_t coap_opt_parse(const coap_opt_t *opt, + size_t length, + coap_option_t *result); + +/** + * Returns the size of the given option, taking into account a possible option + * jump. + * + * @param opt An option jump or the beginning of the option. + * @return The number of bytes between @p opt and the end of the option + * starting at @p opt. In case of an error, this function returns + * @c 0 as options need at least one byte storage space. + */ +size_t coap_opt_size(const coap_opt_t *opt); + +/** + * @defgroup opt_filter Option Filters + * API functions for access option filters + * @{ + */ + +/** + * The number of option types below 256 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_SHORT 6 + +/** + * The number of option types above 255 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * COAP_OPT_FILTER_LONG * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_LONG 2 + +/* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set + * correctly. */ +#if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) +#error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16 +#endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */ + +/** The number of elements in coap_opt_filter_t. */ +#define COAP_OPT_FILTER_SIZE \ + (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1 + +/** + * Fixed-size vector we use for option filtering. It is large enough + * to hold COAP_OPT_FILTER_SHORT entries with an option number between + * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number + * between 256 and 65535. Its internal structure is + * + * @code +struct { + uint16_t mask; + uint16_t long_opts[COAP_OPT_FILTER_LONG]; + uint8_t short_opts[COAP_OPT_FILTER_SHORT]; +} + * @endcode + * + * The first element contains a bit vector that indicates which fields + * in the remaining array are used. The first COAP_OPT_FILTER_LONG + * bits correspond to the long option types that are stored in the + * elements from index 1 to COAP_OPT_FILTER_LONG. The next + * COAP_OPT_FILTER_SHORT bits correspond to the short option types + * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1 + * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter + * elements are treated as bytes. + */ +typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE]; + +/** Pre-defined filter that includes all options. */ +#define COAP_OPT_ALL NULL + +/** + * Clears filter @p f. + * + * @param f The filter to clear. + */ +COAP_STATIC_INLINE void +coap_option_filter_clear(coap_opt_filter_t f) { + memset(f, 0, sizeof(coap_opt_filter_t)); +} + +/** + * Sets the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_set(coap_opt_filter_t filter, uint16_t type); + +/** + * Clears the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type that should be cleared from the filter. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_unset(coap_opt_filter_t filter, uint16_t type); + +/** + * Checks if @p type is contained in @p filter. This function returns + * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given + * type does not fit in the filter). + * + * @param filter The filter object to search. + * @param type The type to search for. + * + * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error. + */ +int coap_option_filter_get(coap_opt_filter_t filter, uint16_t type); + +/** + * Sets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in + * the filter). + * + * @deprecated Use coap_option_filter_set() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_setb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_set(filter, type) ? 1 : -1; +} + +/** + * Clears the corresponding bit for @p type in @p filter. This function returns + * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not + * fit in the filter). + * + * @deprecated Use coap_option_filter_unset() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be cleared. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +COAP_STATIC_INLINE int +coap_option_clrb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_unset(filter, type) ? 1 : -1; +} + +/** + * Gets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type + * does not fit in the filter). + * + * @deprecated Use coap_option_filter_get() instead. + * + * @param filter The filter object to read bit from. + * @param type The type for which the bit should be read. + * + * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. + */ +COAP_STATIC_INLINE int +coap_option_getb(coap_opt_filter_t filter, uint16_t type) { + return coap_option_filter_get(filter, type); +} + +/** + * Iterator to run through PDU options. This object must be + * initialized with coap_option_iterator_init(). Call + * coap_option_next() to walk through the list of options until + * coap_option_next() returns @c NULL. + * + * @code + * coap_opt_t *option; + * coap_opt_iterator_t opt_iter; + * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + * + * while ((option = coap_option_next(&opt_iter))) { + * ... do something with option ... + * } + * @endcode + */ +typedef struct { + size_t length; /**< remaining length of PDU */ + uint16_t type; /**< decoded option type */ + unsigned int bad:1; /**< iterator object is ok if not set */ + unsigned int filtered:1; /**< denotes whether or not filter is used */ + coap_opt_t *next_option; /**< pointer to the unparsed next option */ + coap_opt_filter_t filter; /**< option filter */ +} coap_opt_iterator_t; + +/** + * Initializes the given option iterator @p oi to point to the beginning of the + * @p pdu's option list. This function returns @p oi on success, @c NULL + * otherwise (i.e. when no options exist). Note that a length check on the + * option list must be performed before coap_option_iterator_init() is called. + * + * @param pdu The PDU the options of which should be walked through. + * @param oi An iterator object that will be initilized. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. + * Fence-post options @c 14, @c 28, @c 42, ... are always + * skipped. + * + * @return The iterator object @p oi on success, @c NULL otherwise. + */ +coap_opt_iterator_t *coap_option_iterator_init(const coap_pdu_t *pdu, + coap_opt_iterator_t *oi, + const coap_opt_filter_t filter); + +/** + * Updates the iterator @p oi to point to the next option. This function returns + * a pointer to that option or @c NULL if no more options exist. The contents of + * @p oi will be updated. In particular, @c oi->n specifies the current option's + * ordinal number (counted from @c 1), @c oi->type is the option's type code, + * and @c oi->option points to the beginning of the current option itself. When + * advanced past the last option, @c oi->option will be @c NULL. + * + * Note that options are skipped whose corresponding bits in the filter + * specified with coap_option_iterator_init() are @c 0. Options with type codes + * that do not fit in this filter hence will always be returned. + * + * @param oi The option iterator to update. + * + * @return The next option or @c NULL if no more options exist. + */ +coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); + +/** + * Retrieves the first option of type @p type from @p pdu. @p oi must point to a + * coap_opt_iterator_t object that will be initialized by this function to + * filter only options with code @p type. This function returns the first option + * with this type, or @c NULL if not found. + * + * @param pdu The PDU to parse for options. + * @param type The option type code to search for. + * @param oi An iterator object to use. + * + * @return A pointer to the first option of type @p type, or @c NULL if + * not found. + */ +coap_opt_t *coap_check_option(coap_pdu_t *pdu, + uint16_t type, + coap_opt_iterator_t *oi); + +/** + * Encodes the given delta and length values into @p opt. This function returns + * the number of bytes that were required to encode @p delta and @p length or @c + * 0 on error. Note that the result indicates by how many bytes @p opt must be + * advanced to encode the option value. + * + * @param opt The option buffer space where @p delta and @p length are + * written. + * @param maxlen The maximum length of @p opt. + * @param delta The actual delta value to encode. + * @param length The actual length value to encode. + * + * @return The number of bytes used or @c 0 on error. + */ +size_t coap_opt_setheader(coap_opt_t *opt, + size_t maxlen, + uint16_t delta, + size_t length); + +/** + * Compute storage bytes needed for an option with given @p delta and + * @p length + * + * @param delta The option delta. + * @param length The option length. + * + * @return The number of bytes required to encode this option. + */ +size_t coap_opt_encode_size(uint16_t delta, size_t length); + +/** + * Encodes option with given @p delta into @p opt. This function returns the + * number of bytes written to @p opt or @c 0 on error. This happens especially + * when @p opt does not provide sufficient space to store the option value, + * delta, and option jumps when required. + * + * @param opt The option buffer space where @p val is written. + * @param n Maximum length of @p opt. + * @param delta The option delta. + * @param val The option value to copy into @p opt. + * @param length The actual length of @p val. + * + * @return The number of bytes that have been written to @p opt or @c 0 on + * error. The return value will always be less than @p n. + */ +size_t coap_opt_encode(coap_opt_t *opt, + size_t n, + uint16_t delta, + const uint8_t *val, + size_t length); + +/** + * Decodes the delta value of the next option. This function returns the number + * of bytes read or @c 0 on error. The caller of this function must ensure that + * it does not read over the boundaries of @p opt (e.g. by calling + * coap_opt_check_delta(). + * + * @param opt The option to examine. + * + * @return The number of bytes read or @c 0 on error. + */ +uint16_t coap_opt_delta(const coap_opt_t *opt); + +/** + * Returns the length of the given option. @p opt must point to an option jump + * or the beginning of the option. This function returns @c 0 when @p opt is not + * an option or the actual length of @p opt (which can be @c 0 as well). + * + * @note {The rationale for using @c 0 in case of an error is that in most + * contexts, the result of this function is used to skip the next + * coap_opt_length() bytes.} + * + * @param opt The option whose length should be returned. + * + * @return The option's length or @c 0 when undefined. + */ +uint16_t coap_opt_length(const coap_opt_t *opt); + +/** + * Returns a pointer to the value of the given option. @p opt must point to an + * option jump or the beginning of the option. This function returns @c NULL if + * @p opt is not a valid option. + * + * @param opt The option whose value should be returned. + * + * @return A pointer to the option value or @c NULL on error. + */ +const uint8_t *coap_opt_value(const coap_opt_t *opt); + +/** @} */ + +/** + * Representation of chained list of CoAP options to install. + * + * @code + * coap_optlist_t *optlist_chain = NULL; + * coap_pdu_t *pdu = coap_new_pdu(session); + * + * ... other set up code ... + * coap_insert_optlist(&optlist_chain, coap_new_optlist(COAP_OPTION_OBSERVE, + * COAP_OBSERVE_ESTABLISH, NULL)); + * + * coap_add_optlist_pdu(pdu, &optlist_chain); + * ... other code ... + * coap_delete_optlist(optlist_chain); + * @endcode + */ +typedef struct coap_optlist_t { + struct coap_optlist_t *next; /**< next entry in the optlist chain */ + uint16_t number; /**< the option number (no delta coding) */ + size_t length; /**< the option value length */ + uint8_t *data; /**< the option data */ +} coap_optlist_t; + +/** + * Create a new optlist entry. + * + * @param number The option number (COAP_OPTION_*) + * @param length The option length + * @param data The option value data + * + * @return A pointer to the new optlist entry, or @c NULL if error + */ +coap_optlist_t *coap_new_optlist(uint16_t number, + size_t length, + const uint8_t *data); + +/** + * The current optlist of @p optlist_chain is first sorted (as per RFC7272 + * ordering requirements) and then added to the @p pdu. + * + * @param pdu The pdu to add the options to from the chain list + * @param optlist_chain The chained list of optlist to add to the pdu + * + * @return @c 1 if succesful or @c 0 if failure; + */ +int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t** optlist_chain); + +/** + * Adds @p optlist to the given @p optlist_chain. The optlist_chain variable + * be set to NULL before the initial call to coap_insert_optlist(). + * The optlist_chain will need to be deleted using coap_delete_optlist() + * when no longer required. + * + * @param optlist_chain The chain to add optlist to + * @param optlist The optlist to add to the queue + * + * @return @c 1 if successful, @c 0 otherwise. + */ +int coap_insert_optlist(coap_optlist_t **optlist_chain, + coap_optlist_t *optlist); + +/** + * Removes all entries from the @p optlist_chain, freeing off their + * memory usage. + * + * @param optlist_chain The optlist chain to remove all the entries from + */ +void coap_delete_optlist(coap_optlist_t *optlist_chain); + +#endif /* COAP_OPTION_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/pdu.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/pdu.h new file mode 100644 index 00000000000..206e2643543 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/pdu.h @@ -0,0 +1,543 @@ +/* + * pdu.h -- CoAP message structure + * + * Copyright (C) 2010-2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file pdu.h + * @brief Pre-defined constants that reflect defaults for CoAP + */ + +#ifndef COAP_PDU_H_ +#define COAP_PDU_H_ + +#include "uri.h" + +struct coap_session_t; + +#ifdef WITH_LWIP +#include +#endif + +#include + +#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP/TCP port */ +#define COAPS_DEFAULT_PORT 5684 /* CoAP default UDP/TCP port for secure transmission */ +#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ +#ifndef COAP_DEFAULT_MTU +#define COAP_DEFAULT_MTU 1152 +#endif /* COAP_DEFAULT_MTU */ + +/* TCP Message format constants, do not modify */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP8 13 +#define COAP_MESSAGE_SIZE_OFFSET_TCP16 269 /* 13 + 256 */ +#define COAP_MESSAGE_SIZE_OFFSET_TCP32 65805 /* 269 + 65536 */ + +/* Derived message size limits */ +#define COAP_MAX_MESSAGE_SIZE_TCP0 (COAP_MESSAGE_SIZE_OFFSET_TCP8-1) /* 12 */ +#define COAP_MAX_MESSAGE_SIZE_TCP8 (COAP_MESSAGE_SIZE_OFFSET_TCP16-1) /* 268 */ +#define COAP_MAX_MESSAGE_SIZE_TCP16 (COAP_MESSAGE_SIZE_OFFSET_TCP32-1) /* 65804 */ +#define COAP_MAX_MESSAGE_SIZE_TCP32 (COAP_MESSAGE_SIZE_OFFSET_TCP32+0xFFFFFFFF) + +#ifndef COAP_DEFAULT_MAX_PDU_RX_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4) +#else +/* 8 MiB max-message-size plus some space for options */ +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (8*1024*1024+256) +#endif +#endif /* COAP_DEFAULT_MAX_PDU_RX_SIZE */ + +#ifndef COAP_DEBUG_BUF_SIZE +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) +#define COAP_DEBUG_BUF_SIZE 128 +#else /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +/* 1024 derived from RFC7252 4.6. Message Size max payload */ +#define COAP_DEBUG_BUF_SIZE (8 + 1024 * 2) +#endif /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ +#endif /* COAP_DEBUG_BUF_SIZE */ + +#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ +#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ + +/** well-known resources URI */ +#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" + +/* CoAP message types */ + +#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */ +#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */ +#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */ +#define COAP_MESSAGE_RST 3 /* indicates error in received messages */ + +/* CoAP request methods */ + +#define COAP_REQUEST_GET 1 +#define COAP_REQUEST_POST 2 +#define COAP_REQUEST_PUT 3 +#define COAP_REQUEST_DELETE 4 +#define COAP_REQUEST_FETCH 5 /* RFC 8132 */ +#define COAP_REQUEST_PATCH 6 /* RFC 8132 */ +#define COAP_REQUEST_IPATCH 7 /* RFC 8132 */ + +/* + * CoAP option types (be sure to update coap_option_check_critical() when + * adding options + */ + +#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */ +#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */ +#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */ +#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */ +#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */ +#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */ +#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */ +#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ +#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */ +#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */ +#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */ +#define COAP_OPTION_SIZE2 28 /* E, uint, 0-4 B, (none) */ +#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */ +#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */ + +/* option types from RFC 7641 */ + +#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */ +#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE + +/* selected option types from RFC 7959 */ + +#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */ +#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */ + +/* selected option types from RFC 7967 */ + +#define COAP_OPTION_NORESPONSE 258 /* N, uint, 0--1 B, 0 */ + +#define COAP_MAX_OPT 65535 /**< the highest option number we know */ + +/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */ + +/* As of draft-ietf-core-coap-04, response codes are encoded to base + * 32, i.e. the three upper bits determine the response class while + * the remaining five fine-grained information specific to that class. + */ +#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100) + +/* Determines the class of response code C */ +#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) + +#ifndef SHORT_ERROR_RESPONSE +/** + * Returns a human-readable response phrase for the specified CoAP response @p + * code. This function returns @c NULL if not found. + * + * @param code The response code for which the literal phrase should be + * retrieved. + * + * @return A zero-terminated string describing the error, or @c NULL if not + * found. + */ +const char *coap_response_phrase(unsigned char code); + +#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */ + +#else +#define coap_response_phrase(x) ((char *)NULL) + +#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */ +#endif /* SHORT_ERROR_RESPONSE */ + +/* The following definitions exist for backwards compatibility */ +#if 0 /* this does not exist any more */ +#define COAP_RESPONSE_100 40 /* 100 Continue */ +#endif +#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */ +#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */ +#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */ +#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */ +#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */ +#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */ +#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */ +#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */ +#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */ +#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */ +#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */ +#if 0 /* these response codes do not have a valid code any more */ +# define COAP_RESPONSE_X_240 240 /* Token Option required by server */ +# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */ +#endif +#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */ + +#define COAP_SIGNALING_CODE(N) (((N)/100 << 5) | (N)%100) +#define COAP_SIGNALING_CSM COAP_SIGNALING_CODE(701) +#define COAP_SIGNALING_PING COAP_SIGNALING_CODE(702) +#define COAP_SIGNALING_PONG COAP_SIGNALING_CODE(703) +#define COAP_SIGNALING_RELEASE COAP_SIGNALING_CODE(704) +#define COAP_SIGNALING_ABORT COAP_SIGNALING_CODE(705) + +/* Applies to COAP_SIGNALING_CSM */ +#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE 2 +#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER 4 +/* Applies to COAP_SIGNALING_PING / COAP_SIGNALING_PONG */ +#define COAP_SIGNALING_OPTION_CUSTODY 2 +/* Applies to COAP_SIGNALING_RELEASE */ +#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS 2 +#define COAP_SIGNALING_OPTION_HOLD_OFF 4 +/* Applies to COAP_SIGNALING_ABORT */ +#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION 2 + +/* CoAP media type encoding */ + +#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */ +#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */ +#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */ +#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */ +#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */ +#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */ +#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */ +#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */ + +/* Content formats from RFC 8152 */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN 98 /* application/cose; cose-type="cose-sign" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1 18 /* application/cose; cose-type="cose-sign1" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT 96 /* application/cose; cose-type="cose-encrypt" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0 16 /* application/cose; cose-type="cose-encrypt0" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC 97 /* application/cose; cose-type="cose-mac" */ +#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0 17 /* application/cose; cose-type="cose-mac0" */ + +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY 101 /* application/cose-key */ +#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET 102 /* application/cose-key-set */ + +/* Content formats from RFC 8428 */ +#define COAP_MEDIATYPE_APPLICATION_SENML_JSON 110 /* application/senml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON 111 /* application/sensml+json */ +#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR 112 /* application/senml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR 113 /* application/sensml+cbor */ +#define COAP_MEDIATYPE_APPLICATION_SENML_EXI 114 /* application/senml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI 115 /* application/sensml-exi */ +#define COAP_MEDIATYPE_APPLICATION_SENML_XML 310 /* application/senml+xml */ +#define COAP_MEDIATYPE_APPLICATION_SENSML_XML 311 /* application/sensml+xml */ + +/* Note that identifiers for registered media types are in the range 0-65535. We + * use an unallocated type here and hope for the best. */ +#define COAP_MEDIATYPE_ANY 0xff /* any media type */ + +/** + * coap_tid_t is used to store CoAP transaction id, i.e. a hash value + * built from the remote transport address and the message id of a + * CoAP PDU. Valid transaction ids are greater or equal zero. + */ +typedef int coap_tid_t; + +/** Indicates an invalid transaction id. */ +#define COAP_INVALID_TID -1 + +/** + * Indicates that a response is suppressed. This will occur for error + * responses if the request was received via IP multicast. + */ +#define COAP_DROPPED_RESPONSE -2 + +#define COAP_PDU_DELAYED -3 + +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list + * in a CoAP message is limited by 0b11110000 + * marker */ + +#define COAP_OPT_END 0xF0 /* end marker */ + +#define COAP_PAYLOAD_START 0xFF /* payload marker */ + +/** + * @deprecated Use coap_optlist_t instead. + * + * Structures for more convenient handling of options. (To be used with ordered + * coap_list_t.) The option's data will be added to the end of the coap_option + * structure (see macro COAP_OPTION_DATA). + */ +COAP_DEPRECATED typedef struct { + uint16_t key; /* the option key (no delta coding) */ + unsigned int length; +} coap_option; + +#define COAP_OPTION_KEY(option) (option).key +#define COAP_OPTION_LENGTH(option) (option).length +#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option)) + +/** + * structure for CoAP PDUs + * token, if any, follows the fixed size header, then options until + * payload marker (0xff), then the payload if stored inline. + * Memory layout is: + * <---header--->|<---token---><---options--->0xff<---payload---> + * header is addressed with a negative offset to token, its maximum size is + * max_hdr_size. + * options starts at token + token_length + * payload starts at data, its length is used_size - (data - token) + */ + +typedef struct coap_pdu_t { + uint8_t type; /**< message type */ + uint8_t code; /**< request method (value 1--10) or response code (value 40-255) */ + uint8_t max_hdr_size; /**< space reserved for protocol-specific header */ + uint8_t hdr_size; /**< actaul size used for protocol-specific header */ + uint8_t token_length; /**< length of Token */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + uint16_t max_delta; /**< highest option number */ + size_t alloc_size; /**< allocated storage for token, options and payload */ + size_t used_size; /**< used bytes of storage for token, options and payload */ + size_t max_size; /**< maximum size for token, options and payload, or zero for variable size pdu */ + uint8_t *token; /**< first byte of token, if any, or options */ + uint8_t *data; /**< first byte of payload, if any */ +#ifdef WITH_LWIP + struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside + * inside the pbuf's payload, but this pointer + * has to be kept because no exact offset can be + * given. This field must not be accessed from + * outside, because the pbuf's reference count + * is checked to be 1 when the pbuf is assigned + * to the pdu, and the pbuf stays exclusive to + * this pdu. */ +#endif +} coap_pdu_t; + +#define COAP_PDU_IS_EMPTY(pdu) ((pdu)->code == 0) +#define COAP_PDU_IS_REQUEST(pdu) (!COAP_PDU_IS_EMPTY(pdu) && (pdu)->code < 32) +#define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 224) +#define COAP_PDU_IS_SIGNALING(pdu) ((pdu)->code >= 224) + +#define COAP_PDU_MAX_UDP_HEADER_SIZE 4 +#define COAP_PDU_MAX_TCP_HEADER_SIZE 6 + +#ifdef WITH_LWIP +/** + * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this + * function. + * + * The pbuf is checked for being contiguous, and for having only one reference. + * The reference is stored in the PDU and will be freed when the PDU is freed. + * + * (For now, these are fatal errors; in future, a new pbuf might be allocated, + * the data copied and the passed pbuf freed). + * + * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards + * copying the contents of the pbuf to the pdu. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); +#endif + +typedef uint8_t coap_proto_t; +/** +* coap_proto_t values +*/ +#define COAP_PROTO_NONE 0 +#define COAP_PROTO_UDP 1 +#define COAP_PROTO_DTLS 2 +#define COAP_PROTO_TCP 3 +#define COAP_PROTO_TLS 4 + +/** + * Creates a new CoAP PDU with at least enough storage space for the given + * @p size maximum message size. The function returns a pointer to the + * node coap_pdu_t object on success, or @c NULL on error. The storage allocated + * for the result must be released with coap_delete_pdu() if coap_send() is not + * called. + * + * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON, + * COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * @param code The message code. + * @param tid The transcation id to set or 0 if unknown / not applicable. + * @param size The maximum allowed number of byte for the message. + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * +coap_pdu_init(uint8_t type, uint8_t code, uint16_t tid, size_t size); + +/** + * Dynamically grows the size of @p pdu to @p new_size. The new size + * must not exceed the PDU's configure maximum size. On success, this + * function returns 1, otherwise 0. + * + * @param pdu The PDU to resize. + * @param new_size The new size in bytes. + * @return 1 if the operation succeeded, 0 otherwise. + */ +int coap_pdu_resize(coap_pdu_t *pdu, size_t new_size); + +/** + * Clears any contents from @p pdu and resets @c used_size, + * and @c data pointers. @c max_size is set to @p size, any + * other field is set to @c 0. Note that @p pdu must be a valid + * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). + */ +void coap_pdu_clear(coap_pdu_t *pdu, size_t size); + +/** + * Creates a new CoAP PDU. + */ +coap_pdu_t *coap_new_pdu(const struct coap_session_t *session); + +/** + * Dispose of an CoAP PDU and frees associated storage. + * Not that in general you should not call this function directly. + * When a PDU is sent with coap_send(), coap_delete_pdu() will be + * called automatically for you. + */ + +void coap_delete_pdu(coap_pdu_t *); + +/** +* Interprets @p data to determine the number of bytes in the header. +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The first byte of raw data to parse as CoAP PDU. +* +* @return A value greater than zero on success or @c 0 on error. +*/ +size_t coap_pdu_parse_header_size(coap_proto_t proto, + const uint8_t *data); + +/** + * Parses @p data to extract the message size. + * @p length must be at least coap_pdu_parse_header_size(proto, data). + * This function returns @c 0 on error or a number greater than zero on success. + * + * @param proto Session's protocol + * @param data The raw data to parse as CoAP PDU. + * @param length The actual size of @p data. + * + * @return A value greater than zero on success or @c 0 on error. + */ +size_t coap_pdu_parse_size(coap_proto_t proto, + const uint8_t *data, + size_t length); + +/** + * Decode the protocol specific header for the specified PDU. + * @param pdu A newly received PDU. + * @param proto The target wire protocol. + * @return 1 for success or 0 on error. + */ + +int coap_pdu_parse_header(coap_pdu_t *pdu, coap_proto_t proto); + +/** + * Verify consistency in the given CoAP PDU structure and locate the data. + * This function returns @c 0 on error or a number greater than zero on + * success. + * This function only parses the token and options, up to the payload start + * marker. + * + * @param pdu The PDU structure to. + * + * @return 1 on success or @c 0 on error. + */ +int coap_pdu_parse_opt(coap_pdu_t *pdu); + +/** +* Parses @p data into the CoAP PDU structure given in @p result. +* The target pdu must be large enough to +* This function returns @c 0 on error or a number greater than zero on success. +* +* @param proto Session's protocol +* @param data The raw data to parse as CoAP PDU. +* @param length The actual size of @p data. +* @param pdu The PDU structure to fill. Note that the structure must +* provide space to hold at least the token and options +* part of the message. +* +* @return 1 on success or @c 0 on error. +*/ +int coap_pdu_parse(coap_proto_t proto, + const uint8_t *data, + size_t length, + coap_pdu_t *pdu); +/** + * Adds token of length @p len to @p pdu. + * Adding the token destroys any following contents of the pdu. Hence options + * and data must be added after coap_add_token() has been called. In @p pdu, + * length is set to @p len + @c 4, and max_delta is set to @c 0. This function + * returns @c 0 on error or a value greater than zero on success. + * + * @param pdu The PDU where the token is to be added. + * @param len The length of the new token. + * @param data The token to add. + * + * @return A value greater than zero on success, or @c 0 on error. + */ +int coap_add_token(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first + * parameter. + * coap_add_option() destroys the PDU's data, so coap_add_data() must be called + * after all options have been added. As coap_add_token() destroys the options + * following the token, the token must be added before coap_add_option() is + * called. This function returns the number of bytes written or @c 0 on error. + */ +size_t coap_add_option(coap_pdu_t *pdu, + uint16_t type, + size_t len, + const uint8_t *data); + +/** + * Adds option of given type to pdu that is passed as first parameter, but does + * not write a value. It works like coap_add_option with respect to calling + * sequence (i.e. after token and before data). This function returns a memory + * address to which the option data has to be written before the PDU can be + * sent, or @c NULL on error. + */ +uint8_t *coap_add_option_later(coap_pdu_t *pdu, + uint16_t type, + size_t len); + +/** + * Adds given data to the pdu that is passed as first parameter. Note that the + * PDU's data is destroyed by coap_add_option(). coap_add_data() must be called + * only once per PDU, otherwise the result is undefined. + */ +int coap_add_data(coap_pdu_t *pdu, + size_t len, + const uint8_t *data); + +/** + * Adds given data to the pdu that is passed as first parameter but does not + * copyt it. Note that the PDU's data is destroyed by coap_add_option(). + * coap_add_data() must be have been called once for this PDU, otherwise the + * result is undefined. + * The actual data must be copied at the returned location. + */ +uint8_t *coap_add_data_after(coap_pdu_t *pdu, size_t len); + +/** + * Retrieves the length and data pointer of specified PDU. Returns 0 on error or + * 1 if *len and *data have correct values. Note that these values are destroyed + * with the pdu. + */ +int coap_get_data(const coap_pdu_t *pdu, + size_t *len, + uint8_t **data); + +/** + * Compose the protocol specific header for the specified PDU. + * @param pdu A newly composed PDU. + * @param proto The target wire protocol. + * @return Number of header bytes prepended before pdu->token or 0 on error. + */ + +size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto); + +#endif /* COAP_PDU_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/prng.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/prng.h new file mode 100644 index 00000000000..c9510bf5602 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/prng.h @@ -0,0 +1,127 @@ +/* + * prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef COAP_PRNG_H_ +#define COAP_PRNG_H_ + +/** + * @defgroup prng Pseudo Random Numbers + * API functions for gerating pseudo random numbers + * @{ + */ + +#if defined(WITH_CONTIKI) +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +contiki_prng_impl(unsigned char *buf, size_t len) { + uint16_t v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) contiki_prng_impl((Buf), (Length)) +#define prng_init(Value) random_init((uint16_t)(Value)) +#elif defined(WITH_LWIP) && defined(LWIP_RAND) +COAP_STATIC_INLINE int +lwip_prng_impl(unsigned char *buf, size_t len) { + u32_t v = LWIP_RAND(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = LWIP_RAND(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) lwip_prng_impl((Buf), (Length)) +#define prng_init(Value) +#elif defined(_WIN32) +#define prng_init(Value) +errno_t __cdecl rand_s( _Out_ unsigned int* _RandomValue ); + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len != 0 ) { + uint32_t r = 0; + size_t i; + if ( rand_s( &r ) != 0 ) + return 0; + for ( i = 0; i < len && i < 4; i++ ) { + *buf++ = (uint8_t)r; + r >>= 8; + } + len -= i; + } + return 1; +} + +#else +#include + + /** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +COAP_STATIC_INLINE int +coap_prng_impl( unsigned char *buf, size_t len ) { + while ( len-- ) + *buf++ = rand() & 0xFF; + return 1; +} +#endif + + +#ifndef prng +/** + * Fills \p Buf with \p Length bytes of random data. + * + * @hideinitializer + */ +#define prng(Buf,Length) coap_prng_impl((Buf), (Length)) +#endif + +#ifndef prng_init +/** + * Called to set the PRNG seed. You may want to re-define this to allow for a + * better PRNG. + * + * @hideinitializer + */ +#define prng_init(Value) srand((unsigned long)(Value)) +#endif + +/** @} */ + +#endif /* COAP_PRNG_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/resource.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/resource.h new file mode 100644 index 00000000000..58018720e4e --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/resource.h @@ -0,0 +1,524 @@ +/* + * resource.h -- generic resource handling + * + * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file resource.h + * @brief Generic resource handling + */ + +#ifndef COAP_RESOURCE_H_ +#define COAP_RESOURCE_H_ + +# include + +#ifndef COAP_RESOURCE_CHECK_TIME +/** The interval in seconds to check if resources have changed. */ +#define COAP_RESOURCE_CHECK_TIME 2 +#endif /* COAP_RESOURCE_CHECK_TIME */ + +#include "uthash.h" +#include "async.h" +#include "str.h" +#include "pdu.h" +#include "net.h" +#include "subscribe.h" + +/** + * Definition of message handler function (@sa coap_resource_t). + */ +typedef void (*coap_method_handler_t) + (coap_context_t *, + struct coap_resource_t *, + coap_session_t *, + coap_pdu_t *, + coap_binary_t * /* token */, + coap_string_t * /* query string */, + coap_pdu_t * /* response */); + +#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1 +#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2 + +typedef struct coap_attr_t { + struct coap_attr_t *next; + coap_str_const_t *name; + coap_str_const_t *value; + int flags; +} coap_attr_t; + +/** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ +#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1 + +/** + * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0 + +/** + * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2 + +typedef struct coap_resource_t { + unsigned int dirty:1; /**< set to 1 if resource has changed */ + unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet + * been notified of the last change */ + unsigned int observable:1; /**< can be observed */ + unsigned int cacheable:1; /**< can be cached */ + unsigned int is_unknown:1; /**< resource created for unknown handler */ + + /** + * Used to store handlers for the seven coap methods @c GET, @c POST, @c PUT, + * @c DELETE, @c FETCH, @c PATCH and @c IPATCH. + * coap_dispatch() will pass incoming requests to the handler + * that corresponds to its request method or generate a 4.05 response if no + * handler is available. + */ + coap_method_handler_t handler[7]; + + UT_hash_handle hh; + + coap_attr_t *link_attr; /**< attributes to be included with the link format */ + coap_subscription_t *subscribers; /**< list of observers for this resource */ + + /** + * Request URI Path for this resource. This field will point into static + * or allocated memory which must remain there for the duration of the + * resource. + */ + coap_str_const_t *uri_path; /**< the key used for hash lookup for this resource */ + int flags; + + /** + * The next value for the Observe option. This field must be increased each + * time the resource changes. Only the lower 24 bits are sent. + */ + unsigned int observe; + + /** + * This pointer is under user control. It can be used to store context for + * the coap handler. + */ + void *user_data; + +} coap_resource_t; + +/** + * Creates a new resource object and initializes the link field to the string + * @p uri_path. This function returns the new coap_resource_t object. + * + * If the string is going to be freed off by coap_delete_resource() when + * COAP_RESOURCE_FLAGS_RELEASE_URI is set in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param uri_path The string URI path of the new resource. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_RESOURCE_FLAGS_RELEASE_URI + * If this flag is set, the URI passed to + * coap_resource_init() is free'd by + * coap_delete_resource()@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_CON + * If this flag is set, coap-observe notifications + * will be sent confirmable by default.@n + * + * COAP_RESOURCE_FLAGS_NOTIFY_NON (default) + * If this flag is set, coap-observe notifications + * will be sent non-confirmable by default.@n + * + * If flags is set to 0 then the + * COAP_RESOURCE_FLAGS_NOTIFY_NON is considered. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, + int flags); + + +/** + * Creates a new resource object for the unknown resource handler with support + * for PUT. + * + * In the same way that additional handlers can be added to the resource + * created by coap_resource_init() by using coap_register_handler(), POST, + * GET, DELETE etc. handlers can be added to this resource. It is the + * responsibility of the application to manage the unknown resources by either + * creating new resources with coap_resource_init() (which should have a + * DELETE handler specified for the resource removal) or by maintaining an + * active resource list. + * + * Note: There can only be one unknown resource handler per context - attaching + * a new one overrides the previous definition. + * + * Note: It is not possible to observe the unknown resource with a GET request + * - a separate resource needs to be reated by the PUT (or POST) handler, + * and make that resource observable. + * + * This function returns the new coap_resource_t object. + * + * @param put_handler The PUT handler to register with @p resource for + * unknown Uri-Path. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_unknown_init(coap_method_handler_t put_handler); + +/** + * Sets the notification message type of resource @p resource to given + * @p mode + + * @param resource The resource to update. + * @param mode Must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON + * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. + */ +COAP_STATIC_INLINE void +coap_resource_set_mode(coap_resource_t *resource, int mode) { + resource->flags = (resource->flags & + ~(COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)) | + (mode & (COAP_RESOURCE_FLAGS_NOTIFY_CON|COAP_RESOURCE_FLAGS_NOTIFY_NON)); +} + +/** + * Sets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to attach the data to + * @param data Data to attach to the user_data field. This pointer is only used for + * storage, the data remains under user control + */ +COAP_STATIC_INLINE void +coap_resource_set_userdata(coap_resource_t *r, void *data) { + r->user_data = data; +} + +/** + * Gets the user_data. The user_data is exclusively used by the library-user + * and can be used as context in the handler functions. + * + * @param r Resource to retrieve the user_darta from + * + * @return The user_data pointer + */ +COAP_STATIC_INLINE void * +coap_resource_get_userdata(coap_resource_t *r) { + return r->user_data; +} + +/** + * Registers the given @p resource for @p context. The resource must have been + * created by coap_resource_init() or coap_resource_unknown_init(), the + * storage allocated for the resource will be released by coap_delete_resource(). + * + * @param context The context to use. + * @param resource The resource to store. + */ +void coap_add_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes a resource identified by @p resource. The storage allocated for that + * resource is freed, and removed from the context. + * + * @param context The context where the resources are stored. + * @param resource The resource to delete. + * + * @return @c 1 if the resource was found (and destroyed), + * @c 0 otherwise. + */ +int coap_delete_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes all resources from given @p context and frees their storage. + * + * @param context The CoAP context with the resources to be deleted. + */ +void coap_delete_all_resources(coap_context_t *context); + +/** + * Registers a new attribute with the given @p resource. As the + * attribute's coap_str_const_ fields will point to @p name and @p value the + * caller must ensure that these pointers are valid during the + * attribute's lifetime. + + * If the @p name and/or @p value string is going to be freed off at attribute + * removal time by the setting of COAP_ATTR_FLAGS_RELEASE_NAME or + * COAP_ATTR_FLAGS_RELEASE_VALUE in @p flags, then either the 's' + * variable of coap_str_const_t has to point to constant text, or point to data + * within the allocated coap_str_const_t parameter. + * + * @param resource The resource to register the attribute with. + * @param name The attribute's name as a string. + * @param value The attribute's value as a string or @c NULL if none. + * @param flags Flags for memory management (in particular release of + * memory). Possible values:@n + * + * COAP_ATTR_FLAGS_RELEASE_NAME + * If this flag is set, the name passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * COAP_ATTR_FLAGS_RELEASE_VALUE + * If this flag is set, the value passed to + * coap_add_attr_release() is free'd + * when the attribute is deleted@n + * + * @return A pointer to the new attribute or @c NULL on error. + */ +coap_attr_t *coap_add_attr(coap_resource_t *resource, + coap_str_const_t *name, + coap_str_const_t *value, + int flags); + +/** + * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL + * otherwise. + * + * @param resource The resource to search for attribute @p name. + * @param name Name of the requested attribute as a string. + * @return The first attribute with specified @p name or @c NULL if none + * was found. + */ +coap_attr_t *coap_find_attr(coap_resource_t *resource, + coap_str_const_t *name); + +/** + * Deletes an attribute. + * Note: This is for internal use only, as it is not deleted from its chain. + * + * @param attr Pointer to a previously created attribute. + * + */ +void coap_delete_attr(coap_attr_t *attr); + +/** + * Status word to encode the result of conditional print or copy operations such + * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to + * encode the number of characters that has actually been printed, bits 28 to 31 + * encode the status. When COAP_PRINT_STATUS_ERROR is set, an error occurred + * during output. In this case, the other bits are undefined. + * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the + * printing would have exceeded the current buffer. + */ +typedef unsigned int coap_print_status_t; + +#define COAP_PRINT_STATUS_MASK 0xF0000000u +#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK) +#define COAP_PRINT_STATUS_ERROR 0x80000000u +#define COAP_PRINT_STATUS_TRUNC 0x40000000u + +/** + * Writes a description of this resource in link-format to given text buffer. @p + * len must be initialized to the maximum length of @p buf and will be set to + * the number of characters actually written if successful. This function + * returns @c 1 on success or @c 0 on error. + * + * @param resource The resource to describe. + * @param buf The output buffer to write the description to. + * @param len Must be initialized to the length of @p buf and + * will be set to the length of the printed link description. + * @param offset The offset within the resource description where to + * start writing into @p buf. This is useful for dealing + * with the Block2 option. @p offset is updated during + * output as it is consumed. + * + * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, + * the lower 28 bits will indicate the number of characters that + * have actually been output into @p buffer. The flag + * COAP_PRINT_STATUS_TRUNC indicates that the output has been + * truncated. + */ +coap_print_status_t coap_print_link(const coap_resource_t *resource, + unsigned char *buf, + size_t *len, + size_t *offset); + +/** + * Registers the specified @p handler as message handler for the request type @p + * method + * + * @param resource The resource for which the handler shall be registered. + * @param method The CoAP request method to handle. + * @param handler The handler to register with @p resource. + */ +void coap_register_handler(coap_resource_t *resource, + unsigned char method, + coap_method_handler_t handler); + +/** + * Returns the resource identified by the unique string @p uri_path. If no + * resource was found, this function returns @c NULL. + * + * @param context The context to look for this resource. + * @param uri_path The unique string uri of the resource. + * + * @return A pointer to the resource or @c NULL if not found. + */ +coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context, + coap_str_const_t *uri_path); + +/** + * @addtogroup observe + */ + +/** + * Adds the specified peer as observer for @p resource. The subscription is + * identified by the given @p token. This function returns the registered + * subscription information if the @p observer has been added, or @c NULL on + * error. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription. + * @param query The query string, if any. subscription will + take ownership of the string. + * @param has_block2 If Option Block2 defined. + * @param block2 Contents of Block2 if Block 2 defined. + * @return A pointer to the added/updated subscription + * information or @c NULL on error. + */ +coap_subscription_t *coap_add_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token, + coap_string_t *query, + int has_block2, + coap_block_t block2); + +/** + * Returns a subscription object for given @p peer. + * + * @param resource The observed resource. + * @param session The observer's session + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return A valid subscription if exists or @c NULL otherwise. + */ +coap_subscription_t *coap_find_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Marks an observer as alive. + * + * @param context The CoAP context to use. + * @param session The observer's session + * @param token The corresponding token that has been used for the + * subscription. + */ +void coap_touch_observer(coap_context_t *context, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p observer from @p resource and releases the + * allocated storage. The result is @c 1 if an observation relationship with @p + * observer and @p token existed, @c 0 otherwise. + * + * @param resource The observed resource. + * @param session The observer's session. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return @c 1 if the observer has been deleted, @c 0 otherwise. + */ +int coap_delete_observer(coap_resource_t *resource, + coap_session_t *session, + const coap_binary_t *token); + +/** + * Removes any subscription for @p session and releases the allocated storage. + * + * @param context The CoAP context to use. + * @param session The observer's session. + */ +void coap_delete_observers(coap_context_t *context, coap_session_t *session); + +/** + * Checks for all known resources, if they are dirty and notifies subscribed + * observers. + */ +void coap_check_notify(coap_context_t *context); + +#define RESOURCES_ADD(r, obj) \ + HASH_ADD(hh, (r), uri_path->s[0], (obj)->uri_path->length, (obj)) + +#define RESOURCES_DELETE(r, obj) \ + HASH_DELETE(hh, (r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp, *rtmp; \ + HASH_ITER(hh, (r), tmp, rtmp) + +#define RESOURCES_FIND(r, k, res) { \ + HASH_FIND(hh, (r), (k)->s, (k)->length, (res)); \ + } + +/** @} */ + +coap_print_status_t coap_print_wellknown(coap_context_t *, + unsigned char *, + size_t *, size_t, + coap_opt_t *); + +void +coap_handle_failed_notify(coap_context_t *, + coap_session_t *, + const coap_binary_t *); + +/** + * Set whether a @p resource is observable. If the resource is observable + * and the client has set the COAP_OPTION_OBSERVE in a request packet, then + * whenever the state of the resource changes (a call to + * coap_resource_trigger_observe()), an Observer response will get sent. + * + * @param resource The CoAP resource to use. + * @param mode @c 1 if Observable is to be set, @c 0 otherwise. + * + */ +COAP_STATIC_INLINE void +coap_resource_set_get_observable(coap_resource_t *resource, int mode) { + resource->observable = mode ? 1 : 0; +} + +/** + * Initiate the sending of an Observe packet for all observers of @p resource, + * optionally matching @p query if not NULL + * + * @param resource The CoAP resource to use. + * @param query The Query to match against or NULL + * + * @return @c 1 if the Observe has been triggered, @c 0 otherwise. + */ +int +coap_resource_notify_observers(coap_resource_t *resource, + const coap_string_t *query); + +/** + * Get the UriPath from a @p resource. + * + * @param resource The CoAP resource to check. + * + * @return The UriPath if it exists or @c NULL otherwise. + */ +COAP_STATIC_INLINE coap_str_const_t* +coap_resource_get_uri_path(coap_resource_t *resource) { + if (resource) + return resource->uri_path; + return NULL; +} + +/** + * @deprecated use coap_resource_notify_observers() instead. + */ +COAP_DEPRECATED int +coap_resource_set_dirty(coap_resource_t *r, + const coap_string_t *query); + +#endif /* COAP_RESOURCE_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/str.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/str.h new file mode 100644 index 00000000000..6c1488c982d --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/str.h @@ -0,0 +1,121 @@ +/* + * str.h -- strings to be used in the CoAP library + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_STR_H_ +#define COAP_STR_H_ + +#include + + +/** + * @defgroup string String handling support + * API functions for handling strings + * @{ + */ + +/** + * Coap string data definition + */ +typedef struct coap_string_t { + size_t length; /**< length of string */ + uint8_t *s; /**< string data */ +} coap_string_t; + +/** + * Coap string data definition with const data + */ +typedef struct coap_str_const_t { + size_t length; /**< length of string */ + const uint8_t *s; /**< string data */ +} coap_str_const_t; + +#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); } + +/** + * Coap binary data definition + */ +typedef struct coap_binary_t { + size_t length; /**< length of binary data */ + uint8_t *s; /**< binary data */ +} coap_binary_t; + +/** + * Returns a new string object with at least size+1 bytes storage allocated. + * The string must be released using coap_delete_string(). + * + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_string_t *coap_new_string(size_t size); + +/** + * Deletes the given string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_string(coap_string_t *string); + +/** + * Returns a new const string object with at least size+1 bytes storage + * allocated, and the provided data copied into the string object. + * The string must be released using coap_delete_str_const(). + * + * @param data The data to put in the new string object. + * @param size The size to allocate for the binary string data. + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_str_const_t *coap_new_str_const(const uint8_t *data, size_t size); + +/** + * Deletes the given const string and releases any memory allocated. + * + * @param string The string to free off. + */ +void coap_delete_str_const(coap_str_const_t *string); + +/** + * Take the specified byte array (text) and create a coap_str_const_t * + * + * WARNING: The byte array must be in the local scope and not a + * parameter in the function call as sizeof() will return the size of the + * pointer, not the size of the byte array, leading to unxepected results. + * + * @param string The const byte array to convert to a coap_str_const_t * + */ +#ifdef __cplusplus +namespace libcoap { + struct CoAPStrConst : coap_str_const_t { + operator coap_str_const_t *() { return this; } + }; +} +#define coap_make_str_const(CStr) \ + libcoap::CoAPStrConst{sizeof(CStr)-1, reinterpret_cast(CStr)} +#else /* __cplusplus */ +#define coap_make_str_const(string) \ + (&(coap_str_const_t){sizeof(string)-1,(const uint8_t *)(string)}) +#endif /* __cplusplus */ + +/** + * Compares the two strings for equality + * + * @param string1 The first string. + * @param string2 The second string. + * + * @return @c 1 if the strings are equal + * @c 0 otherwise. + */ +#define coap_string_equal(string1,string2) \ + ((string1)->length == (string2)->length && ((string1)->length == 0 || \ + memcmp((string1)->s, (string2)->s, (string1)->length) == 0)) + +/** @} */ + +#endif /* COAP_STR_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/subscribe.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/subscribe.h new file mode 100644 index 00000000000..ed635a6182a --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/subscribe.h @@ -0,0 +1,77 @@ +/* + * subscribe.h -- subscription handling for CoAP + * see RFC7641 + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + + +#ifndef COAP_SUBSCRIBE_H_ +#define COAP_SUBSCRIBE_H_ + +#include "address.h" +#include "coap_io.h" +#include "block.h" + +/** + * @defgroup observe Resource observation + * API functions for interfacing with the observe handling (RFC7641) + * @{ + */ + +/** + * The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe + * relationship for (sender address, token) is requested. + */ +#define COAP_OBSERVE_ESTABLISH 0 + +/** + * The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe + * relationship for (sender address, token) must be cancelled. + */ +#define COAP_OBSERVE_CANCEL 1 + +#ifndef COAP_OBS_MAX_NON +/** + * Number of notifications that may be sent non-confirmable before a confirmable + * message is sent to detect if observers are alive. The maximum allowed value + * here is @c 15. + */ +#define COAP_OBS_MAX_NON 5 +#endif /* COAP_OBS_MAX_NON */ + +#ifndef COAP_OBS_MAX_FAIL +/** + * Number of confirmable notifications that may fail (i.e. time out without + * being ACKed) before an observer is removed. The maximum value for + * COAP_OBS_MAX_FAIL is @c 3. + */ +#define COAP_OBS_MAX_FAIL 3 +#endif /* COAP_OBS_MAX_FAIL */ + +/** Subscriber information */ +typedef struct coap_subscription_t { + struct coap_subscription_t *next; /**< next element in linked list */ + coap_session_t *session; /**< subscriber session */ + + unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */ + unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */ + unsigned int dirty:1; /**< set if the notification temporarily could not be + * sent (in that case, the resource's partially + * dirty flag is set too) */ + unsigned int has_block2:1; /**< GET request had Block2 definition */ + uint16_t tid; /**< transaction id, if any, in regular host byte order */ + coap_block_t block2; /**< GET request Block2 definition */ + size_t token_length; /**< actual length of token */ + unsigned char token[8]; /**< token used for subscription */ + coap_string_t *query; /**< query string used for subscription, if any */ +} coap_subscription_t; + +void coap_subscription_init(coap_subscription_t *); + +/** @} */ + +#endif /* COAP_SUBSCRIBE_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uri.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uri.h new file mode 100644 index 00000000000..4d1670115eb --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uri.h @@ -0,0 +1,147 @@ +/* + * uri.h -- helper functions for URI treatment + * + * Copyright (C) 2010-2011,2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_URI_H_ +#define COAP_URI_H_ + +#include + +#include "str.h" +struct coap_pdu_t; + +/** + * The scheme specifiers. Secure schemes have an odd numeric value, + * others are even. + */ +enum coap_uri_scheme_t { + COAP_URI_SCHEME_COAP=0, + COAP_URI_SCHEME_COAPS=1, + COAP_URI_SCHEME_COAP_TCP=2, + COAP_URI_SCHEME_COAPS_TCP=3 +}; + +/** This mask can be used to check if a parsed URI scheme is secure. */ +#define COAP_URI_SCHEME_SECURE_MASK 0x01 + +/** + * Representation of parsed URI. Components may be filled from a string with + * coap_split_uri() and can be used as input for option-creation functions. + */ +typedef struct { + coap_str_const_t host; /**< host part of the URI */ + uint16_t port; /**< The port in host byte order */ + coap_str_const_t path; /**< Beginning of the first path segment. + Use coap_split_path() to create Uri-Path options */ + coap_str_const_t query; /**< The query part if present */ + + /** The parsed scheme specifier. */ + enum coap_uri_scheme_t scheme; +} coap_uri_t; + +static inline int +coap_uri_scheme_is_secure(const coap_uri_t *uri) { + return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0); +} + +/** + * Creates a new coap_uri_t object from the specified URI. Returns the new + * object or NULL on error. The memory allocated by the new coap_uri_t + * must be released using coap_free(). + * + * @param uri The URI path to copy. + * @param length The length of uri. + * + * @return New URI object or NULL on error. + */ +coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length); + +/** + * Clones the specified coap_uri_t object. Thie function allocates sufficient + * memory to hold the coap_uri_t structure and its contents. The object must + * be released with coap_free(). */ +coap_uri_t *coap_clone_uri(const coap_uri_t *uri); + +/** + * @defgroup uri_parse URI Parsing Functions + * + * CoAP PDUs contain normalized URIs with their path and query split into + * multiple segments. The functions in this module help splitting strings. + * @{ + */ + +/** + * Parses a given string into URI components. The identified syntactic + * components are stored in the result parameter @p uri. Optional URI + * components that are not specified will be set to { 0, 0 }, except for the + * port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if + * parsing succeeded, a value less than zero otherwise. + * + * @param str_var The string to split up. + * @param len The actual length of @p str_var + * @param uri The coap_uri_t object to store the result. + * @return @c 0 on success, or < 0 on error. + * + */ +int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); + +/** + * Splits the given URI path into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective segment after percent-decoding. + * + * @param s The path string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + */ +int coap_split_path(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Splits the given URI query into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective query term. + * + * @param s The query string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + * + * @bug This function does not reserve additional space for delta > 12. + */ +int coap_split_query(const uint8_t *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Extract query string from request PDU according to escape rules in 6.5.8. + * @param request Request PDU. + * @return Reconstructed and escaped query string part. + */ +coap_string_t *coap_get_query(const struct coap_pdu_t *request); + +/** + * Extract uri_path string from request PDU + * @param request Request PDU. + * @return Reconstructed and escaped uri path string part. + */ +coap_string_t *coap_get_uri_path(const struct coap_pdu_t *request); + +/** @} */ + +#endif /* COAP_URI_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uthash.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uthash.h new file mode 100644 index 00000000000..156eb8210c1 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/uthash.h @@ -0,0 +1,1108 @@ +/* +Copyright (c) 2003-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.0.2 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_memcmp +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + if (!(head)->hh.tbl->buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (const void *) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE"); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + default: ; /* does not happen */ \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch ((keylen) & 3U) { \ + case 0: break; \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + uthash_fatal("out of memory"); \ + } \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / (tbl)->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], _dst_hh); \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + const void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/utlist.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/utlist.h new file mode 100644 index 00000000000..2f4c08406f4 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap2/utlist.h @@ -0,0 +1,1073 @@ +/* +Copyright (c) 2007-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 2.0.2 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define IF_NO_DECLTYPE(x) x +#define LDECLTYPE(x) char* +#define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) +#define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define UTLIST_PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define IF_NO_DECLTYPE(x) +#define UTLIST_SV(elt,list) +#define UTLIST_NEXT(elt,list,next) ((elt)->next) +#define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define UTLIST_PREV(elt,list,prev) ((elt)->prev) */ +#define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define UTLIST_RS(list) +#define UTLIST_CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } else if ((_ls_qsize == 0) || (!_ls_q)) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev, _ls_tail); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + UTLIST_CASTASGN(_ls_p,list); \ + UTLIST_CASTASGN(_ls_oldhead,list); \ + (list) = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + UTLIST_SV(_ls_q,list); \ + if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = UTLIST_NEXT(_ls_q,list,next); \ + } \ + UTLIST_RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ + UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ + UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ + } else { \ + UTLIST_CASTASGN(list,_ls_e); \ + } \ + UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + UTLIST_CASTASGN((list)->prev,_ls_tail); \ + UTLIST_CASTASGN(_tmp,list); \ + UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = (head); \ + (head) = (add); \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = (head1); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = (head); \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_INSERT_INORDER(head,add,cmp) \ + LL_INSERT_INORDER2(head,add,cmp,next) + +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + LL_LOWER_BOUND(head, _tmp, add, cmp); \ + LL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define LL_LOWER_BOUND(head,elt,like,cmp) \ + LL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ + do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if (cmp((elt)->next, like) >= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (del)->next; \ + } \ + } \ +} while (0) + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + LL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_REPLACE_ELEM(head, el, add) \ + LL_REPLACE_ELEM2(head, el, add, next) + +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + LDECLTYPE(head) _tmp; \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = (head); \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_PREPEND_ELEM(head, el, add) \ + LL_PREPEND_ELEM2(head, el, add, next) + +#define LL_APPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (el)->next = (add); \ + } else { \ + LL_PREPEND2(head, add, next); \ + } \ +} while (0) \ + +#define LL_APPEND_ELEM(head, el, add) \ + LL_APPEND_ELEM2(head, el, add, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef LL_CONCAT2 +#define LL_CONCAT2(head1,head2,next) \ +do { \ + char *_tmp; \ + if (head1) { \ + _tmp = (char*)(head1); \ + while ((head1)->next) { (head1) = (head1)->next; } \ + (head1)->next = (head2); \ + UTLIST_RS(head1); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#undef LL_APPEND2 +#define LL_APPEND2(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#undef LL_INSERT_INORDER2 +#define LL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, add)) >= 0) { \ + (add)->next = (head); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_DELETE2 +#define LL_DELETE2(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + (head) = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + UTLIST_RS(head); \ + } \ +} while (0) + +#undef LL_REPLACE_ELEM2 +#define LL_REPLACE_ELEM2(head, el, add, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = head; \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el)->next; \ +} while (0) + +#undef LL_PREPEND_ELEM2 +#define LL_PREPEND_ELEM2(head, el, add, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->next = (head); \ + while ((add)->next->next && ((add)->next->next != (el))) { \ + (add)->next = (add)->next->next; \ + } \ + if ((add)->next->next) { \ + (add)->next->next = (add); \ + } \ + } \ + (add)->next = (el); \ + } else { \ + LL_APPEND2(head, add, next); \ + } \ +} while (0) \ + +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = (head); \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_INSERT_INORDER(head,add,cmp) \ + DL_INSERT_INORDER2(head,add,cmp,next) + +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + DL_LOWER_BOUND(head, _tmp, add, cmp); \ + DL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_LOWER_BOUND(head,elt,like,cmp) \ + DL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + UTLIST_CASTASGN(_tmp, (head2)->prev); \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + UTLIST_CASTASGN((head1)->prev, _tmp); \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((head) != NULL); \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +do { \ + (counter) = 0; \ + DL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for ((el) = (head); el; (el) = (el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_REPLACE_ELEM(head, el, add) \ + DL_REPLACE_ELEM2(head, el, add, prev, next) + +#define DL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ + } else { \ + DL_APPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_PREPEND_ELEM(head, el, add) \ + DL_PREPEND_ELEM2(head, el, add, prev, next) + +#define DL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } else { \ + DL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) \ + +#define DL_APPEND_ELEM(head, el, add) \ + DL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef DL_INSERT_INORDER2 +#define DL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = NULL; \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (head)->next = (add); \ + UTLIST_RS(head); \ + if ((add)->next) { \ + (add)->next->prev = (add); \ + } else { \ + (head)->prev = (add); \ + } \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_APPEND(head,add) \ + CDL_APPEND2(head,add,prev,next) + +#define CDL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } \ +} while (0) + +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define CDL_INSERT_INORDER(head,add,cmp) \ + CDL_INSERT_INORDER2(head,add,cmp,next) + +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if (head) { \ + CDL_LOWER_BOUND(head, _tmp, add, cmp); \ + CDL_APPEND_ELEM(head, _tmp, add); \ + } else { \ + (head) = (add); \ + (head)->next = (head); \ + (head)->prev = (head); \ + } \ +} while (0) + +#define CDL_LOWER_BOUND(head,elt,like,cmp) \ + CDL_LOWER_BOUND2(head,elt,like,cmp,next) + +#define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ +do { \ + if ((head) == NULL || (cmp(head, like)) >= 0) { \ + (elt) = NULL; \ + } else { \ + for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ + if ((cmp((elt)->next, like)) >= 0) { \ + break; \ + } \ + } \ + } \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if (((head)==(del)) && ((head)->next == (head))) { \ + (head) = NULL; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +do { \ + (counter) = 0; \ + CDL_FOREACH2(head,el,next) { ++(counter); } \ +} while (0) + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ + (el) && ((tmp2) = (el)->next, 1); \ + (el) = ((el) == (tmp1) ? NULL : (tmp2))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while (0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ +do { \ + assert((head) != NULL); \ + assert((el) != NULL); \ + assert((add) != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_REPLACE_ELEM(head, el, add) \ + CDL_REPLACE_ELEM2(head, el, add, prev, next) + +#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } else { \ + CDL_APPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ + CDL_PREPEND_ELEM2(head, el, add, prev, next) + +#define CDL_APPEND_ELEM2(head, el, add, prev, next) \ +do { \ + if (el) { \ + assert((head) != NULL); \ + assert((add) != NULL); \ + (add)->next = (el)->next; \ + (add)->prev = (el); \ + (el)->next = (add); \ + (add)->next->prev = (add); \ + } else { \ + CDL_PREPEND2(head, add, prev, next); \ + } \ +} while (0) + +#define CDL_APPEND_ELEM(head, el, add) \ + CDL_APPEND_ELEM2(head, el, add, prev, next) + +#ifdef NO_DECLTYPE +/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ + +#undef CDL_INSERT_INORDER2 +#define CDL_INSERT_INORDER2(head,add,cmp,next) \ +do { \ + if ((head) == NULL) { \ + (add)->prev = (add); \ + (add)->next = (add); \ + (head) = (add); \ + } else if ((cmp(head, add)) >= 0) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (add)->prev->next = (add); \ + (head)->prev = (add); \ + (head) = (add); \ + } else { \ + char *_tmp = (char*)(head); \ + while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ + (head) = (head)->next; \ + } \ + (add)->prev = (head); \ + (add)->next = (head)->next; \ + (add)->next->prev = (add); \ + (head)->next = (add); \ + UTLIST_RS(head); \ + } \ +} while (0) +#endif /* NO_DECLTYPE */ + +#endif /* UTLIST_H */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_block_internal.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_block_internal.h index 9abe81557fa..b7ad0a554cc 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_block_internal.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_block_internal.h @@ -191,6 +191,9 @@ int coap_handle_response_get_block(coap_context_t *context, void coap_block_delete_lg_xmit(coap_session_t *session, coap_lg_xmit_t *lg_xmit); +coap_tick_t coap_block_check_lg_xmit_timeouts(coap_session_t *session, + coap_tick_t now); + /** * The function that does all the work for the coap_add_data_large*() * functions. diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_dtls.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_dtls.h index cbd369dfce6..fc30445431d 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_dtls.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_dtls.h @@ -27,6 +27,12 @@ typedef struct coap_dtls_pki_t coap_dtls_pki_t; #ifndef COAP_DTLS_HINT_LENGTH #define COAP_DTLS_HINT_LENGTH 128 #endif +#ifndef COAP_DTLS_MAX_PSK_IDENTITY +#define COAP_DTLS_MAX_PSK_IDENTITY 64 +#endif +#ifndef COAP_DTLS_MAX_PSK +#define COAP_DTLS_MAX_PSK 64 +#endif typedef enum coap_dtls_role_t { COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_event.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_event.h index 89b2a63967c..b6ea60524a2 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_event.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_event.h @@ -24,34 +24,34 @@ * Scalar type to represent different events, e.g. DTLS events or * retransmission timeouts. */ - typedef unsigned int coap_event_t; - +typedef enum coap_event_t { /** * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS */ -#define COAP_EVENT_DTLS_CLOSED 0x0000 -#define COAP_EVENT_DTLS_CONNECTED 0x01DE -#define COAP_EVENT_DTLS_RENEGOTIATE 0x01DF -#define COAP_EVENT_DTLS_ERROR 0x0200 + COAP_EVENT_DTLS_CLOSED = 0x0000, + COAP_EVENT_DTLS_CONNECTED = 0x01DE, + COAP_EVENT_DTLS_RENEGOTIATE = 0x01DF, + COAP_EVENT_DTLS_ERROR = 0x0200, /** * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS */ -#define COAP_EVENT_TCP_CONNECTED 0x1001 -#define COAP_EVENT_TCP_CLOSED 0x1002 -#define COAP_EVENT_TCP_FAILED 0x1003 + COAP_EVENT_TCP_CONNECTED = 0x1001, + COAP_EVENT_TCP_CLOSED = 0x1002, + COAP_EVENT_TCP_FAILED = 0x1003, /** * CSM exchange events for reliable protocols only */ -#define COAP_EVENT_SESSION_CONNECTED 0x2001 -#define COAP_EVENT_SESSION_CLOSED 0x2002 -#define COAP_EVENT_SESSION_FAILED 0x2003 + COAP_EVENT_SESSION_CONNECTED = 0x2001, + COAP_EVENT_SESSION_CLOSED = 0x2002, + COAP_EVENT_SESSION_FAILED = 0x2003, /** - * BLOCK2 receive errors + * (Q-)BLOCK receive errors */ -#define COAP_EVENT_PARTIAL_BLOCK 0x3001 + COAP_EVENT_PARTIAL_BLOCK = 0x3001 +} coap_event_t; /** * Type for event handler functions that can be registered with a CoAP diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_time.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_time.h index baa8650eaff..99d117a4eb7 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_time.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/coap_time.h @@ -88,7 +88,11 @@ COAP_STATIC_INLINE uint64_t coap_ticks_to_rt_us(coap_tick_t t) { #elif defined(RIOT_VERSION) #include +#ifdef XTIMER_HZ #define COAP_TICKS_PER_SECOND (XTIMER_HZ) +#else /* XTIMER_HZ */ +#define COAP_TICKS_PER_SECOND (XTIMER_HZ_BASE) +#endif /* XTIMER_HZ */ typedef uint64_t coap_tick_t; typedef int64_t coap_tick_diff_t; diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/net.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/net.h index 577a0b5d5a5..ea5a2cba1bb 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/net.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/net.h @@ -15,6 +15,7 @@ #include #include #ifndef _WIN32 +#include #include #endif #include diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/pdu.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/pdu.h index a22869b69ed..8031a1c2c40 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/pdu.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/pdu.h @@ -299,7 +299,6 @@ typedef enum coap_pdu_code_t { COAP_REQUEST_CODE_PATCH = COAP_REQUEST_PATCH, COAP_REQUEST_CODE_IPATCH = COAP_REQUEST_IPATCH, - COAP_RESPONSE_CODE_OK = COAP_RESPONSE_CODE(200), COAP_RESPONSE_CODE_CREATED = COAP_RESPONSE_CODE(201), COAP_RESPONSE_CODE_DELETED = COAP_RESPONSE_CODE(202), COAP_RESPONSE_CODE_VALID = COAP_RESPONSE_CODE(203), diff --git a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/resource.h b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/resource.h index 2cd9aea48fa..5cf7751f67e 100644 --- a/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/resource.h +++ b/tools/sdk/esp32s2/include/coap/libcoap/include/coap3/resource.h @@ -83,7 +83,8 @@ typedef void (*coap_method_handler_t) * variable of coap_str_const_t has to point to constant text, or point to data * within the allocated coap_str_const_t parameter. * - * @param uri_path The string URI path of the new resource. + * @param uri_path The string URI path of the new resource. The leading '/' is + * not normally required - e.g. just "full/path/for/resource". * @param flags Flags for memory management (in particular release of * memory). Possible values:@n * diff --git a/tools/sdk/esp32s2/include/coap/port/include/coap/coap.h b/tools/sdk/esp32s2/include/coap/port/include/coap/coap.h new file mode 100644 index 00000000000..f048ca85714 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/port/include/coap/coap.h @@ -0,0 +1,50 @@ +/* Modify head file implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * define operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_H_ +#define _COAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libcoap.h" + +#include "address.h" +#include "async.h" +#include "bits.h" +#include "block.h" +#include "coap_dtls.h" +#include "coap_event.h" +#include "coap_io.h" +#include "coap_time.h" +#include "coap_debug.h" +#include "encode.h" +#include "mem.h" +#include "net.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "resource.h" +#include "str.h" +#include "subscribe.h" +#include "uri.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COAP_H_ */ diff --git a/tools/sdk/esp32s2/include/coap/port/include/coap/coap_dtls.h b/tools/sdk/esp32s2/include/coap/port/include/coap/coap_dtls.h new file mode 100644 index 00000000000..2dd0e88d2e5 --- /dev/null +++ b/tools/sdk/esp32s2/include/coap/port/include/coap/coap_dtls.h @@ -0,0 +1,631 @@ +/* + * coap_dtls.h -- (Datagram) Transport Layer Support for libcoap + * + * Copyright (C) 2016 Olaf Bergmann + * Copyright (C) 2017 Jean-Claude Michelou + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_DTLS_H_ +#define COAP_DTLS_H_ + +#include "coap_time.h" +#include "str.h" + +struct coap_context_t; +struct coap_session_t; +struct coap_dtls_pki_t; + +/** + * @defgroup dtls DTLS Support + * API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Check whether DTLS is available. + * + * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. + */ +int coap_dtls_is_supported(void); + +/** + * Check whether TLS is available. + * + * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. + */ +int coap_tls_is_supported(void); + +typedef enum coap_tls_library_t { + COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */ + COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */ + COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */ + COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */ + COAP_TLS_LIBRARY_MBEDTLS, /**< Using MbedTLS library */ +} coap_tls_library_t; + +/** + * The structure used for returning the underlying (D)TLS library + * information. + */ +typedef struct coap_tls_version_t { + uint64_t version; /**< (D)TLS runtime Library Version */ + coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */ + uint64_t built_version; /**< (D)TLS Built against Library Version */ +} coap_tls_version_t; + +/** + * Determine the type and version of the underlying (D)TLS library. + * + * @return The version and type of library libcoap was compiled against. + */ +coap_tls_version_t *coap_get_tls_library_version(void); + +/** + * Additional Security setup handler that can be set up by + * coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to do some additional checks/changes/updates. + * + * @param tls_session The security session definition - e.g. SSL * for OpenSSL. + * NULL if server call-back. + * This will be dependent on the underlying TLS library - + * see coap_get_tls_library_version() + * @param setup_data A structure containing setup data originally passed into + * coap_context_set_pki() or coap_new_client_session_pki(). + * + * @return @c 1 if successful, else @c 0. + */ +typedef int (*coap_dtls_security_setup_t)(void* tls_session, + struct coap_dtls_pki_t *setup_data); + +/** + * CN Validation call-back that can be set up by coap_context_set_pki(). + * Invoked when libcoap has done the validation checks at the TLS level, + * but the application needs to check that the CN is allowed. + * CN is the SubjectAltName in the cert, if not present, then the leftmost + * Common Name (CN) component of the subject name. + * + * @param cn The determined CN from the certificate + * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate + * @param asn1_length The ASN.1 length + * @param coap_session The CoAP session associated with the certificate update + * @param depth Depth in cert chain. If 0, then client cert, else a CA + * @param validated TLS layer can find no issues if 1 + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->cn_call_back_arg + * + * @return @c 1 if accepted, else @c 0 if to be rejected. + */ +typedef int (*coap_dtls_cn_callback_t)(const char *cn, + const uint8_t *asn1_public_cert, + size_t asn1_length, + struct coap_session_t *coap_session, + unsigned depth, + int validated, + void *arg); + +/** + * The enum used for determining the provided PKI ASN.1 (DER) Private Key + * formats. + */ +typedef enum coap_asn1_privatekey_type_t { + COAP_ASN1_PKEY_NONE, /**< NONE */ + COAP_ASN1_PKEY_RSA, /**< RSA type */ + COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ + COAP_ASN1_PKEY_DSA, /**< DSA type */ + COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ + COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ + COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ + COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ + COAP_ASN1_PKEY_DH, /**< DH type */ + COAP_ASN1_PKEY_DHX, /**< DHX type */ + COAP_ASN1_PKEY_EC, /**< EC type */ + COAP_ASN1_PKEY_HMAC, /**< HMAC type */ + COAP_ASN1_PKEY_CMAC, /**< CMAC type */ + COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ + COAP_ASN1_PKEY_HKDF /**< HKDF type */ +} coap_asn1_privatekey_type_t; + +/** + * The enum used for determining the PKI key formats. + */ +typedef enum coap_pki_key_t { + COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */ + COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ + COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */ +} coap_pki_key_t; + +/** + * The structure that holds the PKI PEM definitions. + */ +typedef struct coap_pki_key_pem_t { + const char *ca_file; /**< File location of Common CA in PEM format */ + const char *public_cert; /**< File location of Public Cert in PEM format */ + const char *private_key; /**< File location of Private Key in PEM format */ +} coap_pki_key_pem_t; + +/** + * The structure that holds the PKI PEM buffer definitions. + */ +typedef struct coap_pki_key_pem_buf_t { + const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */ + const uint8_t *public_cert; /**< PEM buffer Public Cert */ + const uint8_t *private_key; /**< PEM buffer Private Key */ + size_t ca_cert_len; /**< PEM buffer CA Cert length */ + size_t public_cert_len; /**< PEM buffer Public Cert length */ + size_t private_key_len; /**< PEM buffer Private Key length */ +} coap_pki_key_pem_buf_t; + +/** + * The structure that holds the PKI ASN.1 (DER) definitions. + */ +typedef struct coap_pki_key_asn1_t { + const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ + const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ + const uint8_t *private_key; /**< ASN1 (DER) Private Key */ + size_t ca_cert_len; /**< ASN1 CA Cert length */ + size_t public_cert_len; /**< ASN1 Public Cert length */ + size_t private_key_len; /**< ASN1 Private Key length */ + coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ +} coap_pki_key_asn1_t; + +/** + * The structure that holds the PKI key information. + */ +typedef struct coap_dtls_key_t { + coap_pki_key_t key_type; /**< key format type */ + union { + coap_pki_key_pem_t pem; /**< for PEM file keys */ + coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */ + coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) file keys */ + } key; +} coap_dtls_key_t; + +/** + * Server Name Indication (SNI) Validation call-back that can be set up by + * coap_context_set_pki(). + * Invoked if the SNI is not previously seen and prior to sending a certificate + * set back to the client so that the appropriate certificate set can be used + * based on the requesting SNI. + * + * @param sni The requested SNI + * @param arg The same as was passed into coap_context_set_pki() + * in setup_data->sni_call_back_arg + * + * @return New set of certificates to use, or @c NULL if SNI is to be rejected. + */ +typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, + void* arg); + + +#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ + +/** + * The structure used for defining the PKI setup data to be used. + */ +typedef struct coap_dtls_pki_t { + uint8_t version; /** Set to 1 to support this version of the struct */ + + /* Options to enable different TLS functionality in libcoap */ + uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ + uint8_t require_peer_cert; /**< 1 if peer cert is required */ + uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ + uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ + uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ + uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ + uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ + uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ + uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ + uint8_t allow_bad_md_hash; /**< 1 if expired certs are allowed */ + uint8_t allow_short_rsa_length; /**< 1 if expired certs are allowed */ + uint8_t reserved[4]; /**< Reserved - must be set to 0 for + future compatibility */ + /* Size of 4 chosen to align to next + * parameter, so if newly defined option + * it can use one of the reserverd slot so + * no need to change + * COAP_DTLS_PKI_SETUP_VERSION and just + * decrement the reserved[] count. + */ + + /** CN check call-back function. + * If not NULL, is called when the TLS connection has passed the configured + * TLS options above for the application to verify if the CN is valid. + */ + coap_dtls_cn_callback_t validate_cn_call_back; + void *cn_call_back_arg; /**< Passed in to the CN call-back function */ + + /** SNI check call-back function. + * If not @p NULL, called if the SNI is not previously seen and prior to + * sending a certificate set back to the client so that the appropriate + * certificate set can be used based on the requesting SNI. + */ + coap_dtls_sni_callback_t validate_sni_call_back; + void *sni_call_back_arg; /**< Passed in to the sni call-back function */ + + /** Additional Security call-back handler that is invoked when libcoap has + * done the standerd, defined validation checks at the TLS level, + * If not @p NULL, called from within the TLS Client Hello connection + * setup. + */ + coap_dtls_security_setup_t additional_tls_setup_call_back; + + char* client_sni; /**< If not NULL, SNI to use in client TLS setup. + Owned by the client app and must remain valid + during the call to coap_new_client_session_pki() */ + + coap_dtls_key_t pki_key; /**< PKI key definition */ +} coap_dtls_pki_t; + +/** @} */ + +/** + * @defgroup dtls_internal DTLS Support (Internal) + * Internal API functions for interfacing with DTLS libraries. + * @{ + */ + +/** + * Creates a new DTLS context for the given @p coap_context. This function + * returns a pointer to a new DTLS context object or @c NULL on error. + * + * Internal function. + * + * @param coap_context The CoAP context where the DTLS object shall be used. + * + * @return A DTLS context object or @c NULL on error. + */ +void * +coap_dtls_new_context(struct coap_context_t *coap_context); + +typedef enum coap_dtls_role_t { + COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ + COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ +} coap_dtls_role_t; + +/** + * Set the DTLS context's default PSK information. + * This does the PSK specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param identity_hint The default PSK server identity hint sent to a client. + * Required parameter. If @p NULL, will be set to "". + * Empty string is a valid hint. + * This parameter is ignored if COAP_DTLS_ROLE_CLIENT + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_psk(struct coap_context_t *coap_context, + const char *identity_hint, + coap_dtls_role_t role); + +/** + * Set the DTLS context's default server PKI information. + * This does the PKI specifics following coap_dtls_new_context(). + * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the + * TLS library's context (from which sessions are derived). + * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the + * TLS library's session. + * + * Internal function. + * + * @param coap_context The CoAP context. + * @param setup_data Setup information defining how PKI is to be setup. + * Required parameter. If @p NULL, PKI will not be + * set up. + * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki(struct coap_context_t *coap_context, + coap_dtls_pki_t *setup_data, + coap_dtls_role_t role); + +/** + * Set the dtls context's default Root CA information for a client or server. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * @param ca_file If not @p NULL, is the full path name of a PEM encoded + * file containing all the Root CAs to be used. + * @param ca_dir If not @p NULL, points to a directory containing PEM + * encoded files containing all the Root CAs to be used. + * + * @return @c 1 if successful, else @c 0. + */ + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, + const char *ca_file, + const char *ca_dir); + +/** + * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have + * been called. + * + * Internal function. + * + * @param coap_context The current coap_context_t object. + * + * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. + */ + +int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); + +/** + * Releases the storage allocated for @p dtls_context. + * + * Internal function. + * + * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). + */ +void coap_dtls_free_context(void *dtls_context); + +/** + * Create a new client-side session. This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_dtls_new_client_session(struct coap_session_t *coap_session); + +/** + * Create a new DTLS server-side session. + * Called after coap_dtls_hello() has returned @c 1, signalling that a validated + * HELLO was received from a client. + * This should send a HELLO to the server. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the DTLS session. + */ +void *coap_dtls_new_server_session(struct coap_session_t *coap_session); + +/** + * Terminates the DTLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_free_session(struct coap_session_t *coap_session); + +/** + * Notify of a change in the CoAP session's MTU, for example after + * a PMTU update. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); + +/** + * Send data to a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this would be blocking, @c -1 if there is an error or the + * number of cleartext bytes sent. + */ +int coap_dtls_send(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Check if timeout is handled per CoAP session or per CoAP context. + * + * Internal function. + * + * @return @c 1 of timeout and retransmit is per context, @c 0 if it is + * per session. + */ +int coap_dtls_is_context_timeout(void); + +/** + * Do all pending retransmits and get next timeout + * + * Internal function. + * + * @param dtls_context The DTLS context. + * + * @return @c 0 if no event is pending or date of the next retransmit. + */ +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); + +/** + * Get next timeout for this session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param now The current time in ticks. + * + * @return @c 0 If no event is pending or ticks time of the next retransmit. + */ +coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, + coap_tick_t now); + +/** + * Handle a DTLS timeout expiration. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_dtls_handle_timeout(struct coap_session_t *coap_session); + +/** + * Handling incoming data from a DTLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return Result of coap_handle_dgram on the decrypted CoAP PDU + * or @c -1 for error. + */ +int coap_dtls_receive(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Handling client HELLO messages from a new candiate peer. + * Note that session->tls is empty. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Encrypted datagram. + * @param data_len Encrypted datagram size. + * + * @return @c 0 if a cookie verification message has been sent, @c 1 if the + * HELLO contains a valid cookie and a server session should be created, + * @c -1 if the message is invalid. + */ +int coap_dtls_hello(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * Internal function. + * + * @param coap_session The CoAP session. + * + * @return Maximum number of bytes added by DTLS layer. + */ +unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); + +/** + * Create a new TLS client-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. +*/ +void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); + +/** + * Create a TLS new server-side session. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param connected Updated with whether the connection is connected yet or not. + * @c 0 is not connected, @c 1 is connected. + * + * @return Opaque handle to underlying TLS library object containing security + * parameters for the session. + */ +void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); + +/** + * Terminates the TLS session (may send an ALERT if necessary) then frees the + * underlying TLS library object containing security parameters for the session. + * + * Internal function. + * + * @param coap_session The CoAP session. + */ +void coap_tls_free_session( struct coap_session_t *coap_session ); + +/** + * Send data to a TLS peer, with implicit flush. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Number of bytes to send. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes sent. + */ +ssize_t coap_tls_write(struct coap_session_t *coap_session, + const uint8_t *data, + size_t data_len + ); + +/** + * Read some data from a TLS peer. + * + * Internal function. + * + * @param coap_session The CoAP session. + * @param data Pointer to data. + * @param data_len Maximum number of bytes to read. + * + * @return @c 0 if this should be retried, @c -1 if there is an error + * or the number of cleartext bytes read. + */ +ssize_t coap_tls_read(struct coap_session_t *coap_session, + uint8_t *data, + size_t data_len + ); + +/** + * Initialize the underlying (D)TLS Library layer. + * + * Internal function. + * + */ +void coap_dtls_startup(void); + +/** @} */ + +/** + * @ingroup logging + * Sets the (D)TLS logging level to the specified @p level. + * Note: coap_log_level() will influence output if at a specified level. + * + * @param level The logging level to use - LOG_* + */ +void coap_dtls_set_log_level(int level); + +/** + * @ingroup logging + * Get the current (D)TLS logging. + * + * @return The current log level (one of LOG_*). + */ +int coap_dtls_get_log_level(void); + + +#endif /* COAP_DTLS_H */ diff --git a/tools/sdk/esp32s2/include/config/sdkconfig.h b/tools/sdk/esp32s2/include/config/sdkconfig.h index 48660a5006f..91629e94a54 100644 --- a/tools/sdk/esp32s2/include/config/sdkconfig.h +++ b/tools/sdk/esp32s2/include/config/sdkconfig.h @@ -30,6 +30,7 @@ #define CONFIG_BOOT_ROM_LOG_ALWAYS_ON 1 #define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 #define CONFIG_ESPTOOLPY_FLASHMODE_QIO 1 +#define CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR 1 #define CONFIG_ESPTOOLPY_FLASHMODE "dio" #define CONFIG_ESPTOOLPY_FLASHFREQ_80M 1 #define CONFIG_ESPTOOLPY_FLASHFREQ "80m" @@ -85,7 +86,7 @@ #define CONFIG_TINYUSB_VENDOR_RX_BUFSIZE 64 #define CONFIG_TINYUSB_VENDOR_TX_BUFSIZE 64 #define CONFIG_TINYUSB_DEBUG_LEVEL 0 -#define CONFIG_COMPILER_OPTIMIZATION_PERF 1 +#define CONFIG_COMPILER_OPTIMIZATION_SIZE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1 #define CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL 2 #define CONFIG_COMPILER_HIDE_PATHS_MACROS 1 @@ -117,9 +118,9 @@ #define CONFIG_SPIRAM_SPEED_80M 1 #define CONFIG_SPIRAM 1 #define CONFIG_SPIRAM_USE_MALLOC 1 -#define CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL 4096 +#define CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL 8192 #define CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP 1 -#define CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL 32768 +#define CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL 0 #define CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM 0x0 #define CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM 0 #define CONFIG_ESP32S2_DEBUG_OCDAWARE 1 @@ -278,7 +279,7 @@ #define CONFIG_LWIP_LOCAL_HOSTNAME "espressif" #define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1 #define CONFIG_LWIP_TIMERS_ONDEMAND 1 -#define CONFIG_LWIP_MAX_SOCKETS 10 +#define CONFIG_LWIP_MAX_SOCKETS 16 #define CONFIG_LWIP_SO_REUSE 1 #define CONFIG_LWIP_SO_REUSE_RXTOALL 1 #define CONFIG_LWIP_SO_RCVBUF 1 @@ -289,6 +290,7 @@ #define CONFIG_LWIP_GARP_TMR_INTERVAL 60 #define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 #define CONFIG_LWIP_DHCP_RESTORE_LAST_IP 1 +#define CONFIG_LWIP_DHCP_OPTIONS_LEN 68 #define CONFIG_LWIP_DHCPS 1 #define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 #define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 @@ -316,14 +318,8 @@ #define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 2560 #define CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 1 #define CONFIG_LWIP_TCPIP_TASK_AFFINITY 0x0 -#define CONFIG_LWIP_PPP_SUPPORT 1 -#define CONFIG_LWIP_PPP_ENABLE_IPV6 1 #define CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE 3 #define CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS 5 -#define CONFIG_LWIP_PPP_PAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_CHAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_MSCHAP_SUPPORT 1 -#define CONFIG_LWIP_PPP_MPPE_SUPPORT 1 #define CONFIG_LWIP_ICMP 1 #define CONFIG_LWIP_MAX_RAW_PCBS 16 #define CONFIG_LWIP_SNTP_MAX_SERVERS 1 @@ -401,6 +397,7 @@ #define CONFIG_MDNS_TASK_AFFINITY 0x0 #define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 2000 #define CONFIG_MDNS_TIMER_PERIOD_MS 100 +#define CONFIG_MDNS_MULTIPLE_INSTANCE 1 #define CONFIG_MQTT_PROTOCOL_311 1 #define CONFIG_MQTT_TRANSPORT_SSL 1 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 @@ -487,6 +484,7 @@ /* List of deprecated options */ #define CONFIG_ADC2_DISABLE_DAC CONFIG_ADC_DISABLE_DAC +#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT #define CONFIG_CXX_EXCEPTIONS CONFIG_COMPILER_CXX_EXCEPTIONS #define CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE @@ -529,13 +527,9 @@ #define CONFIG_MB_TIMER_PORT_ENABLED CONFIG_FMB_TIMER_PORT_ENABLED #define CONFIG_MONITOR_BAUD_115200B CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B #define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE +#define CONFIG_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE #define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR #define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR -#define CONFIG_PPP_CHAP_SUPPORT CONFIG_LWIP_PPP_CHAP_SUPPORT -#define CONFIG_PPP_MPPE_SUPPORT CONFIG_LWIP_PPP_MPPE_SUPPORT -#define CONFIG_PPP_MSCHAP_SUPPORT CONFIG_LWIP_PPP_MSCHAP_SUPPORT -#define CONFIG_PPP_PAP_SUPPORT CONFIG_LWIP_PPP_PAP_SUPPORT -#define CONFIG_PPP_SUPPORT CONFIG_LWIP_PPP_SUPPORT #define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN #define CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS #define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS @@ -575,5 +569,5 @@ #define CONFIG_USB_MSC_BUFSIZE CONFIG_TINYUSB_MSC_BUFSIZE #define CONFIG_USB_MSC_ENABLED CONFIG_TINYUSB_MSC_ENABLED #define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS -#define CONFIG_ARDUINO_IDF_COMMIT "3e370c4296" +#define CONFIG_ARDUINO_IDF_COMMIT "b86fe0c66c" #define CONFIG_ARDUINO_IDF_BRANCH "master" diff --git a/tools/sdk/esp32s2/include/driver/esp32s2/include/driver/touch_sensor.h b/tools/sdk/esp32s2/include/driver/esp32s2/include/driver/touch_sensor.h index 178e3b1a9dd..d90a56e992c 100644 --- a/tools/sdk/esp32s2/include/driver/esp32s2/include/driver/touch_sensor.h +++ b/tools/sdk/esp32s2/include/driver/esp32s2/include/driver/touch_sensor.h @@ -293,7 +293,7 @@ esp_err_t touch_pad_reset_benchmark(touch_pad_t touch_num); * @return * - ESP_OK Success */ -esp_err_t touch_pad_filter_set_config(touch_filter_config_t *filter_info); +esp_err_t touch_pad_filter_set_config(const touch_filter_config_t *filter_info); /** * @brief get parameter of touch sensor filter and detection algorithm. @@ -331,7 +331,7 @@ esp_err_t touch_pad_filter_disable(void); * @return * - ESP_OK Success */ -esp_err_t touch_pad_denoise_set_config(touch_pad_denoise_t *denoise); +esp_err_t touch_pad_denoise_set_config(const touch_pad_denoise_t *denoise); /** * @brief get parameter of denoise pad (TOUCH_PAD_NUM0). @@ -380,7 +380,7 @@ esp_err_t touch_pad_denoise_read_data(uint32_t *data); * @return * - ESP_OK Success */ -esp_err_t touch_pad_waterproof_set_config(touch_pad_waterproof_t *waterproof); +esp_err_t touch_pad_waterproof_set_config(const touch_pad_waterproof_t *waterproof); /** * @brief get parameter of waterproof function. diff --git a/tools/sdk/esp32s2/include/driver/include/driver/rmt.h b/tools/sdk/esp32s2/include/driver/include/driver/rmt.h index a7e2aad5f24..bc07954a080 100644 --- a/tools/sdk/esp32s2/include/driver/include/driver/rmt.h +++ b/tools/sdk/esp32s2/include/driver/include/driver/rmt.h @@ -856,16 +856,35 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT /** - * @brief Set loop count for RMT TX channel + * @brief Set loop count threshold value for RMT TX channel + * + * When tx loop count reaches this value, an ISR callback will notify user * * @param channel RMT channel - * @param count loop count + * @param count loop count, 1 ~ 1023 * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count); -#endif + +/** + * @brief Enable or disable the feature that when loop count reaches the threshold, RMT will stop transmitting. + * + * - When the loop auto-stop feature is enabled will halt RMT transmission after the loop count reaches a certain threshold + * - When disabled, the RMT transmission continue indefinitely until halted by the users + * + * @note The auto-stop feature is implemented in hardware on particular targets (i.e. those with SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP defined). + * Otherwise, the auto-stop feature is implemented in software via the interrupt. + * + * @param channel RMT channel + * @param en enable bit + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + */ +esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en); +#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT /** * @brief Reset RMT TX/RX memory index. diff --git a/tools/sdk/esp32s2/include/esp-face/face_detection/include/fd_forward.h b/tools/sdk/esp32s2/include/esp-face/face_detection/include/fd_forward.h new file mode 100644 index 00000000000..878c8c481c8 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/face_detection/include/fd_forward.h @@ -0,0 +1,103 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "mtmn.h" + + typedef enum + { + FAST = 0, /*!< fast resize type */ + NORMAL = 1, /*!< normal resize type */ + } mtmn_resize_type; + + typedef struct + { + float score; /*!< score threshold for filter candidates by score */ + float nms; /*!< nms threshold for nms process */ + int candidate_number; /*!< candidate number limitation for each net */ + } threshold_config_t; + + typedef struct + { + int w; /*!< net width */ + int h; /*!< net height */ + threshold_config_t threshold; /*!< threshold of net */ + } net_config_t; + + typedef struct + { + float min_face; /*!< The minimum size of a detectable face */ + float pyramid; /*!< The scale of the gradient scaling for the input images */ + int pyramid_times; /*!< The pyramid resizing times */ + threshold_config_t p_threshold; /*!< The thresholds for P-Net. For details, see the definition of threshold_config_t */ + threshold_config_t r_threshold; /*!< The thresholds for R-Net. For details, see the definition of threshold_config_t */ + threshold_config_t o_threshold; /*!< The thresholds for O-Net. For details, see the definition of threshold_config_t */ + mtmn_resize_type type; /*!< The image resize type. 'pyramid' will lose efficacy, when 'type'==FAST. */ + } mtmn_config_t; + + /** + * @brief Get the initial MTMN model configuration + * + * @return mtmn_config_t MTMN configuration + */ + static inline mtmn_config_t mtmn_init_config() + { + mtmn_config_t mtmn_config; + mtmn_config.type = FAST; + mtmn_config.min_face = 80; + mtmn_config.pyramid = 0.707; + mtmn_config.pyramid_times = 4; + mtmn_config.p_threshold.score = 0.6; + mtmn_config.p_threshold.nms = 0.7; + mtmn_config.p_threshold.candidate_number = 20; + mtmn_config.r_threshold.score = 0.7; + mtmn_config.r_threshold.nms = 0.7; + mtmn_config.r_threshold.candidate_number = 10; + mtmn_config.o_threshold.score = 0.7; + mtmn_config.o_threshold.nms = 0.7; + mtmn_config.o_threshold.candidate_number = 1; + + return mtmn_config; + } + + /** + * @brief Do MTMN face detection, return box and landmark infomation. + * + * @param image_matrix Image matrix, rgb888 format + * @param config Configuration of MTMN i.e. score threshold, nms threshold, candidate number threshold, pyramid, min face size + * @return box_array_t* A list of boxes and score. + */ + box_array_t *face_detect(dl_matrix3du_t *image_matrix, + mtmn_config_t *config); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_flash.h b/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_flash.h new file mode 100644 index 00000000000..5da0ddcc182 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_flash.h @@ -0,0 +1,82 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "fr_forward.h" + +#define FR_FLASH_TYPE 32 +#define FR_FLASH_SUBTYPE 32 +#define FR_FLASH_PARTITION_NAME "fr" +#define FR_FLASH_INFO_FLAG 12138 + + /** + * @brief Produce face id according to the input aligned face, and save it to dest_id and flash. + * + * @param l Face id list + * @param aligned_face An aligned face + * @return -2 Flash partition not found + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face_id_to_flash(face_id_list *l, + dl_matrix3du_t *aligned_face); + + /** + * @brief Produce face id according to the input aligned face, and save the id-name pairs to dest_id and flash. + * + * @param l Face id list + * @param new_id An aligned face + * @param name name corresponding to face id + * @return -2 Flash partition not found + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face_id_to_flash_with_name(face_id_name_list *l, + dl_matrix3d_t *new_id, + char *name); + /** + * @brief Read the enrolled face IDs from the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t read_face_id_from_flash(face_id_list *l); + + /** + * @brief Read the enrolled face IDs and their corresponding names from the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t read_face_id_from_flash_with_name(face_id_name_list *l); + + /** + * @brief Delete the enrolled face IDs in the flash. + * + * @param l Face id list + * @return int8_t The number of IDs remaining in flash + */ + int8_t delete_face_id_in_flash(face_id_list *l); + + /** + * @brief Delete the enrolled face ID corresponding to the name in the flash. + * + * @param l Face id list + * @param name The name that needs to be deleted + * @return int8_t The number of IDs remaining in flash + */ + int8_t delete_face_id_in_flash_with_name(face_id_name_list *l, char *name); + + /** + * @brief Delete all the enrolled face IDs and names paris in the flash. + * + * @param l Face id list + */ + void delete_face_all_in_flash_with_name(face_id_name_list *l); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_forward.h b/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_forward.h new file mode 100644 index 00000000000..32c55168eb6 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/face_recognition/include/fr_forward.h @@ -0,0 +1,194 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "frmn.h" + +#define FACE_WIDTH 56 +#define FACE_HEIGHT 56 +#define FACE_ID_SIZE 512 +#define FACE_REC_THRESHOLD 0.55 + +#define LEFT_EYE_X 0 +#define LEFT_EYE_Y 1 +#define RIGHT_EYE_X 6 +#define RIGHT_EYE_Y 7 +#define NOSE_X 4 +#define NOSE_Y 5 +#define LEFT_MOUTH_X 2 +#define LEFT_MOUTH_Y 3 +#define RIGHT_MOUTH_X 8 +#define RIGHT_MOUTH_Y 9 + +#define EYE_DIST_SET 16.5f +#define NOSE_EYE_RATIO_THRES_MIN 0.49f +#define NOSE_EYE_RATIO_THRES_MAX 2.04f + + +#define ENROLL_NAME_LEN 16 + typedef struct tag_face_id_node + { + struct tag_face_id_node *next; /*!< next face id node */ + char id_name[ENROLL_NAME_LEN]; /*!< name corresponding to the face id */ + dl_matrix3d_t *id_vec; /*!< face id */ + } face_id_node; + + typedef struct + { + face_id_node *head; /*!< head pointer of the id list */ + face_id_node *tail; /*!< tail pointer of the id list */ + uint8_t count; /*!< number of enrolled ids */ + uint8_t confirm_times; /*!< images needed for one enrolling */ + } face_id_name_list; + + typedef struct + { + uint8_t head; /*!< head index of the id list */ + uint8_t tail; /*!< tail index of the id list */ + uint8_t count; /*!< number of enrolled ids */ + uint8_t size; /*!< max len of id list */ + uint8_t confirm_times; /*!< images needed for one enrolling */ + dl_matrix3d_t **id_list; /*!< stores face id vectors */ + } face_id_list; + + /** + * @brief Initialize face id list. + * + * @param l Face id list + * @param size Size of list, one list contains one vector + * @param confirm_times Enroll times for one id + */ + void face_id_init(face_id_list *l, uint8_t size, uint8_t confirm_times); + + /** + * @brief Initialize face id list with name. + * + * @param l Face id list + * @param size Size of list, one list contains one vector + * @param confirm_times Enroll times for one id + */ + void face_id_name_init(face_id_name_list *l, uint8_t size, uint8_t confirm_times); + + /** + * @brief Alloc memory for aligned face. + * + * @return dl_matrix3du_t* Size: 1xFACE_WIDTHxFACE_HEIGHTx3 + */ + dl_matrix3du_t *aligned_face_alloc(); + + /**@{*/ + /** + * @brief Align detected face to average face according to landmark. + * + * @param onet_boxes Output of MTMN with box and landmark + * @param src Image matrix, rgb888 format + * @param dest Output image + * @return ESP_OK Input face is good for recognition + * @return ESP_FAIL Input face is not good for recognition + */ + int8_t align_face_rot(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest); + + int8_t align_face_sim(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest); + + inline int8_t align_face(box_array_t *onet_boxes, + dl_matrix3du_t *src, + dl_matrix3du_t *dest) + { + return align_face_sim(onet_boxes, src, dest); + } + /**@}*/ + + /** + * @brief Run the face recognition model to get the face feature + * + * @param aligned_face A 56x56x3 image, the variable need to do align_face first + * @return face_id A 512 vector, size (1, 1, 1, 512) + */ + dl_matrix3d_t *get_face_id(dl_matrix3du_t *aligned_face); + + /** + * @brief Add src_id to dest_id + * + * @param dest_id Face id after accumulation + * @param src_id Face id to be added + */ + void add_face_id(dl_matrix3d_t *dest_id, + dl_matrix3d_t *src_id); + + /** + * @brief Match face with the id_list, and return matched_id. + * + * @param l An ID list + * @param algined_face An aligned face + * @return int8_t Matched face id + */ + int8_t recognize_face(face_id_list *l, dl_matrix3du_t *algined_face); + + /** + * @brief Match face id with the id_list, and return matched face id node. + * + * @param l + * @param face_id + * @return face_id_node* + */ + face_id_node *recognize_face_with_name(face_id_name_list *l, dl_matrix3d_t *face_id); + + /** + * @brief Produce face id according to the input aligned face, and save it to dest_id. + * + * @param l Face id list + * @param aligned_face An aligned face + * @param enroll_confirm_times Confirm times for each face id enrollment + * @return -1 Wrong input enroll_confirm_times + * @return 0 Enrollment finish + * @return >=1 The left piece of aligned faces should be input + */ + int8_t enroll_face(face_id_list *l, dl_matrix3du_t *aligned_face); + + /** + * @brief Produce face id according to the input aligned face, and save the id-name pairs to dest_id + * + * @param l Face id list with name + * @param new_id A face id that need to be enrolled + * @param name name corresponding to the face id + * @return int8_t The left piece of aligned faces should be input + */ + int8_t enroll_face_with_name(face_id_name_list *l, + dl_matrix3d_t *new_id, + char *name); + + /** + * @brief Delete the enrolled face IDs + * + * @param l Face id list + * @return uint8_t The number of IDs remaining in face id list + */ + uint8_t delete_face(face_id_list *l); + + /** + * @brief Delete the enrolled face IDs and associated names + * + * @param l Face id list + * @param name The name that needs to be deleted + * @return int8_t The number of IDs remaining in face id list + */ + int8_t delete_face_with_name(face_id_name_list *l, char *name); + + /** + * @brief Delete all the enrolled face IDs and names paris + * + * @param l Face id list with names + */ + void delete_face_all_with_name(face_id_name_list *l); +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/image_util/include/esp_image.hpp b/tools/sdk/esp32s2/include/esp-face/image_util/include/esp_image.hpp new file mode 100644 index 00000000000..f5f924d6b6a --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/image_util/include/esp_image.hpp @@ -0,0 +1,344 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +typedef enum +{ + IMAGE_RESIZE_BILINEAR = 0, /* +class Image +{ +public: + /** + * @brief Convert a RGB565 pixel to RGB888 + * + * @param input Pixel value in RGB565 + * @param output Pixel value in RGB888 + */ + static inline void pixel_rgb565_to_rgb888(uint16_t input, T *output) + { + output[2] = (input & 0x1F00) >> 5; //blue + output[1] = ((input & 0x7) << 5) | ((input & 0xE000) >> 11); //green + output[0] = input & 0xF8; //red + }; + + /** + * @brief Resize a RGB565 image to a RGB88 image + * + * @param dst_image The destination image + * @param y_start The start y index of where resized image located + * @param y_end The end y index of where resized image located + * @param x_start The start x index of where resized image located + * @param x_end The end x index of where resized image located + * @param channel The channel number of image + * @param src_image The source image + * @param src_h The height of source image + * @param src_w The width of source image + * @param dst_w The width of destination image + * @param shift_left The bit number of left shifting + * @param type The resize type + */ + static void resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + + /** + * @brief Resize a RGB888 image to a RGB88 image + * + * @param dst_image The destination image + * @param y_start The start y index of where resized image located + * @param y_end The end y index of where resized image located + * @param x_start The start x index of where resized image located + * @param x_end The end x index of where resized image located + * @param channel The channel number of image + * @param src_image The source image + * @param src_h The height of source image + * @param src_w The width of source image + * @param dst_w The width of destination image + * @param shift_left The bit number of left shifting + * @param type The resize type + */ + static void resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + // static void resize_to_rgb565(uint16_t *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); + // static void resize_to_rgb565(uint16_t *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type); +}; + +template +void Image::resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint16_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type) +{ + assert(channel == 3); + float scale_y = (float)src_h / (y_end - y_start); + float scale_x = (float)src_w / (x_end - x_start); + int temp[13]; + + switch (type) + { + case IMAGE_RESIZE_BILINEAR: + for (size_t y = y_start; y < y_end; y++) + { + float ratio_y[2]; + ratio_y[0] = (float)((y + 0.5) * scale_y - 0.5); // y + int src_y = (int)ratio_y[0]; // y1 + ratio_y[0] -= src_y; // y - y1 + + if (src_y < 0) + { + ratio_y[0] = 0; + src_y = 0; + } + if (src_y > src_h - 2) + { + ratio_y[0] = 0; + src_y = src_h - 2; + } + ratio_y[1] = 1 - ratio_y[0]; // y2 - y + + int _dst_i = y * dst_w; + + int _src_row_0 = src_y * src_w; + int _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + float ratio_x[2]; + ratio_x[0] = (float)((x + 0.5) * scale_x - 0.5); // x + int src_x = (int)ratio_x[0]; // x1 + ratio_x[0] -= src_x; // x - x1 + + if (src_x < 0) + { + ratio_x[0] = 0; + src_x = 0; + } + if (src_x > src_w - 2) + { + ratio_x[0] = 0; + src_x = src_w - 2; + } + ratio_x[1] = 1 - ratio_x[0]; // x2 - x + + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = _src_row_0 + src_x; + int src_row_1 = _src_row_1 + src_x; + + Image::pixel_rgb565_to_rgb888(src_image[src_row_0], temp); + Image::pixel_rgb565_to_rgb888(src_image[src_row_0 + 1], temp + 3); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1], temp + 6); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1 + 1], temp + 9); + + for (int c = 0; c < channel; c++) + { + temp[12] = round(temp[c] * ratio_x[1] * ratio_y[1] + temp[channel + c] * ratio_x[0] * ratio_y[1] + temp[channel + channel + c] * ratio_x[1] * ratio_y[0] + src_image[channel + channel + channel + c] * ratio_x[0] * ratio_y[0]); + dst_image[dst_i + c] = (shift_left > 0) ? (temp[12] << shift_left) : (temp[12] >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_MEAN: + shift_left -= 2; + for (int y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + + float _src_row_0 = rintf(y * scale_y) * src_w; + float _src_row_1 = _src_row_0 + src_w; + + for (int x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + rintf(x * scale_x)); + int src_row_1 = (_src_row_1 + rintf(x * scale_x)); + + Image::pixel_rgb565_to_rgb888(src_image[src_row_0], temp); + Image::pixel_rgb565_to_rgb888(src_image[src_row_0 + 1], temp + 3); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1], temp + 6); + Image::pixel_rgb565_to_rgb888(src_image[src_row_1 + 1], temp + 9); + + dst_image[dst_i] = (shift_left > 0) ? ((temp[0] + temp[3] + temp[6] + temp[9]) << shift_left) : ((temp[0] + temp[3] + temp[6] + temp[9]) >> -shift_left); + dst_image[dst_i + 1] = (shift_left > 0) ? ((temp[1] + temp[4] + temp[7] + temp[10]) << shift_left) : ((temp[1] + temp[4] + temp[7] + temp[10]) >> -shift_left); + dst_image[dst_i + 2] = (shift_left > 0) ? ((temp[2] + temp[5] + temp[8] + temp[11]) << shift_left) : ((temp[1] + temp[4] + temp[7] + temp[10]) >> -shift_left); + } + } + + break; + + case IMAGE_RESIZE_NEAREST: + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + float _src_i = rintf(y * scale_y) * src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + int src_i = _src_i + rintf(x * scale_x); + + Image::pixel_rgb565_to_rgb888(src_image[src_i], temp); + + dst_image[dst_i] = (shift_left > 0) ? (temp[0] << shift_left) : (temp[0] >> -shift_left); + dst_image[dst_i + 1] = (shift_left > 0) ? (temp[1] << shift_left) : (temp[1] >> -shift_left); + dst_image[dst_i + 2] = (shift_left > 0) ? (temp[2] << shift_left) : (temp[2] >> -shift_left); + } + } + break; + + default: + break; + } +} + +template +void Image::resize_to_rgb888(T *dst_image, int y_start, int y_end, int x_start, int x_end, int channel, uint8_t *src_image, int src_h, int src_w, int dst_w, int shift_left, image_resize_t type) +{ + float scale_y = (float)src_h / (y_end - y_start); + float scale_x = (float)src_w / (x_end - x_start); + int temp; + + switch (type) + { + case IMAGE_RESIZE_BILINEAR: + for (size_t y = y_start; y < y_end; y++) + { + float ratio_y[2]; + ratio_y[0] = (float)((y + 0.5) * scale_y - 0.5); // y + int src_y = (int)ratio_y[0]; // y1 + ratio_y[0] -= src_y; // y - y1 + + if (src_y < 0) + { + ratio_y[0] = 0; + src_y = 0; + } + if (src_y > src_h - 2) + { + ratio_y[0] = 0; + src_y = src_h - 2; + } + ratio_y[1] = 1 - ratio_y[0]; // y2 - y + + int _dst_i = y * dst_w; + + int _src_row_0 = src_y * src_w; + int _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + float ratio_x[2]; + ratio_x[0] = (float)((x + 0.5) * scale_x - 0.5); // x + int src_x = (int)ratio_x[0]; // x1 + ratio_x[0] -= src_x; // x - x1 + + if (src_x < 0) + { + ratio_x[0] = 0; + src_x = 0; + } + if (src_x > src_w - 2) + { + ratio_x[0] = 0; + src_x = src_w - 2; + } + ratio_x[1] = 1 - ratio_x[0]; // x2 - x + + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + src_x) * channel; + int src_row_1 = (_src_row_1 + src_x) * channel; + + for (int c = 0; c < channel; c++) + { + temp = round(src_image[src_row_0 + c] * ratio_x[1] * ratio_y[1] + src_image[src_row_0 + channel + c] * ratio_x[0] * ratio_y[1] + src_image[src_row_1 + c] * ratio_x[1] * ratio_y[0] + src_image[src_row_1 + channel + c] * ratio_x[0] * ratio_y[0]); + dst_image[dst_i + c] = (shift_left > 0) ? (temp << shift_left) : (temp >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_MEAN: + shift_left -= 2; + + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + + float _src_row_0 = rintf(y * scale_y) * src_w; + float _src_row_1 = _src_row_0 + src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + + int src_row_0 = (_src_row_0 + rintf(x * scale_x)) * channel; + int src_row_1 = (_src_row_1 + rintf(x * scale_x)) * channel; + + for (size_t c = 0; c < channel; c++) + { + temp = (int)src_image[src_row_0 + c] + (int)src_image[src_row_0 + channel + c] + (int)src_image[src_row_1 + c] + (int)src_image[src_row_1 + channel + c]; + dst_image[dst_i + c] = (shift_left > 0) ? (temp << shift_left) : (temp >> -shift_left); + } + } + } + break; + + case IMAGE_RESIZE_NEAREST: + for (size_t y = y_start; y < y_end; y++) + { + int _dst_i = y * dst_w; + float _src_i = rintf(y * scale_y) * src_w; + + for (size_t x = x_start; x < x_end; x++) + { + int dst_i = (_dst_i + x) * channel; + int src_i = (_src_i + rintf(x * scale_x)) * channel; + + for (size_t c = 0; c < channel; c++) + { + dst_image[dst_i + c] = (shift_left > 0) ? ((T)src_image[src_i + c] << shift_left) : ((T)src_image[src_i + c] >> -shift_left); + } + } + } + break; + + default: + break; + } +} \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/image_util/include/image_util.h b/tools/sdk/esp32s2/include/esp-face/image_util/include/image_util.h new file mode 100644 index 00000000000..f997b34154b --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/image_util/include/image_util.h @@ -0,0 +1,548 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include +#include "mtmn.h" + +#define LANDMARKS_NUM (10) + +#define MAX_VALID_COUNT_PER_IMAGE (30) + +#define DL_IMAGE_MIN(A, B) ((A) < (B) ? (A) : (B)) +#define DL_IMAGE_MAX(A, B) ((A) < (B) ? (B) : (A)) + +#define RGB565_MASK_RED 0xF800 +#define RGB565_MASK_GREEN 0x07E0 +#define RGB565_MASK_BLUE 0x001F + + typedef enum + { + BINARY, /*!< binary */ + } en_threshold_mode; + + typedef struct + { + fptp_t landmark_p[LANDMARKS_NUM]; /*!< landmark struct */ + } landmark_t; + + typedef struct + { + fptp_t box_p[4]; /*!< box struct */ + } box_t; + + typedef struct tag_box_list + { + uint8_t *category; /*!< The category of the corresponding box */ + fptp_t *score; /*!< The confidence score of the class corresponding to the box */ + box_t *box; /*!< Anchor boxes or predicted boxes*/ + landmark_t *landmark; /*!< The landmarks corresponding to the box */ + int len; /*!< The num of the boxes */ + } box_array_t; + + typedef struct tag_image_box + { + struct tag_image_box *next; /*!< Next image_box_t */ + uint8_t category; + fptp_t score; /*!< The confidence score of the class corresponding to the box */ + box_t box; /*!< Anchor boxes or predicted boxes */ + box_t offset; /*!< The predicted anchor-based offset */ + landmark_t landmark; /*!< The landmarks corresponding to the box */ + } image_box_t; + + typedef struct tag_image_list + { + image_box_t *head; /*!< The current head of the image_list */ + image_box_t *origin_head; /*!< The original head of the image_list */ + int len; /*!< Length of the image_list */ + } image_list_t; + + /** + * @brief Get the width and height of the box. + * + * @param box Input box + * @param w Resulting width of the box + * @param h Resulting height of the box + */ + static inline void image_get_width_and_height(box_t *box, float *w, float *h) + { + *w = box->box_p[2] - box->box_p[0] + 1; + *h = box->box_p[3] - box->box_p[1] + 1; + } + + /** + * @brief Get the area of the box. + * + * @param box Input box + * @param area Resulting area of the box + */ + static inline void image_get_area(box_t *box, float *area) + { + float w, h; + image_get_width_and_height(box, &w, &h); + *area = w * h; + } + + /** + * @brief calibrate the boxes by offset + * + * @param image_list Input boxes + * @param image_height Height of the original image + * @param image_width Width of the original image + */ + static inline void image_calibrate_by_offset(image_list_t *image_list, int image_height, int image_width) + { + for (image_box_t *head = image_list->head; head; head = head->next) + { + float w, h; + image_get_width_and_height(&(head->box), &w, &h); + head->box.box_p[0] = DL_IMAGE_MAX(0, head->box.box_p[0] + head->offset.box_p[0] * w); + head->box.box_p[1] = DL_IMAGE_MAX(0, head->box.box_p[1] + head->offset.box_p[1] * w); + head->box.box_p[2] += head->offset.box_p[2] * w; + if (head->box.box_p[2] > image_width) + { + head->box.box_p[2] = image_width - 1; + head->box.box_p[0] = image_width - w; + } + head->box.box_p[3] += head->offset.box_p[3] * h; + if (head->box.box_p[3] > image_height) + { + head->box.box_p[3] = image_height - 1; + head->box.box_p[1] = image_height - h; + } + } + } + + /** + * @brief calibrate the landmarks + * + * @param image_list Input landmarks + */ + static inline void image_landmark_calibrate(image_list_t *image_list) + { + for (image_box_t *head = image_list->head; head; head = head->next) + { + float w, h; + image_get_width_and_height(&(head->box), &w, &h); + head->landmark.landmark_p[0] = head->box.box_p[0] + head->landmark.landmark_p[0] * w; + head->landmark.landmark_p[1] = head->box.box_p[1] + head->landmark.landmark_p[1] * h; + + head->landmark.landmark_p[2] = head->box.box_p[0] + head->landmark.landmark_p[2] * w; + head->landmark.landmark_p[3] = head->box.box_p[1] + head->landmark.landmark_p[3] * h; + + head->landmark.landmark_p[4] = head->box.box_p[0] + head->landmark.landmark_p[4] * w; + head->landmark.landmark_p[5] = head->box.box_p[1] + head->landmark.landmark_p[5] * h; + + head->landmark.landmark_p[6] = head->box.box_p[0] + head->landmark.landmark_p[6] * w; + head->landmark.landmark_p[7] = head->box.box_p[1] + head->landmark.landmark_p[7] * h; + + head->landmark.landmark_p[8] = head->box.box_p[0] + head->landmark.landmark_p[8] * w; + head->landmark.landmark_p[9] = head->box.box_p[1] + head->landmark.landmark_p[9] * h; + } + } + + /** + * @brief Convert a rectangular box into a square box + * + * @param boxes Input box + * @param width Width of the orignal image + * @param height height of the orignal image + */ + static inline void image_rect2sqr(box_array_t *boxes, int width, int height) + { + for (int i = 0; i < boxes->len; i++) + { + box_t *box = &(boxes->box[i]); + + int x1 = round(box->box_p[0]); + int y1 = round(box->box_p[1]); + int x2 = round(box->box_p[2]); + int y2 = round(box->box_p[3]); + + int w = x2 - x1 + 1; + int h = y2 - y1 + 1; + int l = DL_IMAGE_MAX(w, h); + + box->box_p[0] = DL_IMAGE_MAX(round(DL_IMAGE_MAX(0, x1) + 0.5 * (w - l)), 0); + box->box_p[1] = DL_IMAGE_MAX(round(DL_IMAGE_MAX(0, y1) + 0.5 * (h - l)), 0); + + box->box_p[2] = box->box_p[0] + l - 1; + if (box->box_p[2] > width) + { + box->box_p[2] = width - 1; + box->box_p[0] = width - l; + } + box->box_p[3] = box->box_p[1] + l - 1; + if (box->box_p[3] > height) + { + box->box_p[3] = height - 1; + box->box_p[1] = height - l; + } + } + } + + /**@{*/ + /** + * @brief Convert RGB565 image to RGB888 image + * + * @param in Input RGB565 image + * @param dst Resulting RGB888 image + */ + static inline void rgb565_to_888(uint16_t in, uint8_t *dst) + { /*{{{*/ + in = (in & 0xFF) << 8 | (in & 0xFF00) >> 8; + dst[2] = (in & RGB565_MASK_BLUE) << 3; // blue + dst[1] = (in & RGB565_MASK_GREEN) >> 3; // green + dst[0] = (in & RGB565_MASK_RED) >> 8; // red + + // dst[0] = (in & 0x1F00) >> 5; + // dst[1] = ((in & 0x7) << 5) | ((in & 0xE000) >> 11); + // dst[2] = in & 0xF8; + } /*}}}*/ + + static inline void rgb565_to_888_q16(uint16_t in, int16_t *dst) + { /*{{{*/ + in = (in & 0xFF) << 8 | (in & 0xFF00) >> 8; + dst[2] = (in & RGB565_MASK_BLUE) << 3; // blue + dst[1] = (in & RGB565_MASK_GREEN) >> 3; // green + dst[0] = (in & RGB565_MASK_RED) >> 8; // red + + // dst[0] = (in & 0x1F00) >> 5; + // dst[1] = ((in & 0x7) << 5) | ((in & 0xE000) >> 11); + // dst[2] = in & 0xF8; + } /*}}}*/ + /**@}*/ + + /** + * @brief Convert RGB888 image to RGB565 image + * + * @param in Resulting RGB565 image + * @param r The red channel of the Input RGB888 image + * @param g The green channel of the Input RGB888 image + * @param b The blue channel of the Input RGB888 image + */ + static inline void rgb888_to_565(uint16_t *in, uint8_t r, uint8_t g, uint8_t b) + { /*{{{*/ + uint16_t rgb565 = 0; + rgb565 = ((r >> 3) << 11); + rgb565 |= ((g >> 2) << 5); + rgb565 |= (b >> 3); + rgb565 = (rgb565 & 0xFF) << 8 | (rgb565 & 0xFF00) >> 8; + *in = rgb565; + } /*}}}*/ + + /** + * @brief Filter out the resulting boxes whose confidence score is lower than the threshold and convert the boxes to the actual boxes on the original image.((x, y, w, h) -> (x1, y1, x2, y2)) + * + * @param score Confidence score of the boxes + * @param offset The predicted anchor-based offset + * @param landmark The landmarks corresponding to the box + * @param width Height of the original image + * @param height Width of the original image + * @param anchor_number Anchor number of the detection output feature map + * @param anchors_size The anchor size + * @param score_threshold Threshold of the confidence score + * @param stride + * @param resized_height_scale + * @param resized_width_scale + * @param do_regression + * @return image_list_t* + */ + image_list_t *image_get_valid_boxes(fptp_t *score, + fptp_t *offset, + fptp_t *landmark, + int width, + int height, + int anchor_number, + int *anchors_size, + fptp_t score_threshold, + int stride, + fptp_t resized_height_scale, + fptp_t resized_width_scale, + bool do_regression); + /** + * @brief Sort the resulting box lists by their confidence score. + * + * @param image_sorted_list The sorted box list. + * @param insert_list The box list that have not been sorted. + */ + void image_sort_insert_by_score(image_list_t *image_sorted_list, const image_list_t *insert_list); + + /** + * @brief Run NMS algorithm + * + * @param image_list The input boxes list + * @param nms_threshold NMS threshold + * @param same_area The flag of boxes with same area + */ + void image_nms_process(image_list_t *image_list, fptp_t nms_threshold, int same_area); + + /** + * @brief Resize an image to half size + * + * @param dimage The output image + * @param dw Width of the output image + * @param dh Height of the output image + * @param dc Channel of the output image + * @param simage Source image + * @param sw Width of the source image + * @param sc Channel of the source image + */ + void image_zoom_in_twice(uint8_t *dimage, + int dw, + int dh, + int dc, + uint8_t *simage, + int sw, + int sc); + + /** + * @brief Resize the image in RGB888 format via bilinear interpolation + * + * @param dst_image The output image + * @param src_image Source image + * @param dst_w Width of the output image + * @param dst_h Height of the output image + * @param dst_c Channel of the output image + * @param src_w Width of the source image + * @param src_h Height of the source image + */ + void image_resize_linear(uint8_t *dst_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h); + + /** + * @brief Crop, rotate and zoom the image in RGB888 format, + * + * @param corp_image The output image + * @param src_image Source image + * @param rotate_angle Rotate angle + * @param ratio scaling ratio + * @param center Center of rotation + */ + void image_cropper(uint8_t *corp_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h, float rotate_angle, float ratio, float *center); + + /** + * @brief Convert the rgb565 image to the rgb888 image + * + * @param m The output rgb888 image + * @param bmp The input rgb565 image + * @param count Total pixels of the rgb565 image + */ + void image_rgb565_to_888(uint8_t *m, uint16_t *bmp, int count); + + /** + * @brief Convert the rgb888 image to the rgb565 image + * + * @param bmp The output rgb565 image + * @param m The input rgb888 image + * @param count Total pixels of the rgb565 image + */ + void image_rgb888_to_565(uint16_t *bmp, uint8_t *m, int count); + + /** + * @brief draw rectangle on the rgb565 image + * + * @param buf Input image + * @param boxes Rectangle Boxes + * @param width Width of the input image + */ + void draw_rectangle_rgb565(uint16_t *buf, box_array_t *boxes, int width); + + /** + * @brief draw rectangle on the rgb888 image + * + * @param buf Input image + * @param boxes Rectangle Boxes + * @param width Width of the input image + */ + void draw_rectangle_rgb888(uint8_t *buf, box_array_t *boxes, int width); + + /** + * @brief Get the pixel difference of two images + * + * @param dst The output pixel difference + * @param src1 Input image 1 + * @param src2 Input image 2 + * @param count Total pixels of the input image + */ + void image_abs_diff(uint8_t *dst, uint8_t *src1, uint8_t *src2, int count); + + /** + * @brief Binarize an image to 0 and value. + * + * @param dst The output image + * @param src Source image + * @param threshold Threshold of binarization + * @param value The value of binarization + * @param count Total pixels of the input image + * @param mode Threshold mode + */ + void image_threshold(uint8_t *dst, uint8_t *src, int threshold, int value, int count, en_threshold_mode mode); + + /** + * @brief Erode the image + * + * @param dst The output image + * @param src Source image + * @param src_w Width of the source image + * @param src_h Height of the source image + * @param src_c Channel of the source image + */ + void image_erode(uint8_t *dst, uint8_t *src, int src_w, int src_h, int src_c); + + typedef float matrixType; + typedef struct + { + int w; /*!< width */ + int h; /*!< height */ + matrixType **array; /*!< array */ + } Matrix; + + /** + * @brief Allocate a 2d matrix + * + * @param h Height of matrix + * @param w Width of matrix + * @return Matrix* 2d matrix + */ + Matrix *matrix_alloc(int h, int w); + + /** + * @brief Free a 2d matrix + * + * @param m 2d matrix + */ + void matrix_free(Matrix *m); + + /** + * @brief Get the similarity matrix of similarity transformation + * + * @param srcx Source x coordinates + * @param srcy Source y coordinates + * @param dstx Destination x coordinates + * @param dsty Destination y coordinates + * @param num The number of the coordinates + * @return Matrix* The resulting transformation matrix + */ + Matrix *get_similarity_matrix(float *srcx, float *srcy, float *dstx, float *dsty, int num); + + /** + * @brief Get the affine transformation matrix + * + * @param srcx Source x coordinates + * @param srcy Source y coordinates + * @param dstx Destination x coordinates + * @param dsty Destination y coordinates + * @return Matrix* The resulting transformation matrix + */ + Matrix *get_affine_transform(float *srcx, float *srcy, float *dstx, float *dsty); + + /** + * @brief Applies an affine transformation to an image + * + * @param img Input image + * @param crop Dst output image that has the size dsize and the same type as src + * @param M Affine transformation matrix + */ + void warp_affine(dl_matrix3du_t *img, dl_matrix3du_t *crop, Matrix *M); + + /** + * @brief Resize the image in RGB888 format via bilinear interpolation, and quantify the output image + * + * @param dst_image Quantized output image + * @param src_image Input image + * @param dst_w Width of the output image + * @param dst_h Height of the output image + * @param dst_c Channel of the output image + * @param src_w Width of the input image + * @param src_h Height of the input image + * @param shift Shift parameter of quantization. + */ + void image_resize_linear_q(qtp_t *dst_image, uint8_t *src_image, int dst_w, int dst_h, int dst_c, int src_w, int src_h, int shift); + + /** + * @brief Preprocess the input image of object detection model. The process is like this: resize -> normalize -> quantify + * + * @param image Input image, RGB888 format. + * @param input_w Width of the input image. + * @param input_h Height of the input image. + * @param target_size Target size of the model input image. + * @param exponent Exponent of the quantized model input image. + * @param process_mode Process mode. 0: resize with padding to keep height == width. 1: resize without padding, height != width. + * @return dl_matrix3dq_t* The resulting preprocessed image. + */ + dl_matrix3dq_t *image_resize_normalize_quantize(uint8_t *image, int input_w, int input_h, int target_size, int exponent, int process_mode); + + /** + * @brief Resize the image in RGB565 format via mean neighbour interpolation, and quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Width of the allocated output image memory. + * @param dc Channel of the allocated output image memory. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param tw Target width of the output image. + * @param th Target height of the output image. + * @param shift Shift parameter of quantization. + */ + void image_resize_shift_fast(qtp_t *dimage, uint16_t *simage, int dw, int dc, int sw, int sh, int tw, int th, int shift); + + /** + * @brief Resize the image in RGB565 format via nearest neighbour interpolation, and quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Width of the allocated output image memory. + * @param dc Channel of the allocated output image memory. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param tw Target width of the output image. + * @param th Target height of the output image. + * @param shift Shift parameter of quantization. + */ + void image_resize_nearest_shift(qtp_t *dimage, uint16_t *simage, int dw, int dc, int sw, int sh, int tw, int th, int shift); + + /** + * @brief Crop the image in RGB565 format and resize it to target size, then quantify the output image + * + * @param dimage Quantized output image. + * @param simage Input image. + * @param dw Target size of the output image. + * @param sw Width of the input image. + * @param sh Height of the input image. + * @param x1 The x coordinate of the upper left corner of the cropped area + * @param y1 The y coordinate of the upper left corner of the cropped area + * @param x2 The x coordinate of the lower right corner of the cropped area + * @param y2 The y coordinate of the lower right corner of the cropped area + * @param shift Shift parameter of quantization. + */ + void image_crop_shift_fast(qtp_t *dimage, uint16_t *simage, int dw, int sw, int sh, int x1, int y1, int x2, int y2, int shift); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/include/dl_define.hpp b/tools/sdk/esp32s2/include/esp-face/include/dl_define.hpp index 16eb0881562..7809768a5bc 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/dl_define.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/dl_define.hpp @@ -10,7 +10,7 @@ #define DL_LOG_LAYER_LATENCY 0 /**/ - PADDING_SAME, /**/ - PADDING_SAME_MXNET /**/ + PADDING_NOT_SET, + PADDING_VALID, /**/ + PADDING_SAME_BEGIN, /**/ + PADDING_SAME_END, /**/ } padding_type_t; -} // namespace dl \ No newline at end of file + + typedef enum + { + CONSTANT, + EDGE, + REFLECT, + SYMMETRIC, + } padding_mode_t; +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/image/dl_image.hpp b/tools/sdk/esp32s2/include/esp-face/include/image/dl_image.hpp index c7fecdc49cc..4a974df063a 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/image/dl_image.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/image/dl_image.hpp @@ -370,11 +370,70 @@ namespace dl */ uint32_t get_moving_point_number(uint8_t *f1, uint8_t *f2, const uint32_t height, const uint32_t width, const uint32_t stride, const uint32_t threshold = 5); - + /** + * @brief Apply an affine transformation to an image. + * + * @tparam T + * @param input the input image. + * @param output the output image. + * @param M_inv the inverse transformation matrix. + */ template void warp_affine(dl::Tensor *input, dl::Tensor *output, dl::math::Matrix *M_inv); + + /** + * @brief Apply an affine transformation to an image. + * + * @tparam T + * @param input the pointer of the input image. + * @param shape the shape of the input image. + * @param output the output image. + * @param M_inv the inverse transformation matrix. + */ template void warp_affine(uint16_t *input, std::vector shape, dl::Tensor *output, dl::math::Matrix *M_inv); + /** + * @brief Get the otsu thresh object. + * + * @param image the gray image. + * @return uint8_t the otsu thresh. + */ + uint8_t get_otsu_thresh(Tensor &image); + + /** + * @brief Convert RGB image to gray image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @return Tensor* output image in gray format + */ + Tensor *rgb2gray(Tensor &image, bool bgr = false); + + /** + * @brief Convert RGB image to LAB image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @param fast true: use the fast alogrithm, but the accuracy will be reduced + * false: do not use the fast alogrithm + * @return Tensor* output image in LAB foramt + */ + Tensor *rgb2lab(Tensor &image, bool bgr = false, bool fast = true); + + /** + * @brief Convert RGB image to HSV image + * + * @param image input image + * @param bgr true: the image is in BGR format + * false: the image is in RGB format + * @param fast true: use the fast alogrithm, but the accuracy will be reduced + * false: do not use the fast alogrithm + * @return Tensor* output image in HSV format + */ + Tensor *rgb2hsv(Tensor &image, bool bgr = false, bool fast = true); + } // namespace image } // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_add2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_add2d.hpp index f0c5964b3d1..c43282b42de 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_add2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_add2d.hpp @@ -25,7 +25,8 @@ namespace dl const int output_exponent; /**/ Tensor *output; /**/ bool inplace; /**/ + false: the output will store to a separate memory >*/ + std::vector output_shape; /**/ public: /** @@ -35,19 +36,21 @@ namespace dl * @param activation activation of add2d, if you don't specify anything, no activation is applied * @param name name of add2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Add2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), activation(activation), output_exponent(output_exponent), output(NULL) - { - this->inplace = inplace; - } + Add2D(const int output_exponent, const Activation *activation = NULL, const char *name = "Add2D", bool inplace = false) : Layer(name), + activation(activation), + output_exponent(output_exponent), + output(NULL), + inplace(inplace), + output_shape({}) {} /** * @brief Destroy the Add2D object */ ~Add2D() { - if((!this->inplace) && (this->output != NULL)) + if ((!this->inplace) && (this->output != NULL)) { delete this->output; } @@ -59,10 +62,12 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { @@ -78,6 +83,11 @@ namespace dl { this->output = &input0; } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -105,7 +115,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -116,6 +130,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::add2d(*this->output, input0, input1, this->activation, assign_core, this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "add2d"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp index f78b262beb9..8a9aaa8dfbe 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_avg_pool2d.hpp @@ -24,23 +24,26 @@ namespace dl std::vector filter_shape; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ + const padding_type_t padding_type; /**/ std::vector padding; /**/ - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new AvgPool2D object. * * @param output_exponent exponent of output * @param filter_shape filter shape in [filter_height, filter_width] - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer @@ -48,16 +51,23 @@ namespace dl AvgPool2D(const int output_exponent, const std::vector filter_shape, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter_shape(filter_shape), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type) + const char *name = "AvgPool2D") : Layer(name), + output_exponent(output_exponent), + filter_shape(filter_shape), + padding_type(padding_type), + padding(padding), + stride_y(stride_y), + stride_x(stride_x), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** @@ -66,7 +76,7 @@ namespace dl */ ~AvgPool2D() { - if(this->output != NULL) + if (this->output != NULL) { delete this->output; } @@ -76,20 +86,31 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); - std::vector output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + assert(input.shape.size() == 3); + + this->output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); - this->padding = nn::get_pad_size(output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); + } + this->output->free_element(); - } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } /** * @brief Get the output @@ -108,7 +129,6 @@ namespace dl * @param autoload_enable one of true or false, * - true: load input and output from PSRAM to CACHE automatically * - false: do not - * @param assign_core not effective yet * @return AvgPool2D result */ Tensor &call(Tensor &input, uint8_t autoload_enable = 0) @@ -116,7 +136,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_base.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_base.hpp index 5c7d28d52b1..b265b454538 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_base.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_base.hpp @@ -1,6 +1,7 @@ #pragma once #include "dl_tool.hpp" #include "dl_tool_cache.hpp" +#include namespace dl { diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_concat.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_concat.hpp new file mode 100644 index 00000000000..35ebe652e53 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_concat.hpp @@ -0,0 +1,139 @@ +#pragma once + +#include +#include + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" +#include "dl_nn_concat.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Concat(input1, input2, input3, ...). + * + * @tparam feature_t support all kinds of integer and float data type + */ + template + class Concat : Layer + { + private: + int output_exponent; /**/ + int axis; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Concat object. + * + * @param name name of layer + * @param axis The axis along which the Tensor will be concatenated. + */ + Concat(int axis, const char *name = "Concat") : Layer(name), axis(axis), output_shape({}) + { + this->output = new Tensor; + } + + /** + * @brief Destroy the Concat object + */ + ~Concat() + { + if (this->output != NULL) + { + delete this->output; + } + } + + /** + * @brief Collect inputs' channel and memory offset, called in Model.build(). + * + * @param args pointers of concatenated Tensor + * @param print_shape whether to print the output shape. + */ + void build(std::vector *> args, bool print_shape = false) + { + assert(args.size() > 1); + int shape_size = args[0]->shape.size(); + + if (this->axis < 0) + { + this->axis = shape_size + this->axis; + } + assert((this->axis < shape_size) && (this->axis > -1)); + + int output_shape_axis = args[0]->shape[this->axis]; + + for (int i = 1; i < args.size(); i++) + { + assert(shape_size == args[i]->shape.size()); + assert(args[i]->exponent == args[i - 1]->exponent); + output_shape_axis += args[i]->shape[this->axis]; + + for (int j = 0; j < shape_size; j++) + { + if (j != this->axis) + { + assert(args[i]->shape[j] == args[i - 1]->shape[j]); + } + } + } + + this->output_exponent = args[0]->exponent; + this->output_shape = args[0]->shape; + this->output_shape[this->axis] = output_shape_axis; + + this->output->set_shape(this->output_shape); + this->output->set_exponent(this->output_exponent); + this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Call Concat operation + * + * @param inputs the pointers of inputs + * @param free_inputs true: free the inputs after call + * false: do not free inputs + * @return Tensor& concat result + */ + Tensor &call(std::vector *> inputs, bool free_inputs = false) + { + DL_LOG_LAYER_LATENCY_INIT(); + + DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); + this->output->set_exponent(this->output_exponent); + DL_LOG_LAYER_LATENCY_END(this->name, "apply"); + + DL_LOG_LAYER_LATENCY_START(); + nn::concat(*this->output, inputs, this->axis, free_inputs); + DL_LOG_LAYER_LATENCY_END(this->name, "concat"); + return *this->output; + } + + /** + * @brief Get the output + * + * @return Tensor& Concat result + */ + Tensor &get_output() + { + return *this->output; + } + }; + } // namespace layer +} // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_conv2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_conv2d.hpp index a7c2229db09..038dd6cd79f 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_conv2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_conv2d.hpp @@ -13,8 +13,11 @@ namespace dl * @tparam feature_t supports int16_t and int8_t, * - int16_t: stands for operation in int16_t quantize * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization */ - template + template class Conv2D : public Layer { private: @@ -22,14 +25,14 @@ namespace dl const Filter *filter; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ - const Bias *bias; /**/ + const padding_type_t padding_type; /**/ + const Bias *bias; /**/ const Activation *activation; /**/ std::vector padding; /**/ - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Conv2D object. * @@ -37,33 +40,43 @@ namespace dl * @param filter filter of Conv2D * @param bias bias of Conv2D, if you don't specify anything, no bias is added * @param activation activation of Conv2D, if you don't specify anything, no activation is applied - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer */ Conv2D(const int output_exponent, const Filter *filter, - const Bias *bias = NULL, + const Bias *bias = NULL, const Activation *activation = NULL, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter(filter), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type), - bias(bias), - activation(activation) + const char *name = "Conv2D") : Layer(name), + output_exponent(output_exponent), + filter(filter), + stride_y(stride_y), + stride_x(stride_x), + padding_type(padding_type), + bias(bias), + activation(activation), + padding(padding), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** @@ -82,19 +95,30 @@ namespace dl * @brief Update output padding and input padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + assert(this->filter->shape.size() == 4); + assert(input.shape[2] == this->filter->shape[2]); - std::vector output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, true); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, true, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); this->output->free_element(); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); + } - this->padding = nn::get_pad_size(output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -122,7 +146,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -153,5 +181,6 @@ namespace dl dl::tool::cache::preload_func((uint32_t)(this->filter->element), size); } }; + } // namespace layer } // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp index 37475353209..30b2c2a6c77 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_depthwise_conv2d.hpp @@ -13,8 +13,11 @@ namespace dl * @tparam feature_t supports int16_t and int8_t, * - int16_t: stands for operation in int16_t quantize * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization */ - template + template class DepthwiseConv2D : public Layer { private: @@ -22,14 +25,14 @@ namespace dl const Filter *filter; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ - const Bias *bias; /**/ + const padding_type_t padding_type; /**/ + const Bias *bias; /**/ const Activation *activation; /**/ std::vector padding; /**/ Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new DepthwiseConv2D object. * @@ -37,40 +40,50 @@ namespace dl * @param filter filter of DepthwiseConv2D * @param bias bias of DepthwiseConv2D, if you don't specify anything, no bias is added * @param activation activation of DepthwiseConv2D, if you don't specify anything, no activation is applied - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input - * such that output has the same height/width dimension as the input - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input + * such that output has the same height/width dimension as the input, + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y - stride in height * @param stride_x - stride in width * @param name name of layer */ DepthwiseConv2D(const int output_exponent, const Filter *filter, - const Bias *bias = NULL, + const Bias *bias = NULL, const Activation *activation = NULL, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - output_exponent(output_exponent), - filter(filter), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type), - bias(bias), - activation(activation) + const char *name = "DepthwiseConv2D") : Layer(name), + output_exponent(output_exponent), + filter(filter), + stride_y(stride_y), + stride_x(stride_x), + padding_type(padding_type), + bias(bias), + activation(activation), + padding(padding), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** * @brief Destroy the DepthwiseConv2D object. * */ - ~DepthwiseConv2D() + ~DepthwiseConv2D() { if (this->output != NULL) { @@ -82,19 +95,31 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + assert(this->filter->shape.size() == 4); + assert(input.shape[2] == this->filter->shape[2]); - std::vector output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); - this->padding = nn::get_pad_size(output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, this->filter->shape_with_dilation, this->stride_y, this->stride_x, this->padding_type); + } this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -122,7 +147,12 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_expand_dims.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_expand_dims.hpp new file mode 100644 index 00000000000..a59bed183fb --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_expand_dims.hpp @@ -0,0 +1,128 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class ExpandDims : public Layer + { + private: + std::vector output_shape; /**/ + std::vector axis; /**/ + Tensor *output; /**/ + bool inplace; /**/ + + public: + int output_exponent; + + /** + * @brief Construct a new ExpandDims object + * + * @param axis position where the new axis is placed. + * @param name name of layer + * @param inplace true: the output will store to input + * false: the output will store to a separate memory + */ + ExpandDims(std::vector axis, const char *name = "ExpandDims", bool inplace = false) : Layer(name), + axis(axis), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the ExpandDims object + * + */ + ~ExpandDims() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape. + * + * @param input as an input. + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->expand_dims(this->axis); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + this->output->expand_dims(this->axis); + } + this->output_shape = this->output->shape; + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& ExpandDims result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief call ExpandDims opeartion + * + * @param input + * @return Tensor& ExpandDims result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->set_shape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "ExpandDims"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_shape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "ExpandDims"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_flatten.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_flatten.hpp new file mode 100644 index 00000000000..70ae483a07f --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_flatten.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Flatten : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + + public: + /** + * @brief Construct a new Flatten object + * + * @param name name of layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Flatten(const char *name = "Flatten", bool inplace = false) : Layer(name), inplace(inplace), output_shape({}) + {} + + /** + * @brief Destroy the Flatten object + * + */ + ~Flatten() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape. + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + this->output_shape = {input.get_size()}; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Flatten result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Flatten operation. + * + * @param input as an input + * @return Tensor& Flatten result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->flatten(); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "flatten"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->flatten(); + DL_LOG_LAYER_LATENCY_END(this->name, "flatten"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_fullyconnected.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_fullyconnected.hpp new file mode 100644 index 00000000000..afa7e5befba --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_fullyconnected.hpp @@ -0,0 +1,167 @@ +#pragma once + +#include "dl_nn_fully_connected.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Activation(FullyConnected(input, filter) + bias). + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + * @tparam bias_t supports int16_t and int8_t, must specify when using int8 per-channel quantization + * - int16_t: for int16 quantization and int8 per-channel quantization + * - int8_t: for int8 per-tensor quantization + */ + template + class FullyConnected : public Layer + { + private: + const int output_exponent; /**/ + const bool flatten; /**/ + const Filter *filter; /**/ + const Bias *bias; /**/ + const Activation *activation; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ + + public: + /** + * @brief Construct a new FullyConnected object. + * + * @param output_exponent exponent of output + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param name name of layer + */ + FullyConnected(const int output_exponent, + const Filter *filter, + const Bias *bias = NULL, + const Activation *activation = NULL, + const bool flatten = true, + const char *name = "FullyConnected") : Layer(name), + output_exponent(output_exponent), + flatten(flatten), + filter(filter), + bias(bias), + activation(activation), + output_shape({}) + { + this->output = new Tensor; + } + + /** + * @brief Destroy the FullyConnected object. + * + */ + ~FullyConnected() + { + if (this->output != NULL) + { + delete this->output; + } + } + + /** + * @brief Update output padding and input padding. + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + assert(this->filter->shape.size() == 4); + assert(this->filter->shape[0] == 1); + assert(this->filter->shape[1] == 1); + if (this->flatten) + { + assert(input.get_size() == this->filter->shape[2]); + this->output_shape = {this->filter->shape[3]}; + } + else + { + assert(input.shape.back() == this->filter->shape[2]); + this->output_shape = input.shape; + this->output_shape[this->output_shape.size() - 1] = this->filter->shape[3]; + } + this->output->set_shape(this->output_shape); + this->output->set_exponent(this->output_exponent); + this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& FullyConnected result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call FullyConnected operation + * + * @param input as an input. + * @param autoload_enable one of true or false, + * - true: load input and output from PSRAM to CACHE automatically + * - false: do not + * @param assign_core not effective yet + * @return FullyConnected result + */ + Tensor &call(Tensor &input, bool autoload_enable = false, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) + { + DL_LOG_LAYER_LATENCY_INIT(); + + DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); + this->output->set_exponent(this->output_exponent); + DL_LOG_LAYER_LATENCY_END(this->name, "apply"); + + if (autoload_enable) + { + dl::tool::cache::autoload_func((uint32_t)(this->output->element), this->output->get_size() * sizeof(feature_t), + (uint32_t)(input.element), input.get_size() * sizeof(feature_t)); + } + + DL_LOG_LAYER_LATENCY_START(); + nn::fully_connected(*this->output, input, *(this->filter), this->bias, this->activation, this->flatten, assign_core); + DL_LOG_LAYER_LATENCY_END(this->name, "fully_connected"); + return *this->output; + } + + /** + * @brief Preload the filter to Cache. + * NOTE: Call this layer's preload() before previous layer's call() such that filter could be loaded while previous layer is doing calculation. + */ + void preload() + { + size_t size = sizeof(feature_t); + int shape_size = this->filter->shape.size(); + for (int i = 0; i < shape_size; ++i) + { + size *= filter->shape[i]; + } + dl::tool::cache::preload_func((uint32_t)(this->filter->element), size); + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp index 044c5f61847..93f2d30ac89 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_avg_pool2d.hpp @@ -20,8 +20,9 @@ namespace dl class GlobalAveragePool2D : public Layer { private: - const int output_exponent; /**/ - Tensor *output; /**/ + const int output_exponent; /**/ + std::vector output_shape; /**/ + Tensor *output; /**/ public: /** * @brief Construct a new GlobalAveragePool2D object. @@ -29,8 +30,9 @@ namespace dl * @param output_exponent exponent of output * @param name name of layer */ - GlobalAveragePool2D(const int output_exponent, const char *name = NULL) : Layer(name), - output_exponent(output_exponent) + GlobalAveragePool2D(const int output_exponent, const char *name = "GlobalAveragePool2D") : Layer(name), + output_exponent(output_exponent), + output_shape({}) { this->output = new Tensor; @@ -52,17 +54,26 @@ namespace dl * @brief Update output shape. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; - this->output->set_shape(output_shape); + this->output_shape = output_shape; + this->output->set_shape(this->output_shape); this->output->set_exponent(this->output_exponent); this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -90,7 +101,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp index aa146823b78..f9b7f73ff8c 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_global_max_pool2d.hpp @@ -20,15 +20,15 @@ namespace dl class GlobalMaxPool2D : public Layer { private: - Tensor *output; /**/ + Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new GlobalMaxPool2D object. * * @param name name of layer */ - GlobalMaxPool2D(const char *name = NULL) : Layer(name) + GlobalMaxPool2D(const char *name = "GlobalMaxPool2D") : Layer(name), output_shape({}) { this->output = new Tensor; } @@ -49,17 +49,26 @@ namespace dl * @brief Update output shape and exponent. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); this->output->set_exponent(input.exponent); std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; - this->output->set_shape(output_shape); + this->output_shape = output_shape; + this->output->set_shape(this->output_shape); this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -87,7 +96,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_leakyrelu.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_leakyrelu.hpp index f18d9b1c522..a972e135006 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_leakyrelu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_leakyrelu.hpp @@ -2,7 +2,7 @@ #include "dl_constant.hpp" #include "dl_variable.hpp" -#include "dl_nn_LeakyReLU.hpp" +#include "dl_nn_leakyrelu.hpp" #include "dl_layer_base.hpp" namespace dl @@ -20,13 +20,13 @@ namespace dl class LeakyReLU : public Layer { private: - feature_t activation_alpha; /**/ - int activation_exponent; /**/ - Tensor *output; /**/ - bool inplace; /**/ + feature_t activation_alpha; /**/ + int activation_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new LeakyReLU object * @@ -34,9 +34,9 @@ namespace dl * @param activation_exponent exponent of quantized alpha * @param name name of leakyrelu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - LeakyReLU(const int activation_alpha, const int activation_exponent, const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + LeakyReLU(const int activation_alpha, const int activation_exponent, const char *name = "LeakyReLU", bool inplace = false) : Layer(name), output(NULL), output_shape({}) { this->activation_alpha = activation_alpha; this->activation_exponent = activation_exponent; @@ -47,7 +47,7 @@ namespace dl * @brief Destroy the LeakyReLU object * */ - ~LeakyReLU() + ~LeakyReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -59,24 +59,32 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; - } - this->output->set_shape(input.shape); + } + this->output->set_shape(this->output_shape); this->output->set_exponent(input.exponent); this->output->free_element(); } else { this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); } - } /** @@ -100,10 +108,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +126,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::leakyrelu(*this->output, input, this->activation_alpha, this->activation_exponent, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max2d.hpp index 8a775a2e0f0..93bc5899443 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max2d.hpp @@ -22,28 +22,28 @@ namespace dl class Max2D : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Max2D object. * * @param name name of max2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Max2D(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + Max2D(const char *name = "Max2D", bool inplace = false) : Layer(name), + output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Max2D object * */ - ~Max2D() + ~Max2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -58,24 +58,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); + this->output_shape = input0.shape; - if(!this->inplace) + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -100,10 +110,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +128,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::max2d(*this->output, input0, input1, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "max2d"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max_pool2d.hpp index f836a983b34..629aa87f515 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_max_pool2d.hpp @@ -23,44 +23,54 @@ namespace dl std::vector filter_shape; /**/ const int stride_y; /**/ const int stride_x; /**/ - const padding_type_t padding_type; /**/ + const padding_type_t padding_type; /**/ std::vector padding; /**/ Tensor *output; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new MaxPool2D object. * * @param filter_shape filter shape in [filter_height, filter_width] - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN or PADDING_NOT_SET, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style + * - PADDING_NOT_SET means padding with the specific "padding" value below. + * @param padding if padding_type is PADDING_NOT_SET, this value will be used as padding size. + * the shape must be 4, the value of each position is: [padding top, padding bottom, padding left, padding right] * @param stride_y stride in height * @param stride_x stride in width * @param name name of layer */ MaxPool2D(const std::vector filter_shape, const padding_type_t padding_type = PADDING_VALID, + std::vector padding = {}, const int stride_y = 1, const int stride_x = 1, - const char *name = NULL) : Layer(name), - filter_shape(filter_shape), - stride_y(stride_y), - stride_x(stride_x), - padding_type(padding_type) + const char *name = "MaxPool2D") : Layer(name), + filter_shape(filter_shape), + padding_type(padding_type), + padding(padding), + stride_y(stride_y), + stride_x(stride_x), + output_shape({}) { this->output = new Tensor; + if (this->padding_type == PADDING_NOT_SET) + { + assert(this->padding.size() == 4); + } } /** * @brief Destroy the MaxPool2D object. * */ - ~MaxPool2D() + ~MaxPool2D() { if (this->output != NULL) { @@ -72,18 +82,29 @@ namespace dl * @brief Update output shape and padding. * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { assert(input.shape[0] > 0); assert(input.shape[1] > 0); + assert(input.shape.size() == 3); + this->output->set_exponent(input.exponent); - std::vector output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - this->output->set_shape(output_shape); + this->output_shape = nn::get_output_shape(input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type, false, this->padding); + this->output->set_shape(this->output_shape); - this->padding = nn::get_pad_size(output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); - input.set_padding_size(this->padding); + if (this->padding_type != PADDING_NOT_SET) + { + this->padding = nn::get_pad_size(this->output_shape, input.shape, filter_shape, this->stride_y, this->stride_x, this->padding_type); + } this->output->free_element(); + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -111,7 +132,11 @@ namespace dl DL_LOG_LAYER_LATENCY_INIT(); DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_min2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_min2d.hpp index 71d39c9b285..e38fbf3d0d2 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_min2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_min2d.hpp @@ -22,28 +22,28 @@ namespace dl class Min2D : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ - public: - + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + public: /** * @brief Construct a new Min2D object * * @param name name of min2d * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Min2D(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) - { - this->inplace = inplace; - } + Min2D(const char *name = "Min2D", bool inplace = false) : Layer(name), + output(NULL), + inplace(inplace), + output_shape({}) {} /** * @brief Destroy the Min2D object * */ - ~Min2D() + ~Min2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -58,25 +58,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); + this->output_shape = input0.shape; - if(!this->inplace) + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->set_exponent(input0.exponent); this->output->free_element(); } else + { this->output = &input0; - + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -101,10 +110,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -115,6 +128,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::min2d(*this->output, input0, input1, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "min2d"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_mul2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_mul2d.hpp index 0edfc9a93f0..21bcca7a81e 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_mul2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_mul2d.hpp @@ -21,14 +21,13 @@ namespace dl class Mul2D : public Layer { private: - const int output_exponent; /**/ + const int output_exponent; /**/ const Activation *activation; /**/ - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - const int output_exponent; /**/ - /** * @brief Construct a new Mul2D object. * @@ -36,18 +35,24 @@ namespace dl * @param activation activation of Mul2D, if you don't specify anything, no activation is applied * @param name name of layer * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Mul2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), - output_exponent(output_exponent),activation(activation), output(NULL) + Mul2D(const int output_exponent, + const Activation *activation = NULL, + const char *name = "Mul2D", + bool inplace = false) : Layer(name), + output_exponent(output_exponent), + activation(activation), + output(NULL), + inplace(inplace), + output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Multiply2D object. */ - ~Mul2D() + ~Mul2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -61,24 +66,34 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } - + else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -106,7 +121,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -117,6 +136,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::mul2d(*this->output, input0, input1, this->activation, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "mul2d"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_prelu.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_prelu.hpp index 4781a669130..96168a783b1 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_prelu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_prelu.hpp @@ -24,9 +24,9 @@ namespace dl int activation_exponent; /**/ Tensor *output; /**/ bool inplace; /**/ + false: the output will store to a separate memory >*/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new PReLU object * @@ -34,20 +34,25 @@ namespace dl * @param activation_exponent exponent of quantized alpha elements * @param name name of prelu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - PReLU(const feature_t *activation_element, const int activation_exponent = 0, const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + PReLU(const feature_t *activation_element, + const int activation_exponent = 0, + const char *name = NULL, + bool inplace = "PReLU") : Layer(name), + activation_element(activation_element), + activation_exponent(activation_exponent), + output(NULL), + inplace(inplace), + output_shape({}) { - this->activation_element = activation_element; - this->activation_exponent = activation_exponent; - this->inplace = inplace; } /** * @brief Destroy the PReLU object * */ - ~PReLU() + ~PReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -59,23 +64,31 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(input.exponent); - this->output->set_shape(input.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else { this->output = &input; } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -99,11 +112,15 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } this->output->set_exponent(input.exponent); - this->output->apply_element(); + this->output->malloc_element(); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); DL_LOG_LAYER_LATENCY_START(); @@ -113,6 +130,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::prelu(*this->output, input, this->activation_element, this->activation_exponent, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_relu.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_relu.hpp index e70663b798c..7dd29d4a178 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_relu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_relu.hpp @@ -21,29 +21,28 @@ namespace dl class ReLU : public Layer { private: - Tensor *output; /**/ - bool inplace; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - - /** * @brief Construct a new ReLU object * * @param name name of relu * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - ReLU(const char *name = NULL, bool inplace = false) : Layer(name), output(NULL) + ReLU(const char *name = "ReLU", bool inplace = false) : Layer(name), + output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the ReLU object * */ - ~ReLU() + ~ReLU() { if ((!this->inplace) && (this->output != NULL)) { @@ -55,23 +54,31 @@ namespace dl * @brief Update output shape and exponent * * @param input as an input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input) + void build(Tensor &input, bool print_shape = false) { - if(!this->inplace) + this->output_shape = input.shape; + if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(input.exponent); - this->output->set_shape(input.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); } else { this->output = &input; } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -95,10 +102,14 @@ namespace dl { DL_LOG_LAYER_LATENCY_INIT(); - if(!this->inplace) + if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output->apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output->malloc_element(); this->output->set_exponent(input.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -109,6 +120,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::relu(*this->output, input, assign_core); DL_LOG_LAYER_LATENCY_END(this->name, "relu"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_reshape.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_reshape.hpp new file mode 100644 index 00000000000..3f2ed72b6e0 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_reshape.hpp @@ -0,0 +1,124 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief Reshape(input) + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + */ + template + class Reshape : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Reshape object + * + * @param shape the target shape + * @param name name of Reshape layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Reshape(std::vector shape, const char *name = "Reshape", bool inplace = false) : Layer(name), + output_shape(shape), inplace(inplace) + { + } + + /** + * @brief Destroy the Reshape object + * + */ + ~Reshape() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Reshape result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Reshape operation. + * + * @param input as an input + * @return Tensor& Reshape result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->reshape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "reshape"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->reshape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "reshape"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_squeeze.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_squeeze.hpp new file mode 100644 index 00000000000..cee92f22764 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_squeeze.hpp @@ -0,0 +1,127 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Squeeze : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + int axis; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Squeeze object + * + * @param axis the dim to to be remove. make sure the length of the dim is equal to 1. + * if axis == INT32_MAX, all the dims with length==1 will be removed. + * @param name name of Squeeze layer + * @param inplace true: the output will store to input0 + * false: the output will store to a separate memory + */ + Squeeze(int axis = INT32_MAX, const char *name = "Squeeze", bool inplace = false) : Layer(name), axis(axis), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the Squeeze object + * + */ + ~Squeeze() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(input.shape); + this->output->squeeze(this->axis); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(input.shape); + this->output->squeeze(this->axis); + } + this->output_shape = this->output->shape; + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Squeeze result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Squeeze operation. + * + * @param input as an input + * @return Tensor& Squeeze result + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->set_shape(this->output_shape); + this->output->copy_element(input, true); + DL_LOG_LAYER_LATENCY_END(this->name, "Squeeze"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_shape(this->output_shape); + DL_LOG_LAYER_LATENCY_END(this->name, "Squeeze"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_sub2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_sub2d.hpp index e3453c08b97..da03b4aad85 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_sub2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_sub2d.hpp @@ -21,13 +21,13 @@ namespace dl class Sub2D : public Layer { private: - const int output_exponent; /**/ - const Activation *activation; /**/ - Tensor *output; /**/ - bool inplace; /**/ + const int output_exponent; /**/ + const Activation *activation; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector output_shape; /**/ public: - /** * @brief Construct a new Sub2D object. * @@ -35,18 +35,17 @@ namespace dl * @param activation activation of Mul2D, if you don't specify anything, no activation is applied * @param name name of layer * @param inplace true: the output will store to input0 - * false: the output will store to a seperate memeory + * false: the output will store to a separate memory */ - Sub2D(const int output_exponent, const Activation *activation = NULL, const char *name = NULL, bool inplace = false) : Layer(name), - output_exponent(output_exponent), activation(activation), output(NULL) + Sub2D(const int output_exponent, const Activation *activation = NULL, const char *name = "Sub2D", bool inplace = false) : Layer(name), + output_exponent(output_exponent), activation(activation), output(NULL), inplace(inplace), output_shape({}) { - this->inplace = inplace; } /** * @brief Destroy the Sub2D object. */ - ~Sub2D() + ~Sub2D() { if ((!this->inplace) && (this->output != NULL)) { @@ -60,22 +59,32 @@ namespace dl * * @param input0 as one input * @param input1 as another input + * @param print_shape whether to print the output shape. */ - void build(Tensor &input0, Tensor &input1) + void build(Tensor &input0, Tensor &input1, bool print_shape = false) { assert(input0.is_same_shape(input1)); + this->output_shape = input0.shape; if (!this->inplace) { - if(this->output != NULL) + if (this->output != NULL) { this->output = new Tensor; } this->output->set_exponent(this->output_exponent); - this->output->set_shape(input0.shape); + this->output->set_shape(this->output_shape); this->output->free_element(); - } + } else + { this->output = &input0; + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } } /** @@ -103,7 +112,11 @@ namespace dl if (!this->inplace) { DL_LOG_LAYER_LATENCY_START(); - this->output.apply_element(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } + this->output.malloc_element(); this->output->set_exponent(input0.exponent); DL_LOG_LAYER_LATENCY_END(this->name, "apply"); @@ -114,6 +127,10 @@ namespace dl else { DL_LOG_LAYER_LATENCY_START(); + if (this->output->shape != this->output_shape) + { + this->output->set_shape(this->output_shape); + } nn::sub2d(this->output, input0, input1, this->activation, assign_core, this->output_exponent); DL_LOG_LAYER_LATENCY_END(this->name, "sub2d"); } diff --git a/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_transpose.hpp b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_transpose.hpp new file mode 100644 index 00000000000..d89ba8daed5 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/layer/dl_layer_transpose.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_tool.hpp" +#include "dl_layer_base.hpp" + +namespace dl +{ + namespace layer + { + /** + * @brief + * + * @tparam feature_t + */ + template + class Transpose : public Layer + { + private: + int output_exponent; /**/ + Tensor *output; /**/ + bool inplace; /**/ + std::vector perm; /**/ + std::vector output_shape; /**/ + public: + /** + * @brief Construct a new Transpose object + * + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @param name name of Transpose layer + * @param inplace true: the output will store to input + * false: the output will store to a separate memory + */ + Transpose(std::vector perm = {}, const char *name = "Transpose", bool inplace = false) : Layer(name), perm(perm), inplace(inplace), output_shape({}) + { + } + + /** + * @brief Destroy the Transpose object + * + */ + ~Transpose() + { + if ((!this->inplace) && (this->output != NULL)) + { + delete this->output; + } + } + + /** + * @brief Update output shape and exponent + * + * @param input as an input + * @param print_shape whether to print the output shape. + */ + void build(Tensor &input, bool print_shape = false) + { + this->output_exponent = input.exponent; + this->output_shape = input.shape; + for (int i = 0; i < this->perm.size(); i++) + { + this->output_shape[i] = input.shape[this->perm[i]]; + } + if (!this->inplace) + { + if (this->output != NULL) + { + this->output = new Tensor; + } + this->output->set_exponent(this->output_exponent); + this->output->set_shape(this->output_shape); + this->output->free_element(); + } + else + { + this->output = &input; + this->output->set_shape(this->output_shape); + } + + if (print_shape) + { + std::cout << this->name << " | "; + this->output->print_shape(); + } + } + + /** + * @brief Get the output + * + * @return Tensor& Transpose result + */ + Tensor &get_output() + { + return *this->output; + } + + /** + * @brief Call Transpose operation. + * + * @param input as an input. + * @return Tensor& Transpose result. + */ + Tensor &call(Tensor &input) + { + DL_LOG_LAYER_LATENCY_INIT(); + + if (!this->inplace) + { + DL_LOG_LAYER_LATENCY_START(); + this->output->set_exponent(input.exponent); + this->output->transpose(input, this->perm); + DL_LOG_LAYER_LATENCY_END(this->name, "transpose"); + } + else + { + DL_LOG_LAYER_LATENCY_START(); + this->output->transpose(this->perm); + DL_LOG_LAYER_LATENCY_END(this->name, "transpose"); + } + return *this->output; + } + }; + } // namespace layer +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/model_zoo/color_detector.hpp b/tools/sdk/esp32s2/include/esp-face/include/model_zoo/color_detector.hpp new file mode 100644 index 00000000000..063ab20b34a --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/model_zoo/color_detector.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "dl_image.hpp" + +typedef struct +{ + int area; /*!< Area of connected domains >*/ + std::vector center; /**/ + std::vector box; /**/ +} components_stats_t; + +class ColorDetector +{ +private: + std::vector> results; /*!< detection results >*/ + +public: + std::vector> color_thresh; /*!< threshold of colors, The threshold of each color is composed of 6 numbers >*/ + std::vector area_thresh; /*!< the area threshold of each color, + the area that is smaller than the threshold is filtered >*/ + bool bgr; /*!< true: the input image is in BGR format + false: the input image is in RGB format >*/ + + /** + * @brief get the color threshold of rectangular region in the image + * + * @param image the input image + * @param box the coordinates of the rectanglar region : [left_up_x, left_up_y, right_down_x, right_down_y] + * @return std::vector the threshold. + */ + std::vector cal_color_thresh(dl::Tensor &image, std::vector box); + + /** + * @brief detect the colors based on the color thresholds + * + * @param image the input image. + * @return std::vector>& detection result. + */ + std::vector> &detect(dl::Tensor &image); + + /** + * @brief Construct a new Color Detector object + * + * @param color_thresh threshold of colors, The threshold of each color is composed of 6 numbers + * @param area_thresh the area threshold of each color,the area that is smaller than the threshold is filtered + * @param bgr true: the input image is in BGR format + * false: the input image is in RGB format + */ + ColorDetector(std::vector> color_thresh, std::vector area_thresh, bool bgr = false) : color_thresh(color_thresh), area_thresh(area_thresh), bgr(bgr) + { + } + + /** + * @brief Destroy the Color Detector object + * + */ + ~ColorDetector() {} + + /** + * @brief Get the results object + * + * @return std::vector>& the detection result. + */ + std::vector> &get_results() + { + return this->results; + } +}; \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/include/model_zoo/face_recognition_tool.hpp b/tools/sdk/esp32s2/include/esp-face/include/model_zoo/face_recognition_tool.hpp index 12fe8a842a2..2226d32daf9 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/model_zoo/face_recognition_tool.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/model_zoo/face_recognition_tool.hpp @@ -92,7 +92,7 @@ namespace face_recognition_tool * @return dl::Tensor* */ template - dl::Tensor *transform_mfn_input(dl::Tensor &image, bool free_input = false, bool do_padding = true); + dl::Tensor *transform_mfn_input(dl::Tensor &image, bool free_input = false); /** * @brief transform the image to the input of a mfn model @@ -106,7 +106,7 @@ namespace face_recognition_tool * false: do not pad the result */ template - void transform_mfn_input(dl::Tensor &image, dl::Tensor &output, bool free_input = false, bool do_padding = true); + void transform_mfn_input(dl::Tensor &image, dl::Tensor &output, bool free_input = false); /** * @brief transform the mfn output embedding to a floating embedding diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn.hpp index 6dba8016f26..6c737c1d341 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn.hpp @@ -14,13 +14,13 @@ namespace dl * @param filter_shape filter shape with dilation * @param stride_y stride in height * @param stride_x stride in width - * @param pad_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET + * @param pad_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN * @param is_conv2d one of true or false, * - true: serve for Conv2D * - false: serve for other operations * @return std::vector */ - std::vector get_output_shape(const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t pad_type, const bool is_conv2d = false); + std::vector get_output_shape(const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t pad_type, const bool is_conv2d = false, std::vector padding = {}); /** * @brief Get the pad size object @@ -30,7 +30,7 @@ namespace dl * @param filter_shape filter shape with dilation * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN * @return padding size */ std::vector get_pad_size(const std::vector &output_shape, const std::vector &input_shape, const std::vector &filter_shape, const int stride_y, const int stride_x, const padding_type_t padding_type); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_add2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_add2d.hpp index d296be5350b..4d4daaaef05 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_add2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_add2d.hpp @@ -58,20 +58,20 @@ namespace dl */ template auto add2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp index 5b298d98c44..6e7db6ed0e0 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_avg_pool2d.hpp @@ -58,12 +58,12 @@ namespace dl * @param filter_shape filter_shape in [filter_height, filter_width] * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param assign_core not effective yet * @return avg_pool2d result */ @@ -81,19 +81,19 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter_shape, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); - input.set_padding_size(padding); + padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - avg_pool2d(output, input, input.padding, filter_shape, stride_y, stride_x, assign_core); + avg_pool2d(output, input, padding, filter_shape, stride_y, stride_x, assign_core); DL_LOG_NN_LATENCY_END("avg_pool2d"); return output; diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_concat.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_concat.hpp new file mode 100644 index 00000000000..73ed1aae905 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_concat.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include "dl_variable.hpp" +#include "dl_nn.hpp" + +namespace dl +{ + namespace nn + { + template + void concat(Tensor &output, std::vector *> &inputs, int axis, bool free_inputs = false); + + template + Tensor concat(std::vector *> &inputs, int axis, bool free_inputs = false) + { + DL_LOG_NN_LATENCY_INIT(); + + DL_LOG_NN_LATENCY_START(); + assert(inputs.size() > 1); + int shape_size = inputs[0]->shape.size(); + + if (axis < 0) + { + axis = shape_size + axis; + } + + assert((axis < shape_size) && (axis > -1)); + + int output_shape_axis = inputs[0]->shape[axis]; + + for (int i = 1; i < inputs.size(); i++) + { + assert(shape_size == inputs[i]->shape.size()); + assert(inputs[i]->exponent == inputs[i - 1]->exponent); + output_shape_axis += inputs[i]->shape[axis]; + + for (int j = 0; j < shape_size; j++) + { + if (j != axis) + { + assert(inputs[i]->shape[j] == inputs[i - 1]->shape[j]); + } + } + } + DL_LOG_NN_LATENCY_END("assert"); + + DL_LOG_NN_LATENCY_START(); + Tensor output; + std::vector output_shape = inputs[0]->shape; + output_shape[axis] = output_shape_axis; + output.set_shape(output_shape); + output.set_exponent(inputs[0]->exponent); + output.malloc_element(); + DL_LOG_NN_LATENCY_END("malloc"); + + DL_LOG_NN_LATENCY_START(); + concat(output, inputs, axis, free_inputs); + DL_LOG_NN_LATENCY_END("concat"); + return output; + } + } // namespace nn +} // namespace dl diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_conv2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_conv2d.hpp index 77e2c617d04..27ba0372730 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_conv2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_conv2d.hpp @@ -10,7 +10,6 @@ namespace dl { /** * @brief activation(conv2d(input, filter) + bias). - * NOTE: When padding_type is SAME, make sure padding is already added in input. * * @param output as an output * @param input as an input @@ -34,7 +33,6 @@ namespace dl /** * @brief activation(conv2d(input, filter) + bias). - * NOTE: When padding_type is SAME, make sure padding is already added in input. * * @param output as an output * @param input as an input @@ -56,6 +54,29 @@ namespace dl const Activation *const activation = NULL, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** + * @brief activation(conv2d(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param padding padding size needed in [top, bottom, left, right] of this operation + * @param filter filter of conv2d + * @param stride_y stride in height + * @param stride_x stride in width + * @param bias bias of conv2d, if you don't specify anything, no bias is added + * @param activation activation of conv2d, if you don't specify anything, no activation is applied + * @param assign_core not effective yet + */ + void conv2d(Tensor &output, + Tensor &input, + std::vector &padding, + const Filter &filter, + const int stride_y, + const int stride_x, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** * @brief activation(conv2d(input, filter) + bias). * @@ -67,25 +88,25 @@ namespace dl * @param filter Filter of conv2d * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param bias bias of conv2d, if you don't specify anything, no bias is added * @param activation activation of conv2d, if you don't specify anything, no activation is applied * @param assign_core not effective yet * @return conv2d result */ - template + template Tensor conv2d(const int output_exponent, Tensor &input, const Filter &filter, const int stride_y, const int stride_x, const padding_type_t padding_type, - const Bias *bias, + const Bias *bias, const Activation *activation, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) { @@ -94,20 +115,19 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type, true); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - conv2d(output, input, input.padding, filter, stride_y, stride_x, bias, activation, assign_core); + conv2d(output, input, padding, filter, stride_y, stride_x, bias, activation, assign_core); DL_LOG_NN_LATENCY_END("conv2d"); return output; diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp index 6e972bfd81b..135815a65cb 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_depthwise_conv2d.hpp @@ -10,7 +10,6 @@ namespace dl { /** * @brief activate(depthwise_conv2d(input, filter) + bias) - * NOTE: When padding_type is SAME, make sure padding is already added in input * * @param output as an output * @param input as an input @@ -34,7 +33,6 @@ namespace dl /** * @brief activate(depthwise_conv2d(input, filter) + bias) - * NOTE: When padding_type is SAME, make sure padding is already added in input * * @param output as an output * @param input as an input @@ -56,6 +54,29 @@ namespace dl const Activation *activation = NULL, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** + * @brief activate(depthwise_conv2d(input, filter) + bias) + * + * @param output as an output + * @param input as an input + * @param padding padding size needed in [top, bottom, left, right] of this operation + * @param filter Filter of depthwise_conv2d + * @param stride_y stride in height + * @param stride_x stride in width + * @param bias bias of depthwise_conv2d, if you don't specify anything, no bias is added + * @param activation activation of depthwise_conv2d, if you don't specify anything, no activation is applied + * @param assign_core not effective yet + */ + void depthwise_conv2d(Tensor &output, + Tensor &input, + std::vector &padding, + const Filter &filter, + const int stride_y, + const int stride_x, + const Bias *bias = NULL, + const Activation *activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + /** * @brief activation(depthwise_conv2d(input, filter) + bias) * @@ -67,25 +88,25 @@ namespace dl * @param filter filter of depthwise_conv2d * @param stride_y stride in height * @param stride_x stride in width - * @param pad_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param pad_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID means no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param bias bias of depthwise_conv2d, if you don't specify anything, no bias is added * @param activation activation of depthwise_conv2d, if you don't specify anything, no activation is applied * @param assign_core not effective yet * @return depthwise_conv2d result */ - template + template Tensor depthwise_conv2d(const int output_exponent, Tensor &input, const Filter &filter, const int stride_y, const int stride_x, const padding_type_t padding_type, - const Bias *bias, + const Bias *bias, const Activation *activation, const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) { @@ -94,20 +115,20 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); + DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter.shape_with_dilation, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - depthwise_conv2d(output, input, input.padding, filter, stride_y, stride_x, bias, activation, assign_core); + depthwise_conv2d(output, input, padding, filter, stride_y, stride_x, bias, activation, assign_core); DL_LOG_NN_LATENCY_END("depthwise_conv2d"); return output; diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_fully_connected.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_fully_connected.hpp new file mode 100644 index 00000000000..372c84825fd --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_fully_connected.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "dl_constant.hpp" +#include "dl_variable.hpp" +#include "dl_nn.hpp" + +namespace dl +{ + namespace nn + { + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @param output as an output + * @param input as an input + * @param filter filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + */ + void fully_connected(Tensor &output, + Tensor &input, + const Filter &filter, + const Bias *const bias = NULL, + const Activation *const activation = NULL, + const bool flatten = true, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + + /** + * @brief activation(FullyConnected(input, filter) + bias). + * + * @tparam feature_t supports int16_t and int8_t, + * - int16_t: stands for operation in int16_t quantize + * - int8_t: stands for operation in int8_t quantize + * @param output_exponent exponent of output + * @param input as an input + * @param filter Filter of FullyConnected + * @param bias bias of FullyConnected, if you don't specify anything, no bias is added + * @param activation activation of FullyConnected, if you don't specify anything, no activation is applied + * @param flatten true: input shape is [x1, x2, ..., xn], filter shape is [1, 1, x1 * x2 * ... * xn, output_dim], output shape is [output_dim] + * false: input shape is [x1, x2, ..., xn, input_dim], filter shape is [1, 1, input_dim, output_dim], output shape is [x1, x2, ...., xn, output_dim] + * @param assign_core not effective yet + * @return FullyConnected result + */ + template + Tensor fully_connected(const int output_exponent, + Tensor &input, + const Filter &filter, + const Bias *bias, + const Activation *activation, + const bool flatten, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) + { + DL_LOG_NN_LATENCY_INIT(); + + DL_LOG_NN_LATENCY_START(); + assert(filter.shape.size() == 4); + assert(filter.shape[0] == 1); + assert(filter.shape[1] == 1); + + std::vector output_shape; + if (flatten) + { + assert(input.get_size() == filter.shape[2]); + output_shape = {filter.shape.back()}; + } + else + { + assert(input.shape.back() == filter->shape[2]); + output_shape = input.shape; + output_shape[output_shape.size() - 1] = filter.shape.back(); + } + Tensor output; + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); + DL_LOG_NN_LATENCY_END("apply"); + + DL_LOG_NN_LATENCY_START(); + fully_connected(output, input, filter, bias, activation, flatten, assign_core); + DL_LOG_NN_LATENCY_END("fully_connected"); + + return output; + } + } // namespace nn +} // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp index 723ca9eddc4..724d3ca0952 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_avg_pool2d.hpp @@ -53,7 +53,7 @@ namespace dl std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; Tensor output; - output.set_exponent(output_exponent).set_shape(output_shape).apply_element(); + output.set_exponent(output_exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp index 945645cfd55..f6f15e91bd3 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_global_max_pool2d.hpp @@ -51,7 +51,7 @@ namespace dl std::vector output_shape(input.shape.size(), 1); output_shape[2] = input.shape[2]; Tensor output; - output.set_exponent(input.exponent).set_shape(output_shape).apply_element(); + output.set_exponent(input.exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_leakyrelu.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_leakyrelu.hpp index d3738fc44ca..c41728b1ad5 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_leakyrelu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_leakyrelu.hpp @@ -52,17 +52,17 @@ namespace dl * @return leakyrelu result or no return(result store to input) */ template - auto leakyrelu(Tensor &input, - const int activation_alpha, - const int activation_exponent, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto leakyrelu(Tensor &input, + const int activation_alpha, + const int activation_exponent, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max2d.hpp index 0a5e8f43221..466089bc386 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max2d.hpp @@ -48,20 +48,20 @@ namespace dl * @return max2d result or no return(result store to input0) */ template - auto max2d(Tensor &input0, - Tensor &input1, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto max2d(Tensor &input0, + Tensor &input1, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input0.exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(input0.exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max_pool2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max_pool2d.hpp index 7f95f3d4278..50d51728ce0 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max_pool2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_max_pool2d.hpp @@ -57,12 +57,12 @@ namespace dl * @param filter_shape filter shape in [filter_height, filter_width] * @param stride_y stride in height * @param stride_x stride in width - * @param padding_type one of PADDING_VALID or PADDING_SAME or PADDING_SAME_MXNET, + * @param padding_type one of PADDING_VALID or PADDING_SAME_END or PADDING_SAME_BEGIN, * - PADDING_VALID: no padding - * PADDING_SAME and PADDING_SAME_MXNET results in padding with zeros evenly to the left/right or up/down of the input + * PADDING_SAME_END and PADDING_SAME_BEGIN results in padding with zeros evenly to the left/right or up/down of the input * such that output has the same height/width dimension as the input, - * - PADDING_SAME results padding in TensorFlow style - * - PADDING_SAME_MXNET results padding in MXNET style + * - PADDING_SAME_END results padding in TensorFlow style + * - PADDING_SAME_BEGIN results padding in MXNET style * @param assign_core not effective yet * @return max_pool2d result */ @@ -79,20 +79,20 @@ namespace dl DL_LOG_NN_LATENCY_START(); std::vector output_shape = get_output_shape(input.shape, filter_shape, stride_y, stride_x, padding_type); Tensor output; - output.set_exponent(input.exponent).set_shape(output_shape).apply_element(); + output.set_exponent(input.exponent).set_shape(output_shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); + std::vector padding(4, 0); + DL_LOG_NN_LATENCY_START(); - if (padding_type == PADDING_SAME || padding_type == PADDING_SAME_MXNET) + if (padding_type == PADDING_SAME_END || padding_type == PADDING_SAME_BEGIN) { - std::vector padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); - input.set_padding_size(padding); - input.set_padding_value(padding, 0); + padding = get_pad_size(output_shape, input.shape, filter_shape, stride_y, stride_x, padding_type); } DL_LOG_NN_LATENCY_END("padding"); DL_LOG_NN_LATENCY_START(); - max_pool2d(output, input, input.padding, filter_shape, stride_y, stride_x, assign_core); + max_pool2d(output, input, padding, filter_shape, stride_y, stride_x, assign_core); DL_LOG_NN_LATENCY_END("max_pool2d"); return output; diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_min2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_min2d.hpp index 71cb87d50d5..8faddf3c228 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_min2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_min2d.hpp @@ -47,20 +47,20 @@ namespace dl * @return min2d result or no return(result store to input0) */ template - auto min2d(Tensor &input0, - Tensor &input1, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto min2d(Tensor &input0, + Tensor &input1, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); assert(input0.exponent == input1.exponent); DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input0.exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(input0.exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_mul2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_mul2d.hpp index 410528a05a3..909619a8767 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_mul2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_mul2d.hpp @@ -18,12 +18,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void mul2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void mul2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(mul2d(input0, input1)). @@ -35,12 +35,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void mul2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void mul2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(mul2d(input0, input1)). @@ -57,21 +57,21 @@ namespace dl * @return mul2d result or no return(result store to input0) */ template - auto mul2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto mul2d(const int output_exponent, + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_prelu.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_prelu.hpp index fb4315d9fc3..e83e8975604 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_prelu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_prelu.hpp @@ -52,17 +52,17 @@ namespace dl * @return prelu result or no return(result store to input) */ template - auto prelu(Tensor &input, - const feature_t *activation_element, - const int activation_exponent, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto prelu(Tensor &input, + const feature_t *activation_element, + const int activation_exponent, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); @@ -76,7 +76,7 @@ namespace dl DL_LOG_NN_LATENCY_START(); prelu(input, input, activation_element, activation_exponent, assign_core); DL_LOG_NN_LATENCY_END("prelu"); - } + } } } // namespace nn } // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_relu.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_relu.hpp index e4159fdf898..308492dfe4b 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_relu.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_relu.hpp @@ -15,9 +15,9 @@ namespace dl * @param input as an input * @param assign_core not effective yet */ - void relu(Tensor &output, - Tensor &input, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + void relu(Tensor &output, + Tensor &input, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); /** * @brief relu(input). @@ -26,9 +26,9 @@ namespace dl * @param input as an input * @param assign_core not effective yet */ - void relu(Tensor &output, - Tensor &input, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); + void relu(Tensor &output, + Tensor &input, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE); /** * @brief relu(input) @@ -46,11 +46,11 @@ namespace dl { DL_LOG_NN_LATENCY_INIT(); Tensor output; - - if constexpr(!inplace) + + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(input.exponent).set_shape(input.shape).apply_element(); + output.set_exponent(input.exponent).set_shape(input.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_sub2d.hpp b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_sub2d.hpp index 385188e4ba2..5bbd4940b10 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_sub2d.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/nn/dl_nn_sub2d.hpp @@ -18,12 +18,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void sub2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void sub2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(sub2d(input0, input1)). @@ -35,12 +35,12 @@ namespace dl * @param assign_core not effective yet * @param output_exponent exponent of output, only and must specify if inplace operation happens */ - void sub2d(Tensor &output, - Tensor &input0, - Tensor &input1, - const Activation *const activation = NULL, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, - const int output_exponent = INT_MIN); + void sub2d(Tensor &output, + Tensor &input0, + Tensor &input1, + const Activation *const activation = NULL, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE, + const int output_exponent = INT_MIN); /** * @brief activation(sub2d(input0, input1)). @@ -57,20 +57,20 @@ namespace dl * @return sub2d result or no return(result store to input0) */ template - auto sub2d(const int output_exponent, - Tensor &input0, - Tensor &input1, - const Activation *activation, - const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type + auto sub2d(const int output_exponent, + Tensor &input0, + Tensor &input1, + const Activation *activation, + const std::vector &assign_core = CONFIG_DEFAULT_ASSIGN_CORE) -> typename std::conditional>::type { assert(input0.is_same_shape(input1)); DL_LOG_NN_LATENCY_INIT(); Tensor output; - if constexpr(!inplace) + if constexpr (!inplace) { DL_LOG_NN_LATENCY_START(); - output.set_exponent(output_exponent).set_shape(input0.shape).apply_element(); + output.set_exponent(output_exponent).set_shape(input0.shape).malloc_element(); DL_LOG_NN_LATENCY_END("apply"); DL_LOG_NN_LATENCY_START(); diff --git a/tools/sdk/esp32s2/include/esp-face/include/tool/dl_tool.hpp b/tools/sdk/esp32s2/include/esp-face/include/tool/dl_tool.hpp index f8e0871a04f..e5490e073d1 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/tool/dl_tool.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/tool/dl_tool.hpp @@ -67,62 +67,49 @@ namespace dl void copy_memory(void *dst, void *src, const int n); /** - * @brief Apply memory without initialized. Must use free_aligned() to free the memory. + * @brief Apply memory without initialized. Can use free_aligned() to free the memory. * * @param number number of elements * @param size size of element - * @param align number of aligned, e.g., 16 means 16-byte aligned + * @param align number of byte aligned, e.g., 16 means 16-byte aligned * @return pointer of allocated memory. NULL for failed */ - inline void *malloc_aligned(int number, int size, int align = 0) + inline void *malloc_aligned(int number, int size, int align = 4) { - int n = number * size; - n >>= 4; - n += 2; - n <<= 4; - int total_size = n + align + sizeof(void *) + sizeof(int); - void *res = malloc(total_size); + assert((align > 0) && (((align & (align-1)) == 0))); + int total_size = number * size; + + void *res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); #if DL_SPIRAM_SUPPORT if (NULL == res) - res = heap_caps_malloc(total_size, MALLOC_CAP_SPIRAM); + res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_SPIRAM); #endif if (NULL == res) { printf("Fail to malloc %d bytes from DRAM(%d bytyes) and PSRAM(%d bytes), PSRAM is %s.\n", total_size, - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), + heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_SPIRAM), DL_SPIRAM_SUPPORT ? "on" : "off"); return NULL; } - void **data = (void **)res + 2; // 4-byte for pointer, 4-bytes for n - void **aligned; - if (align) - aligned = (void **)(((size_t)data + (align - 1)) & -align); - else - aligned = data; - - aligned[-1] = res; - int *temp = (int *)aligned; - temp[-2] = n; - return (void *)aligned; + return (void *)res; } /** - * @brief Apply memory with zero-initialized. Must use dl_lib_free() to free the memory. + * @brief Apply memory with zero-initialized. Can use free_aligned() to free the memory. * * @param number number of elements * @param size size of element - * @param align number of aligned, e.g., 16 means 16-byte aligned + * @param align number of byte aligned, e.g., 16 means 16-byte aligned * @return pointer of allocated memory. NULL for failed */ - inline void *calloc_aligned(int number, int size, int align = 0) + inline void *calloc_aligned(int number, int size, int align = 4) { void *aligned = malloc_aligned(number, size, align); - int n = *((int *)aligned - 2); - set_zero(aligned, n); + set_zero(aligned, number * size); return (void *)aligned; } @@ -137,7 +124,70 @@ namespace dl if (NULL == address) return; - free(((void **)address)[-1]); + heap_caps_free(address); + } + + /** + * @brief Apply memory without initialized in preference order: internal aligned, internal, external aligned + * + * @param number number of elements + * @param size size of element + * @param align number of byte aligned, e.g., 16 means 16-byte aligned + * @return pointer of allocated memory. NULL for failed + */ + inline void *malloc_aligned_prefer(int number, int size, int align = 4) + { + assert((align > 0) && (((align & (align-1)) == 0))); + int total_size = number * size; + void *res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + if (NULL == res){ + res = heap_caps_malloc(total_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + } +#if DL_SPIRAM_SUPPORT + if (NULL == res){ + res = heap_caps_aligned_alloc(align, total_size, MALLOC_CAP_SPIRAM); + } +#endif + if (NULL == res) + { + printf("Fail to malloc %d bytes from DRAM(%d bytyes) and PSRAM(%d bytes), PSRAM is %s.\n", + total_size, + heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL), + heap_caps_get_free_size(MALLOC_CAP_SPIRAM), + DL_SPIRAM_SUPPORT ? "on" : "off"); + return NULL; + } + + return res; + } + + /** + * @brief Apply memory with zero-initialized in preference order: internal aligned, internal, external aligned + * + * @param number number of elements + * @param size size of element + * @param align number of byte aligned, e.g., 16 means 16-byte aligned + * @return pointer of allocated memory. NULL for failed + */ + inline void *calloc_aligned_prefer(int number, int size, int align = 4) + { + void *res = malloc_aligned_prefer(number, size, align); + set_zero(res, number * size); + + return (void *)res; + } + + /** + * @brief Free the calloc_aligned_prefer() and malloc_aligned_prefer() memory + * + * @param address pointer of memory to free + */ + inline void free_aligned_prefer(void *address) + { + if (NULL == address) + return; + + heap_caps_free(address); } /** diff --git a/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_constant.hpp b/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_constant.hpp index 73e3b0832e7..07b2dd24ee1 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_constant.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_constant.hpp @@ -57,7 +57,8 @@ namespace dl * @param exponent exponent of element * @param shape shape of Filter, * - 1D: reserved - * - 2D: [filter_height, filter_width, input_channel, output_channel] + * - 2D: for convolution is [filter_height, filter_width, input_channel, output_channel], + * for depthwise convolution is [filter_height, filter_width, input_channel, 1] * @param dilation dilation of Filter * - 1D: reserved * - 2D: [dilation_in_height, dilation_in_width] @@ -97,6 +98,9 @@ namespace dl { public: using Constant::Constant; + std::vector channel_exponent; /**/ + + Bias(const T *element, const std::vector channel_exponent, const std::vector shape); }; /** diff --git a/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_variable.hpp b/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_variable.hpp index bf6e8630856..18cbe9707e9 100644 --- a/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_variable.hpp +++ b/tools/sdk/esp32s2/include/esp-face/include/typedef/dl_variable.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "dl_tool.hpp" @@ -17,27 +18,20 @@ namespace dl class Tensor { private: - int size; /* axis_offset; /* shape; /* shape_with_padding; /* padding; /* shape; /*set_shape({0}); } /** * @brief Construct a new Tensor object by copying from input. @@ -49,21 +43,20 @@ namespace dl */ Tensor(Tensor &input, bool deep) : size(input.size), auto_free(input.auto_free), - exponent(input.exponent), - shape(input.shape), - shape_with_padding(input.shape_with_padding), - padding(input.padding) + exponent(input.exponent) { - if (deep) + this->set_shape(input.shape); + if (deep && (input.element != NULL)) { - int size_real = input.shape_with_padding.size() ? input.shape_with_padding[0] * input.shape_with_padding[1] * input.shape_with_padding[2] : 0; - T *new_element = (T *)tool::calloc_aligned(size_real, sizeof(T), 16); + int size_real = input.get_size(); + T *new_element = (T *)tool::calloc_aligned_prefer(size_real, sizeof(T), 16); tool::copy_memory(new_element, input.element, size_real * sizeof(T)); this->element = new_element; } else { this->element = input.element; + this->auto_free = false; } } @@ -77,6 +70,33 @@ namespace dl this->free_element(); } + /** + * @brief + * + * @param input an input Tensor + * @param deep one of true or false + * - true: apply a new memory, copy value from input.element to this new memory + * - false: take over input.element to this->element + * @return Tensor& self + */ + Tensor ©_element(Tensor &input, bool deep) + { + assert(this->get_size() == input.get_size()); + assert(input.element != NULL); + + this->malloc_element(); + if (deep) + { + tool::copy_memory(this->element, input.element, this->get_size() * sizeof(T)); + } + else + { + this->element = input.element; + this->auto_free = false; + } + return *this; + } + /** * @brief Set the auto free object. * @@ -120,190 +140,144 @@ namespace dl } /** - * @brief Set the shape of Tensor. Initial this->padding = {0}. Initial this->size = -1. + * @brief Set the shape of Tensor. * - * @param shape shape in - * - 2D: [height, width] + * @param shape the target shape + * * @return self */ - Tensor &set_shape(const std::vector shape) - { - for (int i = 0; i < shape.size(); ++i) - { - assert(shape[i] > 0); - } - this->shape = shape; - this->shape_with_padding = shape; - this->size = -1; - this->padding = std::vector(((this->shape.size() - 1) << 1), 0); - return *this; - } + Tensor &set_shape(const std::vector shape); /** - * @brief Set the padding size object. + * @brief print the shape of the Tensor * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @return self */ - Tensor &set_padding_size(std::vector &padding) + void print_shape() { - assert(this->shape.size()); // call Tensor.set_shape() first - assert(this->shape.size() == 3); // TODO: || this->shape.size() == 2 - - if (this->shape.size() == 3) + if (this->shape.size()) { - std::vector new_padding = this->padding; - bool dont_update = true; - - if (padding[0] > this->padding[0]) + printf("shape = ("); + for (int i = 0; i < this->shape.size() - 1; i++) { - new_padding[0] = padding[0]; - dont_update = false; - } - - if (padding[1] > this->padding[1]) - { - new_padding[1] = padding[1]; - dont_update = false; - } - - if (padding[2] > this->padding[2]) - { - new_padding[2] = padding[2]; - dont_update = false; - } - - if (padding[3] > this->padding[3]) - { - new_padding[3] = padding[3]; - dont_update = false; + printf("%d, ", this->shape[i]); } + printf("%d)\n", this->shape.back()); + } + else + { + printf("shape = ()\n"); + } + } - if (dont_update) - { - return *this; - } + /** + * @brief flatten the Tensor + * + * @return Tensor& self + */ + Tensor &flatten(); - std::vector new_shape_with_padding = this->shape; + /** + * @brief Change a new shape to the Tensor without changing its data. + * + * @param shape the target shape + * @return Tensor& self + */ + Tensor &reshape(std::vector shape); - new_shape_with_padding[0] += (new_padding[0] + new_padding[1]); - new_shape_with_padding[1] += (new_padding[2] + new_padding[3]); - int new_size = new_shape_with_padding[0] * new_shape_with_padding[1] * new_shape_with_padding[2]; + /** + * @brief Remove dims with length==1 from Tensor + * + * @param axis the dim to to be remove. make sure the length of the dim is equal to 1. + * if axis == INT32_MAX, all the dims with length==1 will be removed. + * @return Tensor& self + */ + Tensor &squeeze(int axis = INT32_MAX); - if (this->element) // if this->element != NULL, do padding by copy memory - { - T *new_element = (T *)tool::malloc_aligned(new_size, sizeof(T), 16); - T *dst = new_element + ((new_padding[0] * new_shape_with_padding[1]) + new_padding[2]) * new_shape_with_padding[2]; - T *src = this->get_element_ptr(); - int offset_dst_next_y = new_shape_with_padding[1] * new_shape_with_padding[2]; // width * channel - int src_copy_length = this->shape[1] * this->shape[2]; // width * channel - int offset_src_next_y = this->shape_with_padding[1] * this->shape_with_padding[2]; // width * channel - for (int y = 0; y < this->shape[0]; y++) - { - tool::copy_memory(dst, src, src_copy_length * sizeof(T)); - dst += offset_dst_next_y; - src += offset_src_next_y; - } + /** + * @brief Insert a new dim that will appear at the axis position in the expanded Tensor shape. + * + * @param axis the dim to be inserted + * @return Tensor& self + */ + Tensor &expand_dims(int axis); - if (this->auto_free) - tool::free_aligned(this->element); - this->element = new_element; - this->auto_free = true; - } - this->padding = new_padding; - this->shape_with_padding = new_shape_with_padding; - this->size = new_size; - } - else if (this->shape.size() == 2) - { - printf("Tensor.set_padding_size with this->shape.size() == 2 not implement yet.\n"); - } + /** + * @brief Insert a new dim that will appear at the axis position in the expanded Tensor shape. + * + * @param axis the dim to be inserted + * @return Tensor& self + */ + Tensor &expand_dims(std::vector axis); - return *this; - } + /** + * @brief Reverse or permute the axes of the Tensor + * + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @return Tensor& self + */ + Tensor &transpose(std::vector perm = {}); /** - * @brief Set the padding value object. + * @brief Reverse or permute the axes of the input Tensor * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @param value value to set - * @return self + * @param input the input Tensor + * @param perm the new arangement of the dims. if perm == {}, the dims arangement will be reversed. + * @return Tensor& self */ - Tensor &set_padding_value(std::vector &padding, T value); + Tensor &transpose(Tensor &input, std::vector perm = {}); /** * @brief Get the element pointer. * - * @param padding padding size in - * - 2D: [top, bottom, left, right] - * @return pointer to memory with padding + * @return pointer to memory */ - T *get_element_ptr(const std::vector padding = {0, 0, 0, 0}) + T *get_element_ptr() { - assert(this->shape.size() == 3); // TODO: || this->shape.size() == 2 - - if (this->shape.size() == 3) - { - return this->element + ((this->padding[0] - padding[0]) * this->shape_with_padding[1] + (this->padding[2] - padding[2])) * this->shape_with_padding[2]; - } - else if (this->shape.size() == 2) - { - printf("Tensor.get_element_ptr with this->shape.size() == 2 is not implemented.\n"); - } - - return NULL; + return this->element; } /** * @brief Get the element value. * - * @param index index in - * - 2D: [y, x, c] - * @param with_padding one of true or false, - * - true: make padding size in count - * - false: do not - * @return element value + * @param index the index of each dim. + * @return T element value */ - T &get_element_value(const std::vector index, const bool with_padding = false) + T get_element_value(const std::vector index) { - assert(index.size() == this->shape.size()); - assert(this->shape.size() == 3); // TODO: || this->shape() == 2 - - int i = 0; - if (this->shape.size() == 3) - { - int y = index[0]; - int x = index[1]; - int c = index[2]; - i = with_padding ? (y * this->shape_with_padding[1] + x) * this->shape_with_padding[2] + c : ((y + this->padding[0]) * this->shape_with_padding[1] + x + this->padding[2]) * this->shape_with_padding[2] + c; - } - else if (this->shape.size() == 2) - { - printf("Tensor.get_element_value with this->shape.size() == 2 is not implemented.\n"); - } + return this->element[this->get_element_index(index)]; + } - return this->element[i]; + /** + * @brief Get the element value. + * + * @param index the index of the element. + * @return T element value + */ + T get_element_value(int index) + { + return this->element[index]; } /** - * @brief Get the size of element. + * @brief Get the size of Tensor. * - * @return size of element including padding + * @return the size of Tensor. */ int get_size() { - if (this->size == -1) // didn't call Tensor.set_padding_size() before - { - this->size = 1; - for (std::vector::iterator d = this->shape.begin(); d != this->shape.end(); d++) - this->size *= *d; - } - return this->size; } + /** + * @brief Get the axis offset + * + * @return std::vector the axis offset + */ + std::vector get_axis_offset() + { + return this->axis_offset; + } + /** * @brief Apply memory with zero-initialized only if this->element is NULL. * @@ -319,7 +293,7 @@ namespace dl if (this->element != NULL) return false; - this->element = (T *)dl::tool::calloc_aligned(this->get_size(), sizeof(T), 16); + this->element = (T *)dl::tool::calloc_aligned_prefer(this->get_size(), sizeof(T), 16); this->auto_free = auto_free; return true; @@ -340,31 +314,7 @@ namespace dl if (this->element != NULL) return false; - this->element = (T *)tool::malloc_aligned(this->get_size(), sizeof(T), 16); - this->auto_free = auto_free; - - return true; - } - - /** - * @brief If this->element != NULL no memory will be applied and no value will be set in padding. - * Else apply memory without initialized and set value to padding. - * - * @param padding_value value to set in padding - * @param auto_free one of true of false - * - true: free element when object destroyed - * - false: do not - * @return - * - true: apply memory and set padding value successfully - * - false: no memory applied and no padding value set - */ - bool apply_element(const T padding_value = 0, const bool auto_free = true) - { - if (this->element != NULL) - return false; - - this->element = (T *)tool::malloc_aligned(this->get_size(), sizeof(T), 16); - this->set_padding_value(this->padding, padding_value); + this->element = (T *)tool::malloc_aligned_prefer(this->get_size(), sizeof(T), 16); this->auto_free = auto_free; return true; @@ -379,258 +329,56 @@ namespace dl { if (this->auto_free && this->element) { - tool::free_aligned(this->element); + tool::free_aligned_prefer(this->element); this->element = NULL; } } /** - * @brief Print the shape of Tensor in format "shape = ({top_padding} + {height} + {bottom_padding}, {left_padding} + {width} + {right_padding}, {channel}(channel_with_padding))\n". + * @brief print the element of the tensor + * + * @param axis_index_range the element range of each dims to be print. if axis_index_range == {}, all the element will be print. + * @param message to print */ - void print_shape() - { - printf("shape = (%d + %d + %d, %d + %d + %d, %d(%d))\n", - this->padding[0], this->shape[0], this->padding[1], - this->padding[2], this->shape[1], this->padding[3], - this->shape[2], this->shape_with_padding[2]); - } + void print(std::vector axis_index_range = {}, const char *message = ""); /** - * @brief Take numpy for example, this function print Tensor[y_start:y_end, x_start:x_end, c_start:c_end]. + * @brief print all the element of the Tensor. * - * inner box is effective value of Tensor, "0" around is padding. - * - * (with padding) - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 000000(without padding) 00000000 - * 000000 00000000 - * 000000 00000000 - * 000000 effective value 00000000 - * 000000 00000000 - * 000000 00000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * 00000000000000000000000000000000000000000000000000 - * - * @param y_start start index in height - * @param y_end end index in height - * @param x_start start index in width - * @param x_end end index in width - * @param c_start start index in channel - * @param c_end end index in channel - * @param message to print - * @param axis print aligned this axis, effective only if all y_end - y_start, x_end - x_start and c_end - c_start equals to 1 + * @param message to print * @param with_padding one of true or false, - * - true: count from (with padding) in upper image - * - false: count from (without padding) in upper image + * - true: the padding element will also be ed + * - false: the padding element will not be ed */ - void print(int y_start, int y_end, - int x_start, int x_end, - int c_start, int c_end, - const char *message, int axis = 0, const bool with_padding = false) + void print_all(const char *message = "") { - assert(y_end > y_start); - assert(x_end > x_start); - assert(c_end > c_start); - - y_start = DL_MAX(y_start, 0); - x_start = DL_MAX(x_start, 0); - c_start = DL_MAX(c_start, 0); - if (with_padding) - { - y_end = DL_MIN(y_end, this->shape_with_padding[0]); - x_end = DL_MIN(x_end, this->shape_with_padding[1]); - c_end = DL_MIN(c_end, this->shape_with_padding[2]); - } - else - { - y_end = DL_MIN(y_end, this->shape[0]); - x_end = DL_MIN(x_end, this->shape[1]); - c_end = DL_MIN(c_end, this->shape[2]); - } - - printf("%s[%d:%d, %d:%d, %d:%d] | ", message, y_start, y_end, x_start, x_end, c_start, c_end); + std::cout << "\n" + << message << " | "; this->print_shape(); - if (y_end - y_start == 1) - { - if (x_end - x_start == 1) - { - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y_start, x_start, c}, with_padding)); - printf("\n"); - - return; - } - else - { - if (c_end - c_start == 1) - { - for (int x = x_start; x < x_end; x++) - printf("%7d", x); - printf("\n"); - - for (int x = x_start; x < x_end; x++) - printf("%7d", this->get_element_value({y_start, x, c_start}, with_padding)); - printf("\n"); - - return; - } - } - } - else + for (int i = 0; i < this->get_size(); i++) { - if (x_end - x_start == 1) - { - if (c_end - c_start == 1) - { - for (int y = y_start; y < y_end; y++) - printf("%7d", y); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - printf("%7d", this->get_element_value({y, x_start, c_start}, with_padding)); - printf("\n"); - - return; - } - } + std::cout << this->element[i] << " "; } - - if (y_end - y_start == 1) - axis = 0; - - if (x_end - x_start == 1) - axis = 1; - - if (c_end - c_start == 1) - axis = 2; - - if (axis == 0) - { - // ______c - // | - // | - // x - // - for (int y = y_start; y < y_end; y++) - { - printf("y = %d\n ", y); - - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int x = x_start; x < x_end; x++) - { - printf("%5d", x); - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - else if (axis == 1) - { - // ______c - // | - // | - // y - // - for (int x = x_start; x < x_end; x++) - { - printf("x = %d\n ", x); - - for (int c = c_start; c < c_end; c++) - printf("%7d", c); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - { - printf("%5d", y); - for (int c = c_start; c < c_end; c++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - else - { - // ______x - // | - // | - // y - // - for (int c = c_start; c < c_end; c++) - { - printf("c = %d\n ", c); - - for (int x = x_start; x < x_end; x++) - printf("%7d", x); - printf("\n"); - - for (int y = y_start; y < y_end; y++) - { - printf("%5d", y); - for (int x = x_start; x < x_end; x++) - printf("%7d", this->get_element_value({y, x, c}, with_padding)); - printf("\n"); - } - printf("\n"); - } - } - + std::cout << "\n"; return; } /** - * @brief print all the element of the Tensor. + * @brief Get the index of each dims * - * @param message to print - * @param with_padding one of true or false, - * - true: the padding element will also be printed - * - false: the padding element will not be printed + * @param element_index the index of the element + * @return std::vector the index of each dims */ - void print_all(const char *message, const bool with_padding = false) - { - int y_end; - int x_end; - int c_end; - if (with_padding) - { - y_end = this->shape_with_padding[0]; - x_end = this->shape_with_padding[1]; - c_end = this->shape_with_padding[2]; - } - else - { - y_end = this->shape[0]; - x_end = this->shape[1]; - c_end = this->shape[2]; - } + std::vector get_axis_index(int element_index); - printf("\n%s | ", message); - this->print_shape(); - - for (int y = 0; y < y_end; y++) - { - for (int x = 0; x < x_end; x++) - { - for (int c = 0; c < c_end; c++) - printf("%d ", this->get_element_value({y, x, c}, with_padding)); - } - } - printf("\n"); - return; - } + /** + * @brief Get the index of element + * + * @param axis_index the index of each dims + * @return int the index of element + */ + int get_element_index(const std::vector axis_index); /** * @brief Check the element value with input ground-truth. @@ -638,35 +386,39 @@ namespace dl * @param gt_element ground-truth value of element * @param bias permissible error * @param info one of true or false - * - true: print shape and result + * - true: shape and result * - false: do not + * @param failed_number maximum number of wrong element that will be printed + * * @return * - true: in permissible error * - false: not */ - bool check_element(T *gt_element, int bias = 2, bool info = true) + bool check_element(T *gt_element, int bias = 2, bool info = true, int failed_number = 0) { + int count = 0; if (info) this->print_shape(); - int i = 0; - for (int y = 0; y < this->shape[0]; y++) + int size = this->get_size(); + for (int i = 0; i < size; i++) { - for (int x = 0; x < this->shape[1]; x++) + if (DL_ABS(this->element[i] - gt_element[i]) > bias) { - for (int c = 0; c < this->shape[2]; c++) + std::vector index = get_axis_index(i); + std::cout << "element["; + for (int j = 0; j < index.size() - 1; j++) { - int a = this->get_element_value({y, x, c}); - int b = gt_element[i]; - int offset = DL_ABS(a - b); - if (offset > bias) - { - printf("element[%d, %d, %d]: %d v.s. %d\n", y, x, c, a, b); - return false; - } - i++; + std::cout << index[j] << ", "; } + std::cout << index.back() << "]: "; + std::cout << +this->element[i] << " v.s. " << +gt_element[i] << "\n"; + count++; + if (count > failed_number) + return false; } } + if (count) + return false; if (info) printf("PASS\n"); @@ -700,35 +452,44 @@ namespace dl Tensor &operator=(const Tensor &input) { - this->size = input.size; this->auto_free = input.auto_free; this->exponent = input.exponent; - this->shape = input.shape; - this->padding = input.padding; - int size_real_tmp = this->shape_with_padding.size() ? this->shape_with_padding[0] * this->shape_with_padding[1] * this->shape_with_padding[2] : 0; - int size_input_real = input.shape_with_padding.size() ? input.shape_with_padding[0] * input.shape_with_padding[1] * input.shape_with_padding[2] : 0; - this->shape_with_padding = input.shape_with_padding; - if (this->element) + int size_real_tmp = this->size; + int size_input_real = input.size; + this->set_shape(input.shape); + if (input.element) { - if (size_real_tmp != size_input_real) + if (this->element) { - tool::free_aligned(this->element); - T *new_element = (T *)tool::calloc_aligned(size_input_real, sizeof(T), 16); - tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); - this->element = new_element; + if (size_real_tmp != size_input_real) + { + tool::free_aligned_prefer(this->element); + T *new_element = (T *)tool::malloc_aligned_prefer(size_input_real, sizeof(T), 16); + tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); + this->element = new_element; + } + else + { + tool::copy_memory(this->element, input.element, size_input_real * sizeof(T)); + } } else { - tool::copy_memory(this->element, input.element, size_input_real * sizeof(T)); + T *new_element = (T *)tool::malloc_aligned_prefer(size_input_real, sizeof(T), 16); + tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); + this->element = new_element; } + return *this; } else { - T *new_element = (T *)tool::calloc_aligned(size_input_real, sizeof(T), 16); - tool::copy_memory(new_element, input.element, size_input_real * sizeof(T)); - this->element = new_element; + if (this->element) + { + tool::free_aligned_prefer(this->element); + this->element = NULL; + } + return *this; } - return *this; } }; } // namespace dl \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/cat_face_3.h b/tools/sdk/esp32s2/include/esp-face/lib/include/cat_face_3.h new file mode 100644 index 00000000000..42d6fa85821 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/cat_face_3.h @@ -0,0 +1,40 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is free of charge, to any person_body 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. + * + */ + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" +#include "detection.h" + + extern detection_model_t cat_face_3_model; + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/detection.h b/tools/sdk/esp32s2/include/esp-face/lib/include/detection.h new file mode 100644 index 00000000000..0bba4f49b6f --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/detection.h @@ -0,0 +1,87 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" + + typedef enum + { + Anchor_Point, /* +#include +#include +#include +#include +#include + +#if CONFIG_SPIRAM_SUPPORT || CONFIG_ESP32_SPIRAM_SUPPORT +#include "freertos/FreeRTOS.h" +#define DL_SPIRAM_SUPPORT 1 +#else +#define DL_SPIRAM_SUPPORT 0 +#endif + + +#ifndef max +#define max(x, y) (((x) < (y)) ? (y) : (x)) +#endif + +#ifndef min +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +typedef float fptp_t; +typedef uint8_t uc_t; + +typedef enum +{ + DL_SUCCESS = 0, + DL_FAIL = 1, +} dl_error_type; + +typedef enum +{ + PADDING_VALID = 0, /*!< Valid padding */ + PADDING_SAME = 1, /*!< Same padding, from right to left, free input */ + PADDING_SAME_DONT_FREE_INPUT = 2, /*!< Same padding, from right to left, do not free input */ + PADDING_SAME_MXNET = 3, /*!< Same padding, from left to right */ +} dl_padding_type; + +typedef enum +{ + DL_POOLING_MAX = 0, /*!< Max pooling */ + DL_POOLING_AVG = 1, /*!< Average pooling */ +} dl_pooling_type; +/* + * Matrix for 3d + * @Warning: the sequence of variables is fixed, cannot be modified, otherwise there will be errors in esp_dsp_dot_float + */ +typedef struct +{ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + fptp_t *item; /*!< Data */ +} dl_matrix3d_t; + +typedef struct +{ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + uc_t *item; /*!< Data */ +} dl_matrix3du_t; + +typedef enum +{ + UPSAMPLE_NEAREST_NEIGHBOR = 0, /*!< Use nearest neighbor interpolation as the upsample method*/ + UPSAMPLE_BILINEAR = 1, /*!< Use nearest bilinear interpolation as the upsample method*/ +} dl_upsample_type; + +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ +} dl_matrix3d_mobilenet_config_t; + +/* + * @brief Allocate a zero-initialized space. Must use 'dl_lib_free' to free the memory. + * + * @param cnt Count of units. + * @param size Size of unit. + * @param align Align of memory. If not required, set 0. + * @return Pointer of allocated memory. Null for failed. + */ +static void *dl_lib_calloc(int cnt, int size, int align) +{ + int total_size = cnt * size + align + sizeof(void *); + void *res = malloc(total_size); + if (NULL == res) + { +#if DL_SPIRAM_SUPPORT + res = heap_caps_malloc(total_size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + } + if (NULL == res) + { + printf("Item psram alloc failed. Size: %d x %d\n", cnt, size); +#else + printf("Item alloc failed. Size: %d x %d, SPIRAM_FLAG: %d\n", cnt, size, DL_SPIRAM_SUPPORT); +#endif + return NULL; + } + bzero(res, total_size); + void **data = (void **)res + 1; + void **aligned; + if (align) + aligned = (void **)(((size_t)data + (align - 1)) & -align); + else + aligned = data; + + aligned[-1] = res; + return (void *)aligned; +} + +/** + * @brief Free the memory space allocated by 'dl_lib_calloc' + * + */ +static inline void dl_lib_free(void *d) +{ + if (NULL == d) + return; + + free(((void **)d)[-1]); +} + +/* + * @brief Allocate a 3D matrix with float items, the access sequence is NHWC + * + * @param n Number of matrix3d, for filters it is out channels, for others it is 1 + * @param w Width of matrix3d + * @param h Height of matrix3d + * @param c Channel of matrix3d + * @return 3d matrix + */ +static inline dl_matrix3d_t *dl_matrix3d_alloc(int n, int w, int h, int c) +{ + dl_matrix3d_t *r = (dl_matrix3d_t *)dl_lib_calloc(1, sizeof(dl_matrix3d_t), 0); + if (NULL == r) + { + printf("internal r failed.\n"); + return NULL; + } + fptp_t *items = (fptp_t *)dl_lib_calloc(n * w * h * c, sizeof(fptp_t), 0); + if (NULL == items) + { + printf("matrix3d item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Allocate a 3D matrix with 8-bits items, the access sequence is NHWC + * + * @param n Number of matrix3d, for filters it is out channels, for others it is 1 + * @param w Width of matrix3d + * @param h Height of matrix3d + * @param c Channel of matrix3d + * @return 3d matrix + */ +static inline dl_matrix3du_t *dl_matrix3du_alloc(int n, int w, int h, int c) +{ + dl_matrix3du_t *r = (dl_matrix3du_t *)dl_lib_calloc(1, sizeof(dl_matrix3du_t), 0); + if (NULL == r) + { + printf("internal r failed.\n"); + return NULL; + } + uc_t *items = (uc_t *)dl_lib_calloc(n * w * h * c, sizeof(uc_t), 0); + if (NULL == items) + { + printf("matrix3du item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Free a matrix3d + * + * @param m matrix3d with float items + */ +static inline void dl_matrix3d_free(dl_matrix3d_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + +/* + * @brief Free a matrix3d + * + * @param m matrix3d with 8-bits items + */ +static inline void dl_matrix3du_free(dl_matrix3du_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + + +/* + * @brief Dot product with a vector and matrix + * + * @param out Space to put the result + * @param in input vector + * @param f filter matrix + */ +void dl_matrix3dff_dot_product(dl_matrix3d_t *out, dl_matrix3d_t *in, dl_matrix3d_t *f); + +/** + * @brief Do a softmax operation on a matrix3d + * + * @param in Input matrix3d + */ +void dl_matrix3d_softmax(dl_matrix3d_t *m); + +/** + * @brief Copy a range of float items from an existing matrix to a preallocated matrix + * + * @param dst The destination slice matrix + * @param src The source matrix to slice + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3d_slice_copy(dl_matrix3d_t *dst, + dl_matrix3d_t *src, + int x, + int y, + int w, + int h); + +/** + * @brief Copy a range of 8-bits items from an existing matrix to a preallocated matrix + * + * @param dst The destination slice matrix + * @param src The source matrix to slice + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3du_slice_copy(dl_matrix3du_t *dst, + dl_matrix3du_t *src, + int x, + int y, + int w, + int h); + +/** + * @brief Transform a sliced matrix block from nhwc to nchw, the block needs to be memory continous. + * + * @param out The destination sliced matrix in nchw + * @param in The source sliced matrix in nhwc + */ +void dl_matrix3d_sliced_transform_nchw(dl_matrix3d_t *out, + dl_matrix3d_t *in); + +/** + * @brief Do a general CNN layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return dl_matrix3d_t* The result of CNN layer + */ +dl_matrix3d_t *dl_matrix3d_conv(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + int padding, + int mode); + +/** + * @brief Do a global average pooling layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * + * @return The result of global average pooling layer + */ +dl_matrix3d_t *dl_matrix3d_global_pool(dl_matrix3d_t *in); + +/** + * @brief Calculate pooling layer of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @param f_w Window width + * @param f_h Window height + * @param stride_x Stride in horizontal direction + * @param stride_y Stride in vertical direction + * @param padding Padding type: PADDING_VALID and PADDING_SAME + * @param pooling_type Pooling type: DL_POOLING_MAX and POOLING_AVG + * @return dl_matrix3d_t* Resulting matrix, size (1, w', h', c) + */ +dl_matrix3d_t *dl_matrix3d_pooling(dl_matrix3d_t *in, + int f_w, + int f_h, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_pooling_type pooling_type); +/** + * @brief Do a batch normalization operation, update the input matrix3d: input = input * scale + offset + * + * @param m Input matrix3d + * @param scale scale matrix3d, scale = gamma/((moving_variance+sigma)^(1/2)) + * @param Offset Offset matrix3d, offset = beta-(moving_mean*gamma/((moving_variance+sigma)^(1/2))) + */ +void dl_matrix3d_batch_normalize(dl_matrix3d_t *m, + dl_matrix3d_t *scale, + dl_matrix3d_t *offset); + +/** + * @brief Add a pair of matrix3d item-by-item: res=in_1+in_2 + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * + * @return dl_matrix3d_t* Added data + */ +dl_matrix3d_t *dl_matrix3d_add(dl_matrix3d_t *in_1, dl_matrix3d_t *in_2); + +/** + * @brief Concatenate the channels of two matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * + * @return dl_matrix3d_t* A newly allocated matrix3d with as avlues in_1|in_2 + */ +dl_matrix3d_t *dl_matrix3d_concat(dl_matrix3d_t *in_1, dl_matrix3d_t *in_2); + +/** + * @brief Concatenate the channels of four matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * @param in_3 Third Floating point input matrix3d + * @param in_4 Fourth Floating point input matrix3d + * + * @return A newly allocated matrix3d with as avlues in_1|in_2|in_3|in_4 + */ +dl_matrix3d_t *dl_matrix3d_concat_4(dl_matrix3d_t *in_1, + dl_matrix3d_t *in_2, + dl_matrix3d_t *in_3, + dl_matrix3d_t *in_4); + +/** + * @brief Concatenate the channels of eight matrix3ds into a new matrix3d + * + * @param in_1 First Floating point input matrix3d + * @param in_2 Second Floating point input matrix3d + * @param in_3 Third Floating point input matrix3d + * @param in_4 Fourth Floating point input matrix3d + * @param in_5 Fifth Floating point input matrix3d + * @param in_6 Sixth Floating point input matrix3d + * @param in_7 Seventh Floating point input matrix3d + * @param in_8 eighth Floating point input matrix3d + * + * @return A newly allocated matrix3d with as avlues in_1|in_2|in_3|in_4|in_5|in_6|in_7|in_8 + */ +dl_matrix3d_t *dl_matrix3d_concat_8(dl_matrix3d_t *in_1, + dl_matrix3d_t *in_2, + dl_matrix3d_t *in_3, + dl_matrix3d_t *in_4, + dl_matrix3d_t *in_5, + dl_matrix3d_t *in_6, + dl_matrix3d_t *in_7, + dl_matrix3d_t *in_8); + +/** + * @brief Do a mobilefacenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param pw Weights of the pointwise conv layer + * @param pw_bn_scale The scale params of the batch_normalize layer after the pointwise conv layer + * @param pw_bn_offset The offset params of the batch_normalize layer after the pointwise conv layer + * @param dw Weights of the depthwise conv layer + * @param dw_bn_scale The scale params of the batch_normalize layer after the depthwise conv layer + * @param dw_bn_offset The offset params of the batch_normalize layer after the depthwise conv layer + * @param pw_linear Weights of the pointwise linear conv layer + * @param pw_linear_bn_scale The scale params of the batch_normalize layer after the pointwise linear conv layer + * @param pw_linear_bn_offset The offset params of the batch_normalize layer after the pointwise linear conv layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of a mobilefacenet block + */ +dl_matrix3d_t *dl_matrix3d_mobilefaceblock(dl_matrix3d_t *in, + dl_matrix3d_t *pw, + dl_matrix3d_t *pw_bn_scale, + dl_matrix3d_t *pw_bn_offset, + dl_matrix3d_t *dw, + dl_matrix3d_t *dw_bn_scale, + dl_matrix3d_t *dw_bn_offset, + dl_matrix3d_t *pw_linear, + dl_matrix3d_t *pw_linear_bn_scale, + dl_matrix3d_t *pw_linear_bn_offset, + int stride_x, + int stride_y, + int padding, + int mode, + int shortcut); + +/** + * @brief Do a mobilefacenet block forward with 1x1 split conv, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param pw_1 Weights of the pointwise conv layer 1 + * @param pw_2 Weights of the pointwise conv layer 2 + * @param pw_bn_scale The scale params of the batch_normalize layer after the pointwise conv layer + * @param pw_bn_offset The offset params of the batch_normalize layer after the pointwise conv layer + * @param dw Weights of the depthwise conv layer + * @param dw_bn_scale The scale params of the batch_normalize layer after the depthwise conv layer + * @param dw_bn_offset The offset params of the batch_normalize layer after the depthwise conv layer + * @param pw_linear_1 Weights of the pointwise linear conv layer 1 + * @param pw_linear_2 Weights of the pointwise linear conv layer 2 + * @param pw_linear_bn_scale The scale params of the batch_normalize layer after the pointwise linear conv layer + * @param pw_linear_bn_offset The offset params of the batch_normalize layer after the pointwise linear conv layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of a mobilefacenet block + */ +dl_matrix3d_t *dl_matrix3d_mobilefaceblock_split(dl_matrix3d_t *in, + dl_matrix3d_t *pw_1, + dl_matrix3d_t *pw_2, + dl_matrix3d_t *pw_bn_scale, + dl_matrix3d_t *pw_bn_offset, + dl_matrix3d_t *dw, + dl_matrix3d_t *dw_bn_scale, + dl_matrix3d_t *dw_bn_offset, + dl_matrix3d_t *pw_linear_1, + dl_matrix3d_t *pw_linear_2, + dl_matrix3d_t *pw_linear_bn_scale, + dl_matrix3d_t *pw_linear_bn_offset, + int stride_x, + int stride_y, + int padding, + int mode, + int shortcut); + +/** + * @brief Initialize the matrix3d feature map to bias + * + * @param out The matrix3d feature map needs to be initialized + * @param bias The bias of a convlotion operation + */ +void dl_matrix3d_init_bias(dl_matrix3d_t *out, dl_matrix3d_t *bias); + +/** + * @brief Do a elementwise multiplication of two matrix3ds + * + * @param out Preallocated matrix3d, size (n, w, h, c) + * @param in1 Input matrix 1, size (n, w, h, c) + * @param in2 Input matrix 2, size (n, w, h, c) + */ +void dl_matrix3d_multiply(dl_matrix3d_t *out, dl_matrix3d_t *in1, dl_matrix3d_t *in2); + +// +// Activation +// + +/** + * @brief Do a standard relu operation, update the input matrix3d + * + * @param m Floating point input matrix3d + */ +void dl_matrix3d_relu(dl_matrix3d_t *m); + +/** + * @brief Do a relu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param clip If value is higher than this, it will be clipped to this value + */ +void dl_matrix3d_relu_clip(dl_matrix3d_t *m, fptp_t clip); + +/** + * @brief Do a Prelu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param alpha If value is less than zero, it will be updated by multiplying this factor + */ +void dl_matrix3d_p_relu(dl_matrix3d_t *in, dl_matrix3d_t *alpha); + +/** + * @brief Do a leaky relu (Rectifier Linear Unit) operation, update the input matrix3d + * + * @param in Floating point input matrix3d + * @param alpha If value is less than zero, it will be updated by multiplying this factor + */ +void dl_matrix3d_leaky_relu(dl_matrix3d_t *m, fptp_t alpha); + +// +// Conv 1x1 +// +/** + * @brief Do 1x1 convolution with a matrix3d + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + */ +void dl_matrix3dff_conv_1x1(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do 1x1 convolution with a matrix3d, with bias adding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + */ +void dl_matrix3dff_conv_1x1_with_bias(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + */ +void dl_matrix3duf_conv_1x1(dl_matrix3d_t *out, + dl_matrix3du_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + */ +void dl_matrix3duf_conv_1x1_with_bias(dl_matrix3d_t *out, + dl_matrix3du_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +// +// Conv 3x3 +// + +/** + * @brief Do 3x3 convolution with a matrix3d, without padding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (n, 3, 3, c) + * @param step_x Stride of width + * @param step_y Stride of height + */ +void dl_matrix3dff_conv_3x3_op(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *f, + int step_x, + int step_y); + +/** + * @brief Do 3x3 convolution with a matrix3d, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_conv_3x3(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// Conv Common +// + +/** + * @brief Do a general convolution layer pass with an 8-bit fixed point matrix, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3duf_conv_common(dl_matrix3du_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +/** + * @brief Do a general convolution layer pass, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding Padding type + * @return dl_matrix3d_t* Resulting matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_conv_common(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// Depthwise 3x3 +// + +/** + * @brief Do 3x3 depthwise convolution with a float matrix3d + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @return dl_matrix3d_t* Resulting float matrix3d + */ +dl_matrix3d_t *dl_matrix3dff_depthwise_conv_3x3(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + int padding); + +/** + * @brief Do 3x3 depthwise convolution with a 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @return dl_matrix3d_t* Resulting float matrix3d + */ +dl_matrix3d_t *dl_matrix3duf_depthwise_conv_3x3(dl_matrix3du_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + int padding); + +/** + * @brief Do 3x3 depthwise convolution with a float matrix3d, without padding + * + * @param out Preallocated matrix3d, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param step_x Stride of width + * @param step_y Stride of height + */ +void dl_matrix3dff_depthwise_conv_3x3_op(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *f, + int step_x, + int step_y); + +// +// Depthwise Common +// + +/** + * @brief Do a depthwise CNN layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3dff_depthwise_conv_common(dl_matrix3d_t *in, + dl_matrix3d_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding); + +// +// FC +// +/** + * @brief Do a general fully connected layer pass, dimension is (number, width, height, channel) + * + * @param in Input matrix3d, size is (1, w, 1, 1) + * @param filter Weights of the neurons, size is (1, w, h, 1) + * @param bias Bias for the fc layer, size is (1, 1, 1, h) + * @return The result of fc layer, size is (1, 1, 1, h) + */ +void dl_matrix3dff_fc(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter); + +/** + * @brief Do fully connected layer forward, with bias adding + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param bias Bias matrix, size (1, 1, 1, h) + */ +void dl_matrix3dff_fc_with_bias(dl_matrix3d_t *out, + dl_matrix3d_t *in, + dl_matrix3d_t *filter, + dl_matrix3d_t *bias); + +// +// Mobilenet +// + +/** + * @brief Do a mobilenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3d + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3dff_mobilenet(dl_matrix3d_t *in, + dl_matrix3d_t *dilate_filter, + dl_matrix3d_t *dilate_prelu, + dl_matrix3d_t *depthwise_filter, + dl_matrix3d_t *depthwise_prelu, + dl_matrix3d_t *compress_filter, + dl_matrix3d_t *bias, + dl_matrix3d_mobilenet_config_t config); + +/** + * @brief Do a mobilenet block forward, dimension is (number, width, height, channel) + * + * @param in Input matrix3du + * @param filter Weights of the neurons + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect + * If ESP_PLATFORM is not defined, this value is not used. Default is 0 + * @return The result of depthwise CNN layer + */ +dl_matrix3d_t *dl_matrix3duf_mobilenet(dl_matrix3du_t *in, + dl_matrix3d_t *dilate_filter, + dl_matrix3d_t *dilate_prelu, + dl_matrix3d_t *depthwise_filter, + dl_matrix3d_t *depthwise_prelu, + dl_matrix3d_t *compress_filter, + dl_matrix3d_t *bias, + dl_matrix3d_mobilenet_config_t config); diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/dl_lib_matrix3dq.h b/tools/sdk/esp32s2/include/esp-face/lib/include/dl_lib_matrix3dq.h new file mode 100644 index 00000000000..0d982b4a0e0 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/dl_lib_matrix3dq.h @@ -0,0 +1,1441 @@ +#pragma once +#include "dl_lib_matrix3d.h" + +typedef int16_t qtp_t; + +/** + * Matrix for input, filter, and output + * @Warning: the sequence of variables is fixed, cannot be modified, otherwise there will be errors in + * some handwrite xtensa instruction functions + */ +typedef struct +{ + /******* fix start *******/ + int w; /*!< Width */ + int h; /*!< Height */ + int c; /*!< Channel */ + int n; /*!< Number of filter, input and output must be 1 */ + int stride; /*!< Step between lines */ + int exponent; /*!< Exponent for quantization */ + qtp_t *item; /*!< Data */ + /******* fix end *******/ +} dl_matrix3dq_t; + +#ifndef DL_QTP_SHIFT +#define DL_QTP_SHIFT 15 +#define DL_ITMQ(m, x, y) m->itemq[(y) + (x)*m->stride] +#define DL_QTP_RANGE ((1 << DL_QTP_SHIFT) - 1) +#define DL_QTP_MAX 32767 +#define DL_QTP_MIN -32768 + +#define DL_QTP_EXP_NA 255 //non-applicable exponent because matrix is null + +#define DL_SHIFT_AUTO 32 +#endif + +/** + * Implementation of matrix relative operations + */ +typedef enum +{ + DL_C_IMPL = 0, /*!< ANSI C */ + DL_XTENSA_IMPL = 1 /*!< Handwrite xtensa instruction */ +} dl_conv_mode; + +/** + * Configuration of mobilenet operation + */ +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ + dl_conv_mode mode; /*!< Implementation mode */ + int dilate_exponent; /*!< Exponent of dilation filter */ + int depthwise_exponent; /*!< Exponent of depthwise filter */ + int compress_exponent; /*!< Exponent of compress filter */ +} dl_matrix3dq_mobilenet_config_t; + +typedef struct +{ + int stride_x; /*!< Strides of width */ + int stride_y; /*!< Strides of height */ + dl_padding_type padding; /*!< Padding type */ + dl_conv_mode mode; /*!< Implementation mode */ + int dw1_exponent; /*!< Exponent of dw1 filter */ + int pw1_exponent; /*!< Exponent of pw1 filter */ + int dw2_exponent; /*!< Exponent of dw2 filter */ + int pw2_exponent; /*!< Exponent of pw2 filter */ + int shortcut; /*!< Shortcut connection flag */ + int save_input; /*!< Input save flag */ +} dl_matrix3dq_blazeblock_config_t; + +// +// Utility +// + +/* + * @brief Allocate a 3d quantised matrix + * + * @param n Number of filters, for input and output, should be 1 + * @param w Width of matrix + * @param h Height of matrix + * @param c Channel of matrix + * @param e Exponent of matrix data + * @return 3d quantized matrix + */ +static inline dl_matrix3dq_t *dl_matrix3dq_alloc(int n, int w, int h, int c, int e) +{ + dl_matrix3dq_t *r = (dl_matrix3dq_t *)dl_lib_calloc(1, sizeof(dl_matrix3dq_t), 0); + if (NULL == r) + { + printf("dl_matrix3dq alloc failed.\n"); + return NULL; + } + + qtp_t *items = (qtp_t *)dl_lib_calloc(n * w * h * c, sizeof(qtp_t), 16); + if (NULL == items) + { + printf("matrix3dq item alloc failed.\n"); + dl_lib_free(r); + return NULL; + } + + r->w = w; + r->h = h; + r->c = c; + r->n = n; + r->exponent = e; + r->stride = w * c; + r->item = items; + + return r; +} + +/* + * @brief Free a 3d quantized matrix + * + * @param m 3d quantised matrix + */ +static inline void dl_matrix3dq_free(dl_matrix3dq_t *m) +{ + if (NULL == m) + return; + if (NULL == m->item) + { + dl_lib_free(m); + return; + } + dl_lib_free(m->item); + dl_lib_free(m); +} + + +/** + * @brief Copy a range of items from an existing matrix to a preallocated matrix + * + * @param dst The resulting slice matrix + * @param src Old matrix to slice. + * @param x X-offset of the origin of the returned matrix within the sliced matrix + * @param y Y-offset of the origin of the returned matrix within the sliced matrix + * @param w Width of the resulting matrix + * @param h Height of the resulting matrix + */ +void dl_matrix3dq_slice_copy(dl_matrix3dq_t *dst, dl_matrix3dq_t *src, int x, int y, int w, int h); + +/** + * @brief Transform a sliced matrix block from nhwc to nchw, the block needs to be memory continous. + * + * @param out The destination sliced matrix in nchw + * @param in The source sliced matrix in nhwc + */ +void dl_matrix3dq_sliced_transform_nchw(dl_matrix3dq_t *out, + dl_matrix3dq_t *in); + +/** + * @brief Transform a fixed point matrix to a float point matrix + * + * @param m Quantized matrix + * @return Float point matrix + */ +dl_matrix3d_t *dl_matrix3d_from_matrixq(dl_matrix3dq_t *m); + +/** + * @brief Transform a float point matrix to a fixed point matrix with pre-defined exponent + * + * @param m Float point matrix + * @param exponent Exponent for resulting matrix + * @return Fixed point matrix + */ +dl_matrix3dq_t *dl_matrixq_from_matrix3d_qmf(dl_matrix3d_t *m, int exponent); + +/** + * @brief Transform a float point matrix to a fixed point matrix. The exponent is defined by the distribution of the input matrix. + * + * @param m Float point matrix + * @return Fixed point matrix + */ +dl_matrix3dq_t *dl_matrixq_from_matrix3d(dl_matrix3d_t *m); + +/** + * @brief Truncate the overflowed 16bit number + * + * @param value Input value + * @param location Location tag + * @return qtp_t Truncated value + */ +qtp_t dl_matrix3dq_quant_range_exceeded_checking(int64_t value, char *location); + +/** + * @brief Reform a quantized matrix with exponent + * + * @param out Preallocated resulting matrix + * @param in Input matrix + * @param exponent Exponent for resulting matrix + */ +void dl_matrix3dq_shift_exponent(dl_matrix3dq_t *out, dl_matrix3dq_t *in, int exponent); + +/** + * @brief Do batch normalization for a quantized matrix + * + * @param m Input and output quantized matrix, data will be updated + * @param scale Scale of batch-norm + * @param offset Offset of batch-norm + */ +void dl_matrix3dq_batch_normalize(dl_matrix3dq_t *m, dl_matrix3dq_t *scale, dl_matrix3dq_t *offset); + +/** + * @brief Add two quantized matrix with a pre-defined exponent + * + * @param in_1 Adder 1 + * @param in_2 Adder 2 + * @param exponent Exponent for resulting matrix + * @return dl_matrix3dq_t* Result of accumulation of two matrix + */ +dl_matrix3dq_t *dl_matrix3dq_add(dl_matrix3dq_t *in_1, dl_matrix3dq_t *in_2, int exponent); + +/** + * @brief Add two quantized matrix with different channels + * + * @param in_1 Adder 1 + * @param in_2 Adder 2 + * @param exponent Exponent for resulting matrix + * @return dl_matrix3dq_t* Result of accumulation of two matrix + */ +dl_matrix3dq_t *dl_matrix3dq_add_channel_diff(dl_matrix3dq_t *in_1, dl_matrix3dq_t *in_2, int exponent); + +// +// Activation +// +/** + * @brief Do relu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + */ +void dl_matrix3dq_relu(dl_matrix3dq_t *in); + +/** + * @brief Do relu with clips for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param clip Float point value to limit the maximum data + */ +void dl_matrix3dq_relu_clip(dl_matrix3dq_t *in, fptp_t clip); + +/** + * @brief Do leaky relu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param alpha Float point value to multiply for those less than zero + * @param clip Float point value to limit the maximum data + */ +void dl_matrix3dq_leaky_relu(dl_matrix3dq_t *in, fptp_t alpha, fptp_t clip); + +/** + * @brief Do prelu for a quantized matrix + * + * @param in Input and output quantized matrix, data will be updated + * @param alpha Quantized matrix to multiply for those less than zero + */ +void dl_matrix3dq_p_relu(dl_matrix3dq_t *in, dl_matrix3dq_t *alpha); + +// +// Concat +// +/** + * @brief Concatenate two quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of in_1 and in_2, and with the sum of channel number of in_1 and in_2 + */ +dl_matrix3dq_t *dl_matrix3dq_concat(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2); + +/** + * @brief Concatenate four quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @param in_3 Quantized matrix to be concatenated + * @param in_4 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of all inputs, and with the sum of channel number of all inputs + */ +dl_matrix3dq_t *dl_matrix3dq_concat_4(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2, + dl_matrix3dq_t *in_3, + dl_matrix3dq_t *in_4); + +/** + * @brief Concatenate four quantized matrix in channel + * + * @param in_1 Quantized matrix to be concatenated + * @param in_2 Quantized matrix to be concatenated + * @param in_3 Quantized matrix to be concatenated + * @param in_4 Quantized matrix to be concatenated + * @param in_5 Quantized matrix to be concatenated + * @param in_6 Quantized matrix to be concatenated + * @param in_7 Quantized matrix to be concatenated + * @param in_8 Quantized matrix to be concatenated + * @return Quantized matrix with the same width and height of all inputs, and with the sum of channel number of all inputs + */ +dl_matrix3dq_t *dl_matrix3dq_concat_8(dl_matrix3dq_t *in_1, + dl_matrix3dq_t *in_2, + dl_matrix3dq_t *in_3, + dl_matrix3dq_t *in_4, + dl_matrix3dq_t *in_5, + dl_matrix3dq_t *in_6, + dl_matrix3dq_t *in_7, + dl_matrix3dq_t *in_8); + +// +// Conv 1x1 +// +/** + * @brief Do 1x1 convolution with a quantized matrix + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with relu activation + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_relu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_bias(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_bias_relu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with a quantized matrix, with prelu activation + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_conv_1x1_with_prelu(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3duq_conv_1x1(dl_matrix3dq_t *out, + dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do 1x1 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param out Preallocated quantized matrix, size (1, w, h, n) + * @param in Input matrix, size (1, w, h, c) + * @param filter 1x1 filter, size (n, 1, 1, c) + * @param bias Bias, size (1, 1, 1, n) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3duq_conv_1x1_with_bias(dl_matrix3dq_t *out, + dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +// +// Conv 3x3 +// + +/** + * @brief Do 3x3 convolution with a quantized matrix + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding, relu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias_relu(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with an 8-bit fixed point matrix, with bias adding + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_conv_3x3_with_bias(dl_matrix3du_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 convolution with an 8-bit fixed point matrix, with bias adding, prelu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param prelu prelu params, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_conv_3x3_with_bias_prelu(dl_matrix3du_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + + +/** + * @brief Do 3x3 convolution with a quantized matrix, with bias adding, prelu activation + * + * @param input Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (n, 3, 3, c) + * @param bias Bias, size (1, 1, 1, n) + * @param prelu prelu params, size (1, 1, 1, n) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_3x3_with_bias_prelu(dl_matrix3dq_t *input, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); +// +// Conv common +// + +/** + * @brief Do a general convolution layer pass, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer. + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect. + * If ESP_PLATFORM is not defined, this value is not used. + * @return The result of CNN layer. + */ +dl_matrix3dq_t *dl_matrix3dqq_conv_common(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +/** + * @brief Do a general convolution layer pass for an 8-bit fixed point matrix, size is (number, width, height, channel) + * + * @param in Input image + * @param filter Weights of the neurons + * @param bias Bias for the CNN layer. + * @param stride_x The step length of the convolution window in x(width) direction + * @param stride_y The step length of the convolution window in y(height) direction + * @param padding One of VALID or SAME + * @param mode Do convolution using C implement or xtensa implement, 0 or 1, with respect. + * If ESP_PLATFORM is not defined, this value is not used. + * @return The result of CNN layer. + */ +dl_matrix3dq_t *dl_matrix3duq_conv_common(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +// +// Depthwise 3x3 +// +/** + * @brief Do 3x3 depthwise convolution with an 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_depthwise_conv_3x3(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param relu ReLU, 0: don't, 1: do + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int relu, + int exponent, + char *name); + +#if CONFIG_DEVELOPING_CODE +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_3(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); +#endif + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding and stride 1 + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3s1_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 3x3 filter, size (1, 3, 3, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 3x3 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 3x3 filter, size (1, 3, 3, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_3x3_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do global depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param filter filter, size (1, w, h, c) + * @param bias Bias, size (1, 1, 1, c) + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_global_depthwise_conv_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + int exponent, + char *name); + + + +// +// Depthwise 2x2 +// +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 2x2 filter, size (1, 2, 2, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 2x2 filter, size (1, 2, 2, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 2x2 filter, size (1, 2, 2, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 2x2 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 2x2 filter, size (1, 2, 2, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_2x2_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +// +// Depthwise 5x5 +// +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 5x5 filter, size (1, 5, 5, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with bias adding + * + * @param in Input matrix, size (1, w, h, c) + * @param f 5x5 filter, size (1, 5, 5, c) + * @param bias Bias, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param exponent Exponent for resulting matrix + * @param relu Whether to use relu activation + * @param name Layer name to debug + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_bias(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + int relu, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param filter 5x5 filter, size (1, 5, 5, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +/** + * @brief Do 5x5 depthwise convolution with a quantized matrix, with bias adding and prelu activation + * + * @param in Input matrix, size (1, w, h, c) + * @param f 5x5 filter, size (1, 5, 5, c) + * @param bias Bias, size (1, 1, 1, c) + * @param prelu prelu params, size (1, 1, 1, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_5x5_with_bias_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *f, + dl_matrix3dq_t *bias, + dl_matrix3dq_t *prelu, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + char *name); + +// +// Depthwise Common +// +#if CONFIG_DEVELOPING_CODE +/** + * @brief Do a general depthwise convolution layer pass with a quantized matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter Weights of the neurons, size (1, k_w, k_h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param mode Implementation mode + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_depthwise_conv_common(dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); + +/** + * @brief Do a general depthwise convolution layer pass with an 8-bit fixed point matrix + * + * @param in Input matrix, size (1, w, h, c) + * @param filter Weights of the neurons, size (1, k_w, k_h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type + * @param exponent Exponent for resulting matrix + * @param mode Implementation mode + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_depthwise_conv_common(dl_matrix3du_t *in, + dl_matrix3dq_t *filter, + int stride_x, + int stride_y, + dl_padding_type padding, + int exponent, + dl_conv_mode mode); +#endif + +// +// Dot Product +// + +/** + * @brief Do dot product operation with a quantized matrix + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param mode Implementation mode + */ +void dl_matrix3dqq_dot_product(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode); + +// +// FC +// +/** + * @brief Do fully connected layer forward. + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_fc(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_conv_mode mode, + char *name); + +/** + * @brief Do fully connected layer forward, with bias adding + * + * @param out Preallocated resulting matrix, size (1, 1, 1, h) + * @param in Input matrix, size (1, 1, 1, w) + * @param filter Filter matrix, size (1, w, h, 1) + * @param bias Bias matrix, size (1, 1, 1, h) + * @param mode Implementation mode + * @param name Layer name to debug + */ +void dl_matrix3dqq_fc_with_bias(dl_matrix3dq_t *out, + dl_matrix3dq_t *in, + dl_matrix3dq_t *filter, + dl_matrix3dq_t *bias, + dl_conv_mode mode, + char *name); + +// +// Mobilefaceblock +// +/** + * @brief Do mobilefacenet process with splited pointwise 1x1 convolution, the process sequence is 1x1 pointwise->bn->relu->3x3 depthwise->bn->relu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw_1 Pointwise 1x1 filter, size (n1/2, 1, 1, c) + * @param pw_2 Pointwise 1x1 filter, size (n1/2, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw_linear_1 Pointwise 1x1 filter, size (n2/2, 1, 1, n1) + * @param pw_linear_2 Pointwise 1x1 filter, size (n2/2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_split(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->relu->3x3 depthwise->bn->relu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw_linear Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Padding type, 0: valid, 1: same + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *pw_linear, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->prelu->3x3 depthwise->bn->prelu->1x1 pointwise->bn + * + * @param in Input matrix, size (1, w, h, c) + * @param pw Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw_bias Pointwise bias, size (1, 1, 1, n1) + * @param pw_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param dw Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param dw_bias Depthwise bias, size (1, 1, 1, n1) + * @param dw_prelu Depthwise prelu, size(1, 1, 1, n1) + * @param pw_linear Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw_linear_bias Pointwise bias, size (1, 1, 1, n2) + * @param pw_exponent Exponent for pointwise resulting matrix + * @param dw_exponent Exponent for depthwise resulting matrix + * @param pw_linear_exponent Exponent for pointwise resulting matrix + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param padding Depthwise Convlution Padding type + * @param mode Implementation mode + * @param shortcut Whether has a shortcut at pointwise linear + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +/**@{*/ +/** + * @brief Do mobilefacenet process, the process sequence is 1x1 pointwise->bn->prelu->3x3 depthwise->bn->prelu->1x1 pointwise->bn + * + * Compared to ‘dl_matrix3dqq_mobilefaceblock_prelu’, this family of functions 'dl_matrix3dqq_mobilefaceblock_prelu_split_x1_x2' + * split the first pointwise convlution into x1 pointwise convlutions, and split the second pointwise convlution into x2 pointwise convlutions. + * + * + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_2_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_4_4(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw_1, + dl_matrix3dq_t *pw_2, + dl_matrix3dq_t *pw_3, + dl_matrix3dq_t *pw_4, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_3, + dl_matrix3dq_t *pw_linear_4, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); + +dl_matrix3dq_t *dl_matrix3dqq_mobilefaceblock_prelu_split_1_2(dl_matrix3dq_t *in, + dl_matrix3dq_t *pw, + dl_matrix3dq_t *pw_bias, + dl_matrix3dq_t *pw_prelu, + dl_matrix3dq_t *dw, + dl_matrix3dq_t *dw_bias, + dl_matrix3dq_t *dw_prelu, + dl_matrix3dq_t *pw_linear_1, + dl_matrix3dq_t *pw_linear_2, + dl_matrix3dq_t *pw_linear_bias, + int pw_exponent, + int dw_exponent, + int pw_linear_exponent, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_conv_mode mode, + int shortcut); +/**@}*/ + +// +// blazeblock +// + +/** + * @brief Do blazeblock process, the process sequence is depthwise->bn->1x1 pointwise->bn->shortcut->relu + * + * @param in Input matrix, size (1, w, h, c) + * @param dw1_kernel Depthwise filter, size (1, k, k, c) + * @param dw1_bias Depthwise bias, size (1, 1, 1, c) + * @param pw1_kernel Pointwise 1x1 filter, size (n, 1, 1, c) + * @param pw1_bias Pointwise bias, size (1, 1, 1, n) + * @param config blazeblock configuration + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_blazeblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *dw1_kernel, + dl_matrix3dq_t *dw1_bias, + dl_matrix3dq_t *pw1_kernel, + dl_matrix3dq_t *pw1_bias, + dl_matrix3dq_blazeblock_config_t config, + char *name); + +/** + * @brief Do double blazeblock process, the process sequence is depthwise->bn->1x1 pointwise->bn->relu->depthwise->bn->1x1 pointwise->bn->shortcut->relu + * + * @param in Input matrix, size (1, w, h, c) + * @param dw1_kernel Depthwise filter, size (1, k, k, c) + * @param dw1_bias Depthwise bias, size (1, 1, 1, c) + * @param pw1_kernel Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param pw1_bias Pointwise bias, size (1, 1, 1, n1) + * @param dw2_kernel Depthwise filter, size (1, k, k, n1) + * @param dw2_bias Depthwise bias, size (1, 1, 1, n1) + * @param pw2_kernel Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param pw2_bias Pointwise bias, size (1, 1, 1, n2) + * @param config blazeblock configuration + * @param name Layer name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_double_blazeblock(dl_matrix3dq_t *in, + dl_matrix3dq_t *dw1_kernel, + dl_matrix3dq_t *dw1_bias, + dl_matrix3dq_t *pw1_kernel, + dl_matrix3dq_t *pw1_bias, + dl_matrix3dq_t *dw2_kernel, + dl_matrix3dq_t *dw2_bias, + dl_matrix3dq_t *pw2_kernel, + dl_matrix3dq_t *pw2_bias, + dl_matrix3dq_blazeblock_config_t config, + char *name); +// +// Mobilenet +// + +/** + * @brief Do mobilenet process, the process sequence is 1x1 dilated->prelu->3x3 depthwise->prelu->1x1 compress->bias + * + * @param in Input matrix, size (1, w, h, c) + * @param dilate Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param dilate_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param depthwise Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param depthwise_prelu Depthwise prelu, size (1, 1, 1, n1) + * @param compress Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param bias Pointwise bias, size (1, 1, 1, n2) + * @param config Mobilenet configuration + * @param name Block name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3dqq_mobilenet(dl_matrix3dq_t *in, + dl_matrix3dq_t *dilate, + dl_matrix3dq_t *dilate_prelu, + dl_matrix3dq_t *depthwise, + dl_matrix3dq_t *depth_prelu, + dl_matrix3dq_t *compress, + dl_matrix3dq_t *bias, + dl_matrix3dq_mobilenet_config_t config, + char *name); + +/** + * @brief Do mobilenet process, the process sequence is 1x1 dilated->prelu->3x3 depthwise->prelu->1x1 compress->bias + * + * @param in Input matrix, 8-bit fixed point, size (1, w, h, c) + * @param dilate Pointwise 1x1 filter, size (n1, 1, 1, c) + * @param dilate_prelu Pointwise prelu, size (1, 1, 1, n1) + * @param depthwise Depthwise 3x3 filter, size (1, 3, 3, n1) + * @param depthwise_prelu Depthwise prelu, size (1, 1, 1, n1) + * @param compress Pointwise 1x1 filter, size (n2, 1, 1, n1) + * @param bias Pointwise bias, size (1, 1, 1, n2) + * @param config Mobilenet configuration + * @param name Block name to debug + * @return dl_matrix3dq_t* Resulting quantized matrix + */ +dl_matrix3dq_t *dl_matrix3duq_mobilenet(dl_matrix3du_t *in, + dl_matrix3dq_t *dilate, + dl_matrix3dq_t *dilate_prelu, + dl_matrix3dq_t *depthwise, + dl_matrix3dq_t *depth_prelu, + dl_matrix3dq_t *compress, + dl_matrix3dq_t *bias, + dl_matrix3dq_mobilenet_config_t config, + char *name); + +// +// Padding +// + +/**@{*/ +/** + * @brief This family of functions do a padding operation before a convlution + * + * @param padded_input the padded result pointer + * @param output_height the output height pointer + * @param output_width the output width pointer + * @param input Input matrix, size (1, w, h, c) + * @param stride_x Stride of width + * @param stride_y Stride of height + * @param kernel_size Kernel size of the next convlution + * @param padding_type Padding type + * @return dl_error_type Return DL_SUCCESS if padding successfully, else return DL_FAIL + */ +dl_error_type dl_matrix3dqq_padding(dl_matrix3dq_t **padded_input, + int *output_height, + int *output_width, + dl_matrix3dq_t *input, + int stride_x, + int stride_y, + int kernel_size, + dl_padding_type padding_type); + +dl_error_type dl_matrix3duq_padding(dl_matrix3du_t **padded_input, + int *output_height, + int *output_width, + dl_matrix3du_t *input, + int stride_x, + int stride_y, + int kernel_size, + dl_padding_type padding_type); +/**@}*/ + +// +// Upsample +// +/** + * @brief Upsample a feature map to twice the size + * + * @param in Input matrix, size (1, w, h, c) + * @param upsample upsample type + * @return dl_matrix3dq_t* Resulting matrix, size (1, 2*w, 2*h, c) + */ +dl_matrix3dq_t *dl_matrix3dqq_upsample_2x(dl_matrix3dq_t *in, + dl_upsample_type upsample); + +// +// Pooling +// +/** + * @brief Calculate average value of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @return dl_matrix3dq_t* Resulting matrix, size (1, 1, 1, c) + */ +dl_matrix3dq_t *dl_matrix3dq_global_pool(dl_matrix3dq_t *in); + +/** + * @brief Calculate pooling layer of a feature map + * + * @param in Input matrix, size (1, w, h, c) + * @param f_w Window width + * @param f_h Window height + * @param stride_x Stride in horizontal direction + * @param stride_y Stride in vertical direction + * @param padding Padding type: PADDING_VALID and PADDING_SAME + * @param pooling_type Pooling type: DL_POOLING_MAX and POOLING_AVG + * @return dl_matrix3dq_t* Resulting matrix, size (1, w', h', c) + */ +dl_matrix3dq_t *dl_matrix3dq_pooling(dl_matrix3dq_t *in, + int f_w, + int f_h, + int stride_x, + int stride_y, + dl_padding_type padding, + dl_pooling_type pooling_type); diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/frmn.h b/tools/sdk/esp32s2/include/esp-face/lib/include/frmn.h new file mode 100644 index 00000000000..c1f08a0fadc --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/frmn.h @@ -0,0 +1,43 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * @brief Forward the face recognition process with frmn model. Calculate in float. + * + * @param in Image matrix, rgb888 format, size is 56x56, normalized + * @return dl_matrix3d_t* Face ID feature vector, size is 512 + */ + dl_matrix3d_t *frmn(dl_matrix3d_t *in); + + /**@{*/ + /** + * @brief Forward the face recognition process with specified model. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 56x56, normalized + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return Face ID feature vector, size is 512 + */ + dl_matrix3dq_t *frmn_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *frmn2p_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_42m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_72m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_112m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + dl_matrix3dq_t *mfn56_156m_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /**@}*/ + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/hd_model.h b/tools/sdk/esp32s2/include/esp-face/lib/include/hd_model.h new file mode 100644 index 00000000000..0bc28d70ddc --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/hd_model.h @@ -0,0 +1,66 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + typedef struct + { + int num; /*!< The total number of the boxes */ + dl_matrix3d_t *cls; /*!< The class feature map corresponding to the box. size: (height, width, anchor_num, 1) */ + dl_matrix3d_t *score; /*!< The confidence score feature map of the class corresponding to the box. size: (height, width, anchor_num, 1) */ + dl_matrix3d_t *boxes; /*!< (x, y, w, h) of the boxes. x and y are the center coordinates. size:(height, width, anchor_num, 4) */ + } detection_result_t; + + /** + * @brief Forward the hand detection process with hd_nano1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its width and height must be integer multiples of 16. + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return detection_result_t** Detection results + */ + detection_result_t **hd_nano1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Forward the hand detection process with hd_lite1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its width and height must be integer multiples of 32. + * @param mode 0: C implement; 1: handwrite xtensa instruction implement. + * @return detection_result_t** Detection results. + */ + detection_result_t **hd_lite1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Free the single detection result. + * + * @param m The single detection result. + */ + void detection_result_free(detection_result_t *m); + + /** + * @brief Free the detection result group from different feature map. + * + * @param m The detection result group + * @param length The number of the detection results + */ + void detection_results_free(detection_result_t **m, int length); + + /** + * @brief Test the result of hand detection model. + * + */ + void hd_test(); + + /** + * @brief Test the forward time of hand detection model. + * + */ + void hd_time_test(); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/hp_model.h b/tools/sdk/esp32s2/include/esp-face/lib/include/hp_model.h new file mode 100644 index 00000000000..ad9080c5473 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/hp_model.h @@ -0,0 +1,43 @@ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * @brief Forward the hand pose estimation process with hp_nano1_ls16 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its size is (1, 128, 128, 3). + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return dl_matrix3d_t* The resulting hand joint point coordinates, the size is (1, 1, 21, 2) + */ + dl_matrix3d_t *hp_nano1_ls16_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Forward the hand pose estimation process with hp_lite1 model. Calculate in quantization. + * + * @param in A normalized image matrix in rgb888 format, its size is (1, 128, 128, 3). + * @param mode 0: C implement; 1: handwrite xtensa instruction implement + * @return dl_matrix3d_t* The resulting hand joint point coordinates, the size is (1, 1, 21, 2) + */ + dl_matrix3d_t *hp_lite1_q(dl_matrix3dq_t *in, dl_conv_mode mode); + + /** + * @brief Test the result of hand pose estimation model. + * + */ + void hp_test(); + + /** + * @brief Test the forward time of hand pose estimation model. + * + */ + void hp_time_test(); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/lssh.h b/tools/sdk/esp32s2/include/esp-face/lib/include/lssh.h new file mode 100644 index 00000000000..69c661c58e5 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/lssh.h @@ -0,0 +1,91 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" +#include "freertos/FreeRTOS.h" + + typedef struct + { + int resized_height; + int resized_width; + fptp_t y_resize_scale; + fptp_t x_resize_scale; + int enabled_top_k; + fptp_t score_threshold; + fptp_t nms_threshold; + + dl_conv_mode mode; + } lssh_config_t; + + typedef struct + { + int *anchor_size; + int stride; + int boundary; + } lssh_module_config_t; + + typedef struct + { + lssh_module_config_t *module_config; + int number; + } lssh_modules_config_t; + + typedef struct + { + dl_matrix3d_t *category; + dl_matrix3d_t *box_offset; + dl_matrix3d_t *landmark_offset; + } lssh_module_result_t; + + /** + * @brief + * + * @param value + */ + void lssh_module_result_free(lssh_module_result_t value); + + /** + * @brief + * + * @param values + * @param length + */ + void lssh_module_results_free(lssh_module_result_t *values, int length); + + ///////////////////////// + //////sparse_mn_5_q////// + ///////////////////////// + extern lssh_modules_config_t sparse_mn_5_modules_config; + lssh_module_result_t *sparse_mn_5_q_without_landmark(dl_matrix3du_t *image, bool free_image, int enabled_top_k, dl_conv_mode mode); + lssh_module_result_t *sparse_mn_5_q_with_landmark(dl_matrix3du_t *image, bool free_image, int enabled_top_k, dl_conv_mode mode); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/lib/include/mtmn.h b/tools/sdk/esp32s2/include/esp-face/lib/include/mtmn.h new file mode 100644 index 00000000000..609a82ea488 --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/lib/include/mtmn.h @@ -0,0 +1,142 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "dl_lib_matrix3d.h" +#include "dl_lib_matrix3dq.h" + + /** + * Detection results with MTMN. + * + */ + typedef struct + { + dl_matrix3d_t *category; /*!< Classification result after softmax, channel is 2 */ + dl_matrix3d_t *offset; /*!< Bounding box offset of 2 points: top-left and bottom-right, channel is 4 */ + dl_matrix3d_t *landmark; /*!< Offsets of 5 landmarks: + * - Left eye + * - Mouth leftside + * - Nose + * - Right eye + * - Mouth rightside + * + * channel is 10 + * */ + } mtmn_net_t; + + + /** + * @brief Free a mtmn_net_t + * + * @param p A mtmn_net_t pointer + * + */ + + void mtmn_net_t_free(mtmn_net_t *p); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in float. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_lite_f(dl_matrix3du_t *in); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in float. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_lite_f_with_score_verify(dl_matrix3du_t *in, float threshold); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in float. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_lite_f_with_score_verify(dl_matrix3du_t *in, float threshold); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_lite_q(dl_matrix3du_t *in, dl_conv_mode mode); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_lite_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_lite_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the pnet process, coarse detection. Calculate in quantization. + * + * @param in Image matrix, rgb888 format, size is 320x240 + * @return Scores for every pixel, and box offset with respect. + */ + mtmn_net_t *pnet_heavy_q(dl_matrix3du_t *in, dl_conv_mode mode); + + /** + * @brief Forward the rnet process, fine determine the boxes from pnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, and box offset with respect. + */ + mtmn_net_t *rnet_heavy_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + + /** + * @brief Forward the onet process, fine determine the boxes from rnet. Calculate in quantization. + * + * @param in Image matrix, rgb888 format + * @param threshold Score threshold to detect human face + * @return Scores for every box, box offset, and landmark with respect. + */ + mtmn_net_t *onet_heavy_q_with_score_verify(dl_matrix3du_t *in, float threshold, dl_conv_mode mode); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/object_detection/include/object_detection.h b/tools/sdk/esp32s2/include/esp-face/object_detection/include/object_detection.h new file mode 100644 index 00000000000..8627a24684d --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/object_detection/include/object_detection.h @@ -0,0 +1,59 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "detection.h" +// Include models +#include "cat_face_3.h" + + /** + * @brief update detection hyperparameter + * + * @param model The detection model + * @param resize_scale The resize scale of input image + * @param score_threshold Score threshold, used to filter candidates by score + * @param nms_threshold NMS threshold, used to filter out overlapping boxes + * @param image_height Input image height + * @param image_width Input image width + */ + void update_detection_model(detection_model_t *model, fptp_t resize_scale, fptp_t score_threshold, fptp_t nms_threshold, int image_height, int image_width); + + /** + * @brief + * + * @param image The input image + * @param model A 'detection_model_t' type point of detection model + * @return box_array_t* The detection result with box and corresponding score and category + */ + box_array_t *detect_object(dl_matrix3du_t *image, detection_model_t *model); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp-face/pose_estimation/include/pe_forward.h b/tools/sdk/esp32s2/include/esp-face/pose_estimation/include/pe_forward.h new file mode 100644 index 00000000000..0d52b1f803e --- /dev/null +++ b/tools/sdk/esp32s2/include/esp-face/pose_estimation/include/pe_forward.h @@ -0,0 +1,153 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is 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. + * + */ +#pragma once + +#if __cplusplus +extern "C" +{ +#endif + +#include "image_util.h" +#include "dl_lib_matrix3d.h" +#include "hd_model.h" +#include "hp_model.h" + +#define INPUT_EXPONENT -10 +#define SCORE_THRESHOLD 0.5 +#define NMS_THRESHOLD 0.45 + +#if CONFIG_HD_LITE1 + #define HP_TARGET_SIZE 128 +#else + #define HP_TARGET_SIZE 128 +#endif + + typedef struct + { + int target_size; /*!< The input size of hand detection network */ + fptp_t score_threshold; /*!< score threshold, used to filter candidates by score */ + fptp_t nms_threshold; /*!< nms threshold, used to filter out overlapping boxes */ + } hd_config_t; + + /** + * @brief Get the default hand detection network configuration + * + * @return hd_config_t The default configuration + */ + static inline hd_config_t hd_init_config() + { + hd_config_t hd_config; + hd_config.target_size = 96; + hd_config.score_threshold = SCORE_THRESHOLD; + hd_config.nms_threshold = NMS_THRESHOLD; + return hd_config; + } + + typedef struct tag_od_box_list + { + fptp_t *score; /*!< The confidence score of the class corresponding to the box */ + qtp_t *cls; /*!< The class corresponding to the box */ + box_t *box; /*!< (x1, y1, x2, y2) of the boxes */ + int len; /*!< The number of the boxes */ + } od_box_array_t; + + typedef struct tag_od_image_box + { + struct tag_od_image_box *next; /*!< Next od_image_box_t */ + fptp_t score; /*!< The confidence score of the class corresponding to the box */ + qtp_t cls; /*!< The class corresponding to the box */ + box_t box; /*!< (x1, y1, x2, y2) of the boxes */ + } od_image_box_t; + + typedef struct tag_od_image_list + { + od_image_box_t *head; /*!< The current head of the od_image_list */ + od_image_box_t *origin_head; /*!< The original head of the od_image_list */ + int len; /*!< Length of the od_image_list */ + } od_image_list_t; + + /** + * @brief Sort the resulting box lists by their confidence score. + * + * @param image_sorted_list The sorted box list. + * @param insert_list The box list that have not been sorted. + */ + void od_image_sort_insert_by_score(od_image_list_t *image_sorted_list, const od_image_list_t *insert_list); + + /** + * @brief Filter out the resulting boxes whose confidence score is lower than the threshold and convert the boxes to the actual boxes on the original image.((x, y, w, h) -> (x1, y1, x2, y2)) + * + * @param score Confidence score of the boxes. + * @param cls Class of the boxes. + * @param boxes (x, y, w, h) of the boxes. x and y are the center coordinates. + * @param height Height of the detection output feature map. + * @param width Width of the detection output feature map. + * @param anchor_number Anchor number of the detection output feature map. + * @param score_threshold Threshold of the confidence score. + * @param resize_scale Resize scale: target_size/orignal_size. + * @param padding_w Width padding in preporcess. + * @param padding_h Height padding in preporcess. + * @return od_image_list_t* Resulting valid boxes. + */ + od_image_list_t *od_image_get_valid_boxes(fptp_t *score, + fptp_t *cls, + fptp_t *boxes, + int height, + int width, + int anchor_number, + fptp_t score_threshold, + fptp_t resize_scale, + int padding_w, + int padding_h); + + /** + * @brief Run NMS algorithm + * + * @param image_list The input boxes list + * @param nms_threshold NMS threshold + */ + void od_image_nms_process(od_image_list_t *image_list, fptp_t nms_threshold); + + /** + * @brief Do hand detection, return box infomation. + * + * @param image Image matrix, rgb888 format + * @param hd_config Configuration of hand detection + * @return od_box_array_t* A list of boxes, score and class. + */ + od_box_array_t *hand_detection_forward(dl_matrix3du_t *image, hd_config_t hd_config); + + /** + * @brief Do hand pose estimation, return 21 landmarks of each hand. + * + * @param image Image matrix, rgb888 format + * @param od_boxes The output of the hand detection network + * @param target_size The input size of hand pose estimation network + * @return dl_matrix3d_t* The coordinates of 21 landmarks on the input image for each hand, size (n, 1, 21, 2) + */ + dl_matrix3d_t *handpose_estimation_forward(dl_matrix3du_t *image, od_box_array_t *od_boxes, int target_size); + +#if __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp_https_server/include/esp_https_server.h b/tools/sdk/esp32s2/include/esp_https_server/include/esp_https_server.h index 00565a963ad..efe726e9e70 100644 --- a/tools/sdk/esp32s2/include/esp_https_server/include/esp_https_server.h +++ b/tools/sdk/esp32s2/include/esp_https_server/include/esp_https_server.h @@ -10,6 +10,7 @@ #include #include "esp_err.h" #include "esp_http_server.h" +#include "esp_tls.h" #ifdef __cplusplus extern "C" { @@ -20,6 +21,22 @@ typedef enum { HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled } httpd_ssl_transport_mode_t; +/** + * @brief Callback data struct, contains the ESP-TLS connection handle + */ +typedef struct esp_https_server_user_cb_arg { + const esp_tls_t *tls; +} esp_https_server_user_cb_arg_t; + +/** + * @brief Callback function prototype + * Can be used to get connection or client information (SSL context) + * E.g. Client certificate, Socket FD, Connection state, etc. + * + * @param user_cb Callback data struct + */ +typedef void esp_https_server_user_cb(esp_https_server_user_cb_arg_t *user_cb); + /** * HTTPS server config struct * @@ -66,6 +83,9 @@ struct httpd_ssl_config { /** Enable tls session tickets */ bool session_tickets; + + /** User callback for esp_https_server */ + esp_https_server_user_cb *user_cb; }; typedef struct httpd_ssl_config httpd_ssl_config_t; @@ -113,6 +133,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t; .port_secure = 443, \ .port_insecure = 80, \ .session_tickets = false, \ + .user_cb = NULL, \ } /** diff --git a/tools/sdk/esp32s2/include/esp_hw_support/include/esp_sleep.h b/tools/sdk/esp32s2/include/esp_hw_support/include/esp_sleep.h index cfdfbc04186..75d2f9726c3 100644 --- a/tools/sdk/esp32s2/include/esp_hw_support/include/esp_sleep.h +++ b/tools/sdk/esp32s2/include/esp_hw_support/include/esp_sleep.h @@ -44,6 +44,7 @@ typedef enum { #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core #endif + ESP_PD_DOMAIN_RTC8M, //!< Internal 8M oscillator ESP_PD_DOMAIN_VDDSDIO, //!< VDD_SDIO ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; diff --git a/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_io.h b/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_io.h index eebcabf42b4..330f4d9a165 100644 --- a/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_io.h +++ b/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_io.h @@ -65,6 +65,22 @@ esp_err_t esp_lcd_panel_io_tx_color(esp_lcd_panel_io_handle_t io, int lcd_cmd, c */ esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io); +/** + * @brief Type of LCD panel IO event data + */ +typedef struct { +} esp_lcd_panel_io_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] edata Panel IO event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); + /** * @brief Panel IO configuration structure, for SPI interface */ @@ -74,8 +90,8 @@ typedef struct { int spi_mode; /*!< Traditional SPI mode (0~3) */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Size of internal transaction queue */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { @@ -100,8 +116,8 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p typedef struct { uint32_t dev_addr; /*!< I2C device address */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data transfer has finished */ - void *user_data; /*!< User private data, passed directly to on_trans_frame_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ size_t control_phase_bytes; /*!< I2C LCD panel will encode control information (e.g. D/C seclection) into control phase, in several bytes */ unsigned int dc_bit_offset; /*!< Offset of the D/C selection bit in control phase */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ @@ -168,8 +184,8 @@ typedef struct { int cs_gpio_num; /*!< GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus */ unsigned int pclk_hz; /*!< Frequency of pixel clock */ size_t trans_queue_depth; /*!< Transaction queue size, larger queue, higher throughput */ - bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); /*!< Callback, invoked when color data was tranferred done */ - void *user_data; /*!< User private data, passed directly to on_trans_done's user_data */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data was tranferred done */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { diff --git a/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_rgb.h b/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_rgb.h index 2ddd2b6b9a6..1368bb787f6 100644 --- a/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_rgb.h +++ b/tools/sdk/esp32s2/include/esp_lcd/include/esp_lcd_panel_rgb.h @@ -18,6 +18,37 @@ extern "C" { #if SOC_LCD_RGB_SUPPORTED /** * @brief LCD RGB timing structure + * + * Total Width + * <---------------------------------------------------> + * Hsync width HBP Active Width HFP + * <---><--><--------------------------------------><---> + * ____ ____|_______________________________________|____| + * |___| | | | + * | | | + * __| | | | + * /|\ /|\ | | | | + * | VSYNC| | | | | + * |Width\|/ |__ | | | + * | /|\ | | | | + * | VBP | | | | | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | / / / / / / / / / / / / / / / / / / / | | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Total | | | |/ / / / / / / / / / / / / / / / / / / /| | + * Heigh | | | |/ / / / / / / / / / / / / / / / / / / /| | + * |Active| | |/ / / / / / / / / / / / / / / / / / / /| | + * |Heigh | | |/ / / / / / Active Display Area / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | | | |/ / / / / / / / / / / / / / / / / / / /| | + * | \|/_____|_________|_______________________________________| | + * | /|\ | | + * | VFP | | | + * \|/ \|/_____|______________________________________________________| + * */ typedef struct { unsigned int pclk_hz; /*!< Frequency of pixel clock */ @@ -38,6 +69,22 @@ typedef struct { } flags; } esp_lcd_rgb_timing_t; +/** + * @brief Type of RGB LCD panel event data + */ +typedef struct { +} esp_lcd_rgb_panel_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel LCD panel handle, returned from `esp_lcd_new_rgb_panel` + * @param[in] edata Panel event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_rgb_panel_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_rgb_panel_frame_trans_done_cb_t)(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx); + /** * @brief LCD RGB panel configuration structure */ @@ -51,8 +98,8 @@ typedef struct { int pclk_gpio_num; /*!< GPIO used for PCLK signal */ int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; /*!< GPIOs used for data lines */ int disp_gpio_num; /*!< GPIO used for display control signal, set to -1 if it's not used */ - bool (*on_frame_trans_done)(esp_lcd_panel_handle_t panel, void *user_data); /*!< Callback, invoked when one frame buffer has transferred done */ - void *user_data; /*!< User data which would be passed to on_frame_trans_done's user_data */ + esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; /*!< Callback invoked when one frame buffer has transferred done */ + void *user_ctx; /*!< User data which would be passed to on_frame_trans_done's user_ctx */ struct { unsigned int disp_active_low: 1; /*!< If this flag is enabled, a low level of display control signal can turn the screen on; vice versa */ unsigned int relax_on_idle: 1; /*!< If this flag is enabled, the host won't refresh the LCD if nothing changed in host's frame buffer (this is usefull for LCD with built-in GRAM) */ diff --git a/tools/sdk/esp32s2/include/esp_littlefs/include/esp_littlefs.h b/tools/sdk/esp32s2/include/esp_littlefs/include/esp_littlefs.h index dbb1028790d..7b5abe9248f 100644 --- a/tools/sdk/esp32s2/include/esp_littlefs/include/esp_littlefs.h +++ b/tools/sdk/esp32s2/include/esp_littlefs/include/esp_littlefs.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include "sdkconfig.h" diff --git a/tools/sdk/esp32s2/include/esp_rom/include/esp32c3/rom/newlib.h b/tools/sdk/esp32s2/include/esp_rom/include/esp32c3/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32s2/include/esp_rom/include/esp32c3/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp_rom/include/esp32h2/rom/newlib.h b/tools/sdk/esp32s2/include/esp_rom/include/esp32h2/rom/newlib.h new file mode 100644 index 00000000000..a852bdb7f5b --- /dev/null +++ b/tools/sdk/esp32s2/include/esp_rom/include/esp32h2/rom/newlib.h @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables used by newlib in ROM + + Note that any of these symbols which are used by both ROM & IDF will have duplicate copies + in each "side" of the memory. However they're all pointers, and the pointers will be to the same + thing, so it's not a big memory waste and functionality is the same. + + Some variables which look like they should be here, but aren't: + + - __sf_fake_stdin, __sf_fake_stdout, __sf_fake_stderr - These are defined in ROM because ROM includes findfp.c, + but only used if _REENT_INIT or _REENT_INIT_PTR are ever called and ROM doesn't use these macros anywhere unless + printf() or similar is called without initializing reent first. ESP-IDF sets up its own minimal reent structures. + + - __lock___sinit_recursive_mutex, etc. - these are combined into common_recursive_mutex & common_mutex to save space +*/ +typedef struct { + _LOCK_T common_recursive_mutex; + _LOCK_T common_mutex; + struct _reent *global_reent; +} esp_rom_newlib_global_data_t; + +/* Called from IDF newlib component setup + to initialize common data shared between ROM and IDF +*/ +void esp_rom_newlib_init_global_data(const esp_rom_newlib_global_data_t *data); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist.h b/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist.h index 1ff624d9b55..14b7c9aa506 100644 --- a/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist.h +++ b/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist.h @@ -1,16 +1,8 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_H__ #define __ESP_COEXIST_H__ @@ -32,6 +24,13 @@ typedef enum { ESP_COEX_PREFER_NUM, /*!< Prefer value numbers */ } esp_coex_prefer_t; +typedef enum { + EXTERN_COEX_WIRE_1 = 0, + EXTERN_COEX_WIRE_2, + EXTERN_COEX_WIRE_3, + EXTERN_COEX_WIRE_NUM, +} external_coex_wire_t; + /** * @brief coex status type */ @@ -41,6 +40,36 @@ typedef enum { ESP_COEX_ST_TYPE_BT, } esp_coex_status_type_t; +/** + * @brief external coex gpio pti + */ +typedef struct { + int32_t in_pin0; + int32_t in_pin1; + int32_t out_pin0; +} esp_external_coex_gpio_set_t; + +/** + * @brief external coex pti level + */ +typedef enum { + EXTERN_COEX_PTI_MID = 0, + EXTERN_COEX_PTI_HIGH, + EXTERN_COEX_PTI_NUM, +} esp_coex_pti_level_t; + +/** + * @brief external coex pti + */ +typedef struct { + uint32_t in_pti1; + uint32_t in_pti2; + uint32_t in_pti3; + uint32_t out_pti1; + uint32_t out_pti2; + uint32_t out_pti3; +} esp_external_coex_pti_set_t; + #define ESP_COEX_BLE_ST_MESH_CONFIG 0x08 #define ESP_COEX_BLE_ST_MESH_TRAFFIC 0x10 #define ESP_COEX_BLE_ST_MESH_STANDBY 0x20 @@ -84,6 +113,18 @@ esp_err_t esp_coex_status_bit_set(esp_coex_status_type_t type, uint32_t status); */ esp_err_t esp_coex_status_bit_clear(esp_coex_status_type_t type, uint32_t status); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Setup gpio pin and corresponding pti level, start external coex. + * @param wire_type : to select the whole external coex gpio number. + * @param gpio_pin : gpio pin number to choose. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, + esp_external_coex_gpio_set_t gpio_pin); + +esp_err_t esp_disable_extern_coex_gpio_pin(); +#endif #ifdef __cplusplus } diff --git a/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist_internal.h b/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist_internal.h index 3501f0da6fb..7ba06d4c690 100644 --- a/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist_internal.h +++ b/tools/sdk/esp32s2/include/esp_wifi/include/esp_coexist_internal.h @@ -1,21 +1,14 @@ -// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_COEXIST_INTERNAL_H__ #define __ESP_COEXIST_INTERNAL_H__ #include +#include "esp_coexist.h" #include "esp_coexist_adapter.h" #ifdef __cplusplus @@ -210,6 +203,29 @@ int coex_schm_curr_phase_idx_get(void); */ esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); +#if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Set external coexistence pti level and enable it. + * + * @param level1 external coex low pti + * @param level2 external coex mid pti + * @param level3 external coex high pti + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_coex_external_set(esp_coex_pti_level_t level1, + esp_coex_pti_level_t level2, esp_coex_pti_level_t level3); + +/** + * @brief Disable external coexist + * + * @return + * - ESP_OK: succeed + */ +void esp_coex_external_stop(void); +#endif /*External Coex*/ + /** * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library * diff --git a/tools/sdk/esp32s2/include/esp_wifi/include/esp_wifi_types.h b/tools/sdk/esp32s2/include/esp_wifi/include/esp_wifi_types.h index 503e8d7bb05..cee23f3fafc 100644 --- a/tools/sdk/esp32s2/include/esp_wifi/include/esp_wifi_types.h +++ b/tools/sdk/esp32s2/include/esp_wifi/include/esp_wifi_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef __ESP_WIFI_TYPES_H__ @@ -80,6 +72,7 @@ typedef enum { WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, WIFI_REASON_IE_INVALID = 13, WIFI_REASON_MIC_FAILURE = 14, WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, @@ -250,7 +243,8 @@ typedef struct { wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. */ uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ - uint32_t reserved:30; /**< Reserved for future feature set */ + uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */ + uint32_t reserved:29; /**< Reserved for future feature set */ } wifi_sta_config_t; /** @brief Configuration data for ESP32 AP or STA. diff --git a/tools/sdk/esp32s2/include/freertos/include/esp_additions/FreeRTOSConfig.h b/tools/sdk/esp32s2/include/freertos/include/esp_additions/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/include/esp_additions/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32s2/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h b/tools/sdk/esp32s2/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h index a01a56e9fd4..675af141ebc 100644 --- a/tools/sdk/esp32s2/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h +++ b/tools/sdk/esp32s2/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h @@ -90,7 +90,6 @@ #define portNUM_PROCESSORS 1 #endif -#define configASSERT_2 0 #define portUSING_MPU_WRAPPERS 0 #define configUSE_MUTEX 1 @@ -206,7 +205,6 @@ #define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ #endif -#define configUSE_TRACE_FACILITY_2 0 #define configBENCHMARK 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 @@ -306,4 +304,9 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + #endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32s2/include/freertos/include/esp_additions/task_snapshot.h b/tools/sdk/esp32s2/include/freertos/include/esp_additions/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/include/esp_additions/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32s2/include/freertos/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..675af141ebc --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,312 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "sdkconfig.h" + +/* for likely and unlikely */ +#include "esp_compiler.h" + +// The arch-specific FreeRTOSConfig_arch.h in port//include. +#include "freertos/FreeRTOSConfig_arch.h" + +#if !(defined(FREERTOS_CONFIG_XTENSA_H) \ + || defined(FREERTOS_CONFIG_RISCV_H) \ + || defined(FREERTOS_CONFIG_LINUX_H)) +#error "Needs architecture-speific FreeRTOSConfig.h!" +#endif + +#ifndef CONFIG_FREERTOS_UNICORE +#define portNUM_PROCESSORS 2 +#else +#define portNUM_PROCESSORS 1 +#endif + +#define portUSING_MPU_WRAPPERS 0 +#define configUSE_MUTEX 1 + +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#endif /* def __ASSEMBLER__ */ + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * Note that the default heap size is deliberately kept small so that + * the build is more likely to succeed for configurations with limited + * memory. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) + +/* This has impact on speed of search for highest priority */ +#define configMAX_PRIORITIES ( 25 ) + +/* Various things that impact minimum stack sizes */ + +/* Higher stack checker modes cause overhead on each function call */ +#if CONFIG_STACK_CHECK_ALL || CONFIG_STACK_CHECK_STRONG +#define configSTACK_OVERHEAD_CHECKER 256 +#else +#define configSTACK_OVERHEAD_CHECKER 0 +#endif + +/* with optimizations disabled, scheduler uses additional stack */ +#if CONFIG_COMPILER_OPTIMIZATION_NONE +#define configSTACK_OVERHEAD_OPTIMIZATION 320 +#else +#define configSTACK_OVERHEAD_OPTIMIZATION 0 +#endif + +/* apptrace mdule increases minimum stack usage */ +#if CONFIG_APPTRACE_ENABLE +#define configSTACK_OVERHEAD_APPTRACE 1280 +#else +#define configSTACK_OVERHEAD_APPTRACE 0 +#endif + +#define configSTACK_OVERHEAD_TOTAL ( \ + configSTACK_OVERHEAD_CHECKER + \ + configSTACK_OVERHEAD_OPTIMIZATION + \ + configSTACK_OVERHEAD_APPTRACE \ + ) + +#define configMINIMAL_STACK_SIZE (768 + configSTACK_OVERHEAD_TOTAL) + +#ifndef configIDLE_TASK_STACK_SIZE +#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE +#endif + +/* Minimal heap size to make sure examples can run on memory limited + configs. Adjust this to suit your system. */ + + +//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there +//is some space left for the app and main cpu when running outside of a thread. +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) ) + +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) + +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + +#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID +#define configTASKLIST_INCLUDE_COREID 1 +#endif + +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */ +#endif + +#define configBENCHMARK 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE + +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE +#define configCHECK_FOR_STACK_OVERFLOW 0 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL +#define configCHECK_FOR_STACK_OVERFLOW 1 +#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY +#define configCHECK_FOR_STACK_OVERFLOW 2 +#endif + + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_pxTaskGetStackStart 1 + +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* The priority at which the tick interrupt runs. This should probably be + kept at 1. */ +#define configKERNEL_INTERRUPT_PRIORITY 1 + +#if !CONFIG_IDF_TARGET_LINUX +#define configUSE_NEWLIB_REENTRANT 1 +#endif + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +#ifndef __ASSEMBLER__ +#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP +extern void vPortCleanUpTCB ( void *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB ) +#endif +#endif + +/* Test FreeRTOS timers (with timer task) and more. */ +/* Some files don't compile if this flag is disabled */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY +#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH +#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH + +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define configUSE_QUEUE_SETS 1 + +#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if configUSE_TICKLESS_IDLE +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif //configUSE_TICKLESS_IDLE + + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 1 +#endif +#ifndef configENABLE_TASK_SNAPSHOT +#define configENABLE_TASK_SNAPSHOT 0 +#endif + +#if CONFIG_SYSVIEW_ENABLE +#ifndef __ASSEMBLER__ +#include "SEGGER_SYSVIEW_FreeRTOS.h" +#undef INLINE // to avoid redefinition +#endif /* def __ASSEMBLER__ */ +#endif + +#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER +#define configCHECK_MUTEX_GIVEN_BY_OWNER 1 +#else +#define configCHECK_MUTEX_GIVEN_BY_OWNER 0 +#endif + + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 + +// backward compatibility for 4.4 +#define xTaskRemoveFromUnorderedEventList vTaskRemoveFromUnorderedEventList + +#define configNUM_CORES portNUM_PROCESSORS + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/event_groups.h b/tools/sdk/esp32s2/include/freertos/include/freertos/event_groups.h index 84505ddaaa0..9792296e566 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/event_groups.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/event_groups.h @@ -64,7 +64,7 @@ * used to create a synchronisation point between multiple tasks (a * 'rendezvous'). * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroup EventGroup * @endcond */ @@ -78,7 +78,7 @@ * xEventGroupCreate() returns an EventGroupHandle_t variable that can then * be used as a parameter to other event group functions. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventGroupHandle_t EventGroupHandle_t * @endcond * \ingroup EventGroup @@ -94,7 +94,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, * 32 bits if set to 0. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup EventBits_t EventBits_t * @endcond * \ingroup EventGroup @@ -102,7 +102,7 @@ typedef struct EventGroupDef_t * EventGroupHandle_t; typedef TickType_t EventBits_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreate( void ); @@ -152,7 +152,7 @@ typedef TickType_t EventBits_t; * // The event group was created. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupCreate xEventGroupCreate * @endcond * \ingroup EventGroup @@ -162,7 +162,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); @@ -217,7 +217,7 @@ typedef TickType_t EventBits_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, @@ -307,7 +307,7 @@ typedef TickType_t EventBits_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupWaitBits xEventGroupWaitBits * @endcond * \ingroup EventGroup @@ -319,7 +319,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); @@ -372,7 +372,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBits xEventGroupClearBits * @endcond * \ingroup EventGroup @@ -381,7 +381,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -432,7 +432,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * @endcond * \ingroup EventGroup @@ -446,7 +446,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); @@ -516,7 +516,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBits xEventGroupSetBits * @endcond * \ingroup EventGroup @@ -525,7 +525,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); @@ -595,7 +595,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * @endcond * \ingroup EventGroup @@ -610,7 +610,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, @@ -732,7 +732,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupSync xEventGroupSync * @endcond * \ingroup EventGroup @@ -744,7 +744,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); @@ -758,7 +758,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBits() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBits xEventGroupGetBits * @endcond * \ingroup EventGroup @@ -766,7 +766,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); @@ -779,7 +779,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR * @endcond * \ingroup EventGroup @@ -787,7 +787,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * event_groups.h * @code{c} * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); @@ -802,7 +802,7 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/freertos_tasks_c_additions.h b/tools/sdk/esp32s2/include/freertos/include/freertos/freertos_tasks_c_additions.h new file mode 100644 index 00000000000..464c0b3ffb9 --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/freertos_tasks_c_additions.h @@ -0,0 +1,80 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +/** + * This file will be included in `tasks.c` file, thus, it must NOT be included + * by any (other) file. + * The functions below only consist in getters for the static variables in + * `tasks.c` file. + * The only source files that should call these functions are the ones in + * `/additions` directory. + */ + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + + UBaseType_t pxTCBGetSize ( void ) + { + return sizeof(TCB_t); + } + + ListItem_t* pxTCBGetStateListItem ( void *pxTCB ) + { + return &(((TCB_t*)pxTCB)->xStateListItem); + } + + StackType_t* pxTCBGetStartOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxStack; + } + + StackType_t* pxTCBGetTopOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxTopOfStack; + } + + StackType_t* pxTCBGetEndOfStack ( void *pxTCB ) + { + return (StackType_t*) ((TCB_t*)pxTCB)->pxEndOfStack; + } + + + List_t* pxListGetReadyTask ( UBaseType_t idx ) + { + return &( pxReadyTasksLists[idx] ); + } + + List_t* pxListGetReadyPendingTask ( UBaseType_t idx ) + { + return &( xPendingReadyList[idx] ); + } + + List_t* pxGetDelayedTaskList ( void ) { + return pxDelayedTaskList; + } + + List_t* pxGetOverflowDelayedTaskList ( void ) { + return pxOverflowDelayedTaskList; + } + + List_t* pxGetTasksWaitingTermination ( void ) { + return &xTasksWaitingTermination; + } + + List_t* pxGetSuspendedTaskList ( void ) { + return &xSuspendedTaskList; + } + +#endif diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/message_buffer.h b/tools/sdk/esp32s2/include/freertos/include/freertos/message_buffer.h index e57c589fbac..af5c3290b7c 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/message_buffer.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/message_buffer.h @@ -85,7 +85,7 @@ typedef void * MessageBufferHandle_t; /*-----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -139,7 +139,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreate xMessageBufferCreate * @endcond * \ingroup MessageBufferManagement @@ -148,7 +148,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -210,7 +210,7 @@ typedef void * MessageBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * @endcond * \ingroup MessageBufferManagement @@ -219,7 +219,7 @@ typedef void * MessageBufferHandle_t; ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -314,7 +314,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSend xMessageBufferSend * @endcond * \ingroup MessageBufferManagement @@ -323,7 +323,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -423,7 +423,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * @endcond * \ingroup MessageBufferManagement @@ -432,7 +432,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -516,7 +516,7 @@ typedef void * MessageBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceive xMessageBufferReceive * @endcond * \ingroup MessageBufferManagement @@ -526,7 +526,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -622,7 +622,7 @@ typedef void * MessageBufferHandle_t; * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * @endcond * \ingroup MessageBufferManagement @@ -631,7 +631,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -654,7 +654,7 @@ typedef void * MessageBufferHandle_t; vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); @@ -674,7 +674,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); @@ -693,7 +693,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); @@ -712,7 +712,7 @@ typedef void * MessageBufferHandle_t; * the message queue to wait for space to become available, or to wait for a * a message to be available, then pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReset xMessageBufferReset * @endcond * \ingroup MessageBufferManagement @@ -722,7 +722,7 @@ typedef void * MessageBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); @@ -740,7 +740,7 @@ typedef void * MessageBufferHandle_t; * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size * of the largest message that can be written to the message buffer is 6 bytes. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable * @endcond * \ingroup MessageBufferManagement @@ -751,7 +751,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * @code{c} * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); @@ -767,7 +767,7 @@ typedef void * MessageBufferHandle_t; * @return The length (in bytes) of the next message in the message buffer, or 0 * if the message buffer is empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes * @endcond * \ingroup MessageBufferManagement @@ -776,7 +776,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -811,7 +811,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -820,7 +820,7 @@ typedef void * MessageBufferHandle_t; xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -856,7 +856,7 @@ typedef void * MessageBufferHandle_t; * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/queue.h b/tools/sdk/esp32s2/include/freertos/include/freertos/queue.h index 81cccc05df3..05ca7de4546 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/queue.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/queue.h @@ -62,7 +62,7 @@ typedef struct QueueDefinition * QueueSetHandle_t; */ typedef struct QueueDefinition * QueueSetMemberHandle_t; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* For internal use only. */ #define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) @@ -80,7 +80,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreate( @@ -146,7 +146,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreate xQueueCreate * @endcond * \ingroup QueueManagement @@ -156,7 +156,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * QueueHandle_t xQueueCreateStatic( @@ -235,7 +235,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueCreateStatic xQueueCreateStatic * @endcond * \ingroup QueueManagement @@ -245,7 +245,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToToFront( @@ -321,7 +321,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -330,7 +330,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBack( @@ -408,7 +408,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -417,7 +417,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSend( @@ -497,7 +497,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -506,7 +506,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwrite( @@ -585,7 +585,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwrite xQueueOverwrite * @endcond * \ingroup QueueManagement @@ -595,7 +595,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSend( @@ -678,7 +678,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSend xQueueSend * @endcond * \ingroup QueueManagement @@ -689,7 +689,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeek( @@ -780,7 +780,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeek xQueuePeek * @endcond * \ingroup QueueManagement @@ -790,7 +790,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueuePeekFromISR( @@ -820,7 +820,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, * @return pdTRUE if an item was successfully received from the queue, * otherwise pdFALSE. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueuePeekFromISR xQueuePeekFromISR * @endcond * \ingroup QueueManagement @@ -829,7 +829,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceive( @@ -917,7 +917,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * // ... Rest of task code. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceive xQueueReceive * @endcond * \ingroup QueueManagement @@ -927,7 +927,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); @@ -940,7 +940,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, * * @return The number of messages available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -948,7 +948,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ); @@ -963,7 +963,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @return The number of spaces available in the queue. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting * @endcond * \ingroup QueueManagement @@ -971,7 +971,7 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNC UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * void vQueueDelete( QueueHandle_t xQueue ); @@ -983,7 +983,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC * * @param xQueue A handle to the queue to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vQueueDelete vQueueDelete * @endcond * \ingroup QueueManagement @@ -991,7 +991,7 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNC void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToFrontFromISR( @@ -1057,7 +1057,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1067,7 +1067,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendToBackFromISR( @@ -1133,7 +1133,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1142,7 +1142,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueOverwriteFromISR( @@ -1225,7 +1225,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR * @endcond * \ingroup QueueManagement @@ -1234,7 +1234,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueSendFromISR( @@ -1304,7 +1304,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueSendFromISR xQueueSendFromISR * @endcond * \ingroup QueueManagement @@ -1312,10 +1312,10 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; #define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /**@{*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueGenericSendFromISR( @@ -1402,7 +1402,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * queue. h * @code{c} * BaseType_t xQueueReceiveFromISR( @@ -1487,7 +1487,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR * @endcond * \ingroup QueueManagement @@ -1504,7 +1504,7 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * The functions defined above are for passing data to and from tasks. The * functions below are the equivalents for passing data to and from @@ -1778,7 +1778,7 @@ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, */ QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Not public API functions. */ void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/semphr.h b/tools/sdk/esp32s2/include/freertos/include/freertos/semphr.h index 7e99c0b396c..2041641b91d 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/semphr.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/semphr.h @@ -39,7 +39,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * semphr. h * @code{c} @@ -88,7 +88,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -106,7 +106,7 @@ typedef QueueHandle_t SemaphoreHandle_t; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinary( void ); @@ -163,7 +163,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary * @endcond * \ingroup Semaphores @@ -173,7 +173,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); @@ -229,7 +229,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // Rest of task code goes here. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic * @endcond * \ingroup Semaphores @@ -239,7 +239,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTake( @@ -304,7 +304,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTake xSemaphoreTake * @endcond * \ingroup Semaphores @@ -312,7 +312,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeRecursive( @@ -403,7 +403,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive * @endcond * \ingroup Semaphores @@ -465,7 +465,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGive xSemaphoreGive * @endcond * \ingroup Semaphores @@ -473,7 +473,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); @@ -555,7 +555,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive * @endcond * \ingroup Semaphores @@ -641,7 +641,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR * @endcond * \ingroup Semaphores @@ -649,7 +649,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * xSemaphoreTakeFromISR( @@ -686,7 +686,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutex( void ); @@ -741,7 +741,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex * @endcond * \ingroup Semaphores @@ -751,7 +751,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); @@ -808,7 +808,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // so there is no need to check it. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic * @endcond * \ingroup Semaphores @@ -951,7 +951,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); @@ -1027,7 +1027,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * @endcond * \ingroup Semaphores @@ -1037,7 +1037,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer ); @@ -1118,7 +1118,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * // is no need to check its value. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic * @endcond * \ingroup Semaphores @@ -1128,7 +1128,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr. h * @code{c} * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); @@ -1140,7 +1140,7 @@ typedef QueueHandle_t SemaphoreHandle_t; * * @param xSemaphore A handle to the semaphore to be deleted. * - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * \defgroup vSemaphoreDelete vSemaphoreDelete * @endcond * \ingroup Semaphores @@ -1148,7 +1148,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); @@ -1167,7 +1167,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex ); @@ -1182,7 +1182,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * semphr.h * @code{c} * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/stream_buffer.h b/tools/sdk/esp32s2/include/freertos/include/freertos/stream_buffer.h index 9e58cff120c..a20dcf0375e 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/stream_buffer.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/stream_buffer.h @@ -71,7 +71,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * message_buffer.h * * @code{c} @@ -134,7 +134,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreate xStreamBufferCreate * @endcond * \ingroup StreamBufferManagement @@ -142,7 +142,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -220,7 +220,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * @endcond * \ingroup StreamBufferManagement @@ -229,7 +229,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -319,7 +319,7 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSend xStreamBufferSend * @endcond * \ingroup StreamBufferManagement @@ -330,7 +330,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -424,7 +424,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * @endcond * \ingroup StreamBufferManagement @@ -435,7 +435,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -517,7 +517,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceive xStreamBufferReceive * @endcond * \ingroup StreamBufferManagement @@ -528,7 +528,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -607,7 +607,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * @endcond * \ingroup StreamBufferManagement @@ -618,7 +618,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -636,7 +636,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * * @param xStreamBuffer The handle of the stream buffer to be deleted. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vStreamBufferDelete vStreamBufferDelete * @endcond * \ingroup StreamBufferManagement @@ -644,7 +644,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -660,7 +660,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI * @return If the stream buffer is full then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsFull xStreamBufferIsFull * @endcond * \ingroup StreamBufferManagement @@ -668,7 +668,7 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -684,7 +684,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ * @return If the stream buffer is empty then pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty * @endcond * \ingroup StreamBufferManagement @@ -692,7 +692,7 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -711,7 +711,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED * a task blocked waiting to send to or read from the stream buffer then the * stream buffer is not reset and pdFAIL is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReset xStreamBufferReset * @endcond * \ingroup StreamBufferManagement @@ -719,7 +719,7 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -736,7 +736,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F * @return The number of bytes that can be written to the stream buffer before * the stream buffer would be full. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable * @endcond * \ingroup StreamBufferManagement @@ -744,7 +744,7 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -761,7 +761,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL * @return The number of bytes that can be read from the stream buffer before * the stream buffer would be empty. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable * @endcond * \ingroup StreamBufferManagement @@ -769,7 +769,7 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -802,7 +802,7 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE * then the trigger level will be updated and pdTRUE is returned. Otherwise * pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * @endcond * \ingroup StreamBufferManagement @@ -811,7 +811,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -846,7 +846,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -855,7 +855,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * stream_buffer.h * * @code{c} @@ -891,7 +891,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer * @return If a task was removed from the Blocked state then pdTRUE is returned. * Otherwise pdFALSE is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * @endcond * \ingroup StreamBufferManagement @@ -899,7 +899,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* Functions below here are not part of the public API. */ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/task.h b/tools/sdk/esp32s2/include/freertos/include/freertos/task.h index 9135b76f014..125a924d061 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/task.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/task.h @@ -76,7 +76,7 @@ * returns (via a pointer parameter) an TaskHandle_t variable that can then * be used as a parameter to vTaskDelete to delete the task. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup TaskHandle_t TaskHandle_t * @endcond * \ingroup Tasks @@ -114,7 +114,7 @@ typedef enum eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ } eNotifyAction; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** * Used internally only. */ @@ -189,11 +189,13 @@ typedef enum #define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro for forcing a context switch. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskYIELD taskYIELD * @endcond * \ingroup SchedulerControl @@ -201,7 +203,9 @@ typedef enum #define taskYIELD() portYIELD() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the start of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -209,7 +213,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL * @endcond * \ingroup SchedulerControl @@ -228,7 +232,9 @@ typedef enum #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to mark the end of a critical code region. Preemptive context * switches cannot occur when in a critical region. @@ -236,7 +242,7 @@ typedef enum * @note This may alter the stack (depending on the portable implementation) * so must be used with care! * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL * @endcond * \ingroup SchedulerControl @@ -255,11 +261,13 @@ typedef enum #define taskEXIT_CRITICAL_ISR( ) portEXIT_CRITICAL_ISR( ) #endif // ESP_PLATFORM /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to disable all maskable interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -267,11 +275,13 @@ typedef enum #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h + * @endcond * * Macro to enable microcontroller interrupts. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS * @endcond * \ingroup SchedulerControl @@ -422,7 +432,7 @@ typedef enum * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreate xTaskCreate * @endcond * \ingroup Tasks @@ -430,14 +440,14 @@ typedef enum #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) static inline IRAM_ATTR BaseType_t xTaskCreate( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pvCreatedTask) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask) PRIVILEGED_FUNCTION { - return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask, tskNO_AFFINITY ); + return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY ); } #endif @@ -599,20 +609,20 @@ typedef enum #if( configSUPPORT_STATIC_ALLOCATION == 1 ) static inline IRAM_ATTR TaskHandle_t xTaskCreateStatic( - TaskFunction_t pvTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const pxStackBuffer, - StaticTask_t * const pxTaskBuffer) + TaskFunction_t pvTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer) PRIVILEGED_FUNCTION { - return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, pxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); + return xTaskCreateStaticPinnedToCore( pvTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, tskNO_AFFINITY ); } #endif /* configSUPPORT_STATIC_ALLOCATION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -683,18 +693,18 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks */ #if ( portUSING_MPU_WRAPPERS == 1 ) BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, - TaskHandle_t * pxCreatedTask ); + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); @@ -777,7 +787,7 @@ typedef enum * for( ;; ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic * @endcond * \ingroup Tasks @@ -788,7 +798,7 @@ typedef enum #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); @@ -833,7 +843,7 @@ typedef enum * // defined or shared regions have been declared elsewhere). * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCreateRestricted xTaskCreateRestricted * @endcond * \ingroup Tasks @@ -842,7 +852,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelete( TaskHandle_t xTask ); @@ -881,7 +891,7 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, * vTaskDelete( xHandle ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelete vTaskDelete * @endcond * \ingroup Tasks @@ -893,10 +903,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskDelay( const TickType_t xTicksToDelay ); * @endcode + * @endcond * * Delay a task for a given number of ticks. The actual time that the * task remains blocked depends on the tick rate. The constant @@ -938,7 +950,7 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskDelay vTaskDelay * @endcond * \ingroup TaskCtrl @@ -946,10 +958,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); * @endcode + * @endcond * * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. * See the configuration section for more information. @@ -1007,7 +1021,7 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskDelayUntil xTaskDelayUntil * @endcond * \ingroup TaskCtrl @@ -1026,7 +1040,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); @@ -1054,7 +1068,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, * @return If the task referenced by xTask was not in the Blocked state then * pdFAIL is returned. Otherwise pdPASS is returned. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskAbortDelay xTaskAbortDelay * @endcond * \ingroup TaskCtrl @@ -1062,7 +1076,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ); @@ -1107,7 +1121,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskPriorityGet uxTaskPriorityGet * @endcond * \ingroup TaskCtrl @@ -1115,7 +1129,7 @@ BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ); @@ -1127,7 +1141,7 @@ UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * eTaskState eTaskGetState( TaskHandle_t xTask ); @@ -1149,7 +1163,7 @@ UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNC eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); @@ -1203,7 +1217,7 @@ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; * eInvalid ); // Include the task state in xTaskDetails. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetInfo vTaskGetInfo * @endcond * \ingroup TaskCtrl @@ -1214,7 +1228,7 @@ void vTaskGetInfo( TaskHandle_t xTask, eTaskState eState ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); @@ -1254,7 +1268,7 @@ void vTaskGetInfo( TaskHandle_t xTask, * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskPrioritySet vTaskPrioritySet * @endcond * \ingroup TaskCtrl @@ -1263,7 +1277,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); @@ -1312,7 +1326,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, * // with our handle as the parameter. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspend vTaskSuspend * @endcond * \ingroup TaskCtrl @@ -1320,7 +1334,7 @@ void vTaskPrioritySet( TaskHandle_t xTask, void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskResume( TaskHandle_t xTaskToResume ); @@ -1367,7 +1381,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; * // time in accordance with its priority within the system. * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResume vTaskResume * @endcond * \ingroup TaskCtrl @@ -1375,7 +1389,7 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); @@ -1402,7 +1416,7 @@ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * otherwise pdFALSE. This is used by the ISR to determine if a context switch * may be required following the ISR. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskResumeFromISR vTaskResumeFromISR * @endcond * \ingroup TaskCtrl @@ -1412,9 +1426,9 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER CONTROL *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskStartScheduler( void ); @@ -1445,7 +1459,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskStartScheduler vTaskStartScheduler * @endcond * \ingroup SchedulerControl @@ -1453,7 +1467,7 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskEndScheduler( void ); @@ -1507,7 +1521,7 @@ void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; * } * @endcode * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskEndScheduler vTaskEndScheduler * @endcond * \ingroup SchedulerControl @@ -1517,7 +1531,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** @endcond */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskSuspendAll( void ); @@ -1566,7 +1580,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskSuspendAll vTaskSuspendAll * @endcond * \ingroup SchedulerControl @@ -1574,7 +1588,7 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskResumeAll( void ); @@ -1626,7 +1640,7 @@ void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; * } * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskResumeAll xTaskResumeAll * @endcond * \ingroup SchedulerControl @@ -1638,7 +1652,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCount( void ); @@ -1647,7 +1661,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; * * @return The count of ticks since vTaskStartScheduler was called. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCount xTaskGetTickCount * @endcond * \ingroup TaskUtils @@ -1655,7 +1669,7 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TickType_t xTaskGetTickCountFromISR( void ); @@ -1669,7 +1683,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; * microcontroller being used or interrupt nesting is either not supported or * not being used. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR * @endcond * \ingroup TaskUtils @@ -1677,7 +1691,7 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint16_t uxTaskGetNumberOfTasks( void ); @@ -1689,7 +1703,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; * has been deleted but not yet freed by the idle task will also be * included in the count. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks * @endcond * \ingroup TaskUtils @@ -1697,7 +1711,7 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); @@ -1708,7 +1722,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; * xTaskToQuery. A task can query its own name by either passing in its own * handle, or by setting xTaskToQuery to NULL. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetName pcTaskGetName * @endcond * \ingroup TaskUtils @@ -1716,7 +1730,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); @@ -1730,7 +1744,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lin * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup pcTaskGetHandle pcTaskGetHandle * @endcond * \ingroup TaskUtils @@ -1813,7 +1827,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #ifdef configUSE_APPLICATION_TASK_TAG #if configUSE_APPLICATION_TASK_TAG == 1 /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); @@ -1830,7 +1844,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTag( TaskHandle_t xTask ); @@ -1844,7 +1858,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ); @@ -1932,7 +1946,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationStackOverflowHook( TaskHandle_t xTask char *pcTaskName); @@ -1952,7 +1966,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configUSE_TICK_HOOK > 0 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationTickHook( void ); @@ -1967,7 +1981,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) @@ -1986,7 +2000,7 @@ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION; #endif /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); @@ -2155,7 +2169,7 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, * enough to contain the generated report. Approximately 40 bytes per * task should be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskList vTaskList * @endcond * \ingroup TaskUtils @@ -2210,7 +2224,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq * contain the generated report. Approximately 40 bytes per task should * be sufficient. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * @endcond * \ingroup TaskUtils @@ -2218,7 +2232,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unq void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code * uint32_t ulTaskGetIdleRunTimeCounter( void ); @@ -2246,7 +2260,7 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and * portGET_RUN_TIME_COUNTER_VALUE() macros. * - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter * @endcond * \ingroup TaskUtils @@ -2254,11 +2268,13 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction ); * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2359,7 +2375,9 @@ uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, @@ -2373,11 +2391,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2393,7 +2413,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * than when the function returns) in the additional pulPreviousNotifyValue * parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ @@ -2402,11 +2424,13 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2511,7 +2535,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, * @return Dependent on the value of eAction. See the description of the * eAction parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, @@ -2526,11 +2552,13 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2546,7 +2574,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * function is called rather than at the time the function returns) in the * additional pulPreviousNotifyValue parameter. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ @@ -2555,12 +2585,14 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification to be pending at a given index within * an array of direct to task notifications. @@ -2655,7 +2687,9 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * already pending when xTaskNotifyWait was called) then pdPASS is * returned. Otherwise pdFAIL is returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, @@ -2669,11 +2703,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ); * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); * @endcode + * @endcond * * Sends a direct to task notification to a particular index in the target * task's notification array in a manner similar to giving a counting semaphore. @@ -2737,7 +2773,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the * eAction parameter set to eIncrement - so pdPASS is always returned. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed + * @endcond * \ingroup TaskNotifications */ #define xTaskNotifyGive( xTaskToNotify ) \ @@ -2746,11 +2784,13 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ); * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken ); * @endcode + * @endcond * * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt * service routine (ISR). @@ -2821,7 +2861,9 @@ BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, * requested from an ISR is dependent on the port - see the documentation page * for the port in use. * + * @cond !DOC_SINGLE_GROUP * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR + * @endcond * \ingroup TaskNotifications */ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, @@ -2833,12 +2875,14 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) ); /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); * @endcode + * @endcond * * Waits for a direct to task notification on a particular index in the calling * task's notification array in a manner similar to taking a counting semaphore. @@ -2927,7 +2971,9 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, * @return The task's notification count before it is either cleared to zero or * decremented (see the xClearCountOnExit parameter). * + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, @@ -2939,12 +2985,14 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, ulTaskGenericNotifyTake( ( uxIndexToWaitOn ), ( xClearCountOnExit ), ( xTicksToWait ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); * * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -2992,7 +3040,9 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, * @return pdTRUE if the task's notification state was set to * eNotWaitingNotification, otherwise pdFALSE. * + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed + * @endcond * \ingroup TaskNotifications */ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, @@ -3003,12 +3053,14 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) ) /** + * @cond !DOC_EXCLUDE_HEADER_SECTION * task. h * @code{c} * uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ); * * uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ); * @endcode + * @endcond * * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. * @@ -3057,7 +3109,9 @@ BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, * * @return The value of the target task's notification value before the bits * specified by ulBitsToClear were cleared. + * @cond !DOC_SINGLE_GROUP * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear + * @endcond * \ingroup TaskNotifications */ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, @@ -3069,7 +3123,7 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); @@ -3082,14 +3136,14 @@ uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, * is to be captured. The captured time includes the tick count and the number * of times the tick count has overflowed since the system first booted. * \defgroup vTaskSetTimeOutState vTaskSetTimeOutState - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code * BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); @@ -3170,7 +3224,7 @@ void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; * return uxReceived; * } * @endcode - * @cond + * @cond !DOC_SINGLE_GROUP * \defgroup xTaskCheckForTimeOut xTaskCheckForTimeOut * @endcond * \ingroup TaskCtrl @@ -3179,7 +3233,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ); @@ -3204,7 +3258,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, * blocked state and a context switch being performed. Otherwise pdFALSE. * * \defgroup xTaskCatchUpTicks xTaskCatchUpTicks - * @cond + * @cond !DOC_SINGLE_GROUP * \ingroup TaskCtrl * @endcond */ @@ -3214,7 +3268,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES *----------------------------------------------------------*/ -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Return the handle of the task running on a certain CPU. Because of * the nature of SMP processing, there is no guarantee that this @@ -3335,8 +3389,8 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, * making the call, otherwise pdFALSE. */ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; -BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, - const TickType_t xItemValue ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, + const TickType_t xItemValue ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY @@ -3399,11 +3453,6 @@ void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, */ UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; -/* - * Get the current core affinity of a task - */ -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; - /* * Set the uxTaskNumber of the task referenced by the xTask parameter to * uxHandle. diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/task_snapshot.h b/tools/sdk/esp32s2/include/freertos/include/freertos/task_snapshot.h new file mode 100644 index 00000000000..1ad04cce694 --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/task_snapshot.h @@ -0,0 +1,90 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if ( configENABLE_TASK_SNAPSHOT == 1 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check `freertos_tasks_c_additions.h` file for more info + * about these functions declaration. + */ +UBaseType_t pxTCBGetSize ( void ); +ListItem_t* pxTCBGetStateListItem ( void *pxTCB ); +StackType_t* pxTCBGetStartOfStack ( void *pxTCB ); +StackType_t* pxTCBGetTopOfStack ( void *pxTCB ); +StackType_t* pxTCBGetEndOfStack ( void *pxTCB ); +List_t* pxListGetReadyTask ( UBaseType_t idx ); +List_t* pxListGetReadyPendingTask ( UBaseType_t idx ); +List_t* pxGetDelayedTaskList ( void ); +List_t* pxGetOverflowDelayedTaskList ( void ); +List_t* pxGetTasksWaitingTermination ( void ); +List_t* pxGetSuspendedTaskList ( void ); + +/** + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /*!< Address of task control block. */ + StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + + +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by panic handling code to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + +/* + * This function iterates over all tasks in the system. + * Used by panic handling code to iterate over tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @return Handle for the next task. If pxTask is NULL, returns hadnle for the first task. + */ +TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ); + +/* + * This function fills TaskSnapshot_t structure for specified task. + * Used by panic handling code to get snapshot of a task. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @note This function should not be used while FreeRTOS is running (as it doesn't acquire any locks). + * @param pxTask task handle. + * @param pxTaskSnapshot address of TaskSnapshot_t structure to fill. + */ +void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/esp32s2/include/freertos/include/freertos/timers.h b/tools/sdk/esp32s2/include/freertos/include/freertos/timers.h index a8bc4f38c78..af6dcb23501 100644 --- a/tools/sdk/esp32s2/include/freertos/include/freertos/timers.h +++ b/tools/sdk/esp32s2/include/freertos/include/freertos/timers.h @@ -450,7 +450,7 @@ void vTimerSetTimerID( TimerHandle_t xTimer, BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * @endcond * @@ -1315,7 +1315,7 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; */ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; -/** @cond */ +/** @cond !DOC_EXCLUDE_HEADER_SECTION */ /* * Functions beyond this part are not part of the public API and are intended @@ -1339,7 +1339,7 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) /** - * @cond + * @cond !DOC_EXCLUDE_HEADER_SECTION * task.h * @code{c} * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) diff --git a/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h b/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h new file mode 100644 index 00000000000..f2aab51ccfc --- /dev/null +++ b/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig.h @@ -0,0 +1,166 @@ +/* + FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_XTENSA_H +#define FREERTOS_CONFIG_XTENSA_H + +#include "sdkconfig.h" + +/* enable use of optimized task selection by the scheduler */ +#ifdef CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#define XT_USE_THREAD_SAFE_CLIB 0 +#undef XT_USE_SWPRI + +#if CONFIG_FREERTOS_CORETIMER_0 +#define XT_TIMER_INDEX 0 +#elif CONFIG_FREERTOS_CORETIMER_1 +#define XT_TIMER_INDEX 1 +#endif + +#ifndef __ASSEMBLER__ +/** + * This function is defined to provide a deprecation warning whenever + * XT_CLOCK_FREQ macro is used. + * Update the code to use esp_clk_cpu_freq function instead. + * @return current CPU clock frequency, in Hz + */ +int xt_clock_freq(void) __attribute__((deprecated)); + +#define XT_CLOCK_FREQ (xt_clock_freq()) + +#endif // __ASSEMBLER__ + +/* Required for configuration-dependent settings */ +#include + +/* configASSERT behaviour */ +#ifndef __ASSEMBLER__ +#include +#include "esp_rom_sys.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/ets_sys.h" // will be removed in idf v5.0 +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/ets_sys.h" +#endif +#endif // __ASSEMBLER__ + +// If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro +// configASSERT_DEFINED remains unset (meaning some warnings are avoided) + +#if defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE) +#define configASSERT(a) if (unlikely(!(a))) { \ + esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \ + __FUNCTION__); \ + } +#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_ABORT) +#define configASSERT(a) assert(a) +#endif + +#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION +#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0) +#else +#define UNTESTED_FUNCTION() +#endif + +#define configXT_BOARD 1 /* Board mode */ +#define configXT_SIMULATOR 0 + +/* The maximum interrupt priority from which FreeRTOS.org API functions can + be called. Only API functions that end in ...FromISR() can be used within + interrupts. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY XCHAL_EXCM_LEVEL + +/* Stack alignment, architecture specifc. Must be a power of two. */ +#define configSTACK_ALIGNMENT 16 + + +/* The Xtensa port uses a separate interrupt stack. Adjust the stack size + * to suit the needs of your specific application. + * Size needs to be aligned to the stack increment, since the location of + * the stack for the 2nd CPU will be calculated using configISR_STACK_SIZE. + */ +#ifndef configISR_STACK_SIZE +#define configISR_STACK_SIZE ((CONFIG_FREERTOS_ISR_STACKSIZE + configSTACK_ALIGNMENT - 1) & (~(configSTACK_ALIGNMENT - 1))) +#endif + +#ifndef __ASSEMBLER__ +#if CONFIG_APPTRACE_SV_ENABLE +extern uint32_t port_switch_flag[]; +#define os_task_switch_is_pended(_cpu_) (port_switch_flag[_cpu_]) +#else +#define os_task_switch_is_pended(_cpu_) (false) +#endif +#endif + +#endif // FREERTOS_CONFIG_XTENSA_H diff --git a/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/portmacro.h b/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/portmacro.h index 248c86d15c7..47187379c6c 100644 --- a/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/portmacro.h +++ b/tools/sdk/esp32s2/include/freertos/port/xtensa/include/freertos/portmacro.h @@ -24,317 +24,449 @@ * * 1 tab == 4 spaces! */ + #ifndef PORTMACRO_H #define PORTMACRO_H -#ifdef __cplusplus -extern "C" { -#endif - #ifndef __ASSEMBLER__ -#include +#include "sdkconfig.h" #include #include #include #include -#include #include -#include /* required for XSHAL_CLIB */ -#include -#include "esp_private/crosscore_int.h" -#include "esp_timer.h" /* required for FreeRTOS run time stats */ -#include "esp_system.h" -#include "esp_newlib.h" +#include /* required for xthal_get_ccount. [refactor-todo] use cpu_hal instead */ +#include /* required for XTOS_SET_INTLEVEL. [refactor-todo] add common intr functions to esp_hw_support */ +#include "xt_instr_macros.h" #include "soc/spinlock.h" -#include +#include "hal/cpu_hal.h" +#include "esp_private/crosscore_int.h" +#include "esp_attr.h" +#include "esp_timer.h" /* required for esp_timer_get_time. [refactor-todo] make this common between archs */ +#include "esp_newlib.h" /* required for esp_reent_init() in tasks.c */ +#include "esp_heap_caps.h" #include "esp_rom_sys.h" -#include "sdkconfig.h" -#include "freertos/xtensa_api.h" -#include "esp_system.h" -#include "soc/cpu.h" -#include +#include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */ +#include "portbenchmark.h" +/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */ +#include +#include +#include +#include "soc/cpu.h" #ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS #include "soc/soc_memory_layout.h" #endif -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ +#ifdef __cplusplus +extern "C" { +#endif + -#include "esp_system.h" -#include "hal/cpu_hal.h" -#include "xt_instr_macros.h" -/* Type definitions. */ -#define portCHAR int8_t -#define portFLOAT float -#define portDOUBLE double -#define portLONG int32_t -#define portSHORT int16_t -#define portSTACK_TYPE uint8_t -#define portBASE_TYPE int +/* --------------------------------------------------- Port Types ------------------------------------------------------ + * - Port specific types. + * - The settings in this file configure FreeRTOS correctly for the given hardware and compiler. + * - These settings should not be altered. + * - The port types must come before first as they are used further down the file + * ------------------------------------------------------------------------------------------------------------------ */ -typedef portSTACK_TYPE StackType_t; -typedef portBASE_TYPE BaseType_t; -typedef unsigned portBASE_TYPE UBaseType_t; +#define portCHAR int8_t +#define portFLOAT float +#define portDOUBLE double +#define portLONG int32_t +#define portSHORT int16_t +#define portSTACK_TYPE uint8_t +#define portBASE_TYPE int + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef unsigned portBASE_TYPE UBaseType_t; #if( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff +typedef uint16_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffff #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #endif -/*-----------------------------------------------------------*/ -// portbenchmark -#include "portbenchmark.h" +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#include "sdkconfig.h" -#include "esp_attr.h" -#include "portmacro_priv.h" - -// Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. -// They can be called from interrupts too. -// WARNING: Only applies to current CPU. See notes above. -static inline unsigned portENTER_CRITICAL_NESTED(void) { - unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); - portbenchmarkINTERRUPT_DISABLE(); - return state; -} -#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) -/* -Modifications to portENTER_CRITICAL. -For an introduction, see "Critical Sections & Disabling Interrupts" in docs/api-guides/freertos-smp.rst +/* ----------------------------------------------- Port Configurations ------------------------------------------------- + * - Configurations values supplied by each port + * - Required by FreeRTOS + * ------------------------------------------------------------------------------------------------------------------ */ -The original portENTER_CRITICAL only disabled the ISRs. This is enough for single-CPU operation: by -disabling the interrupts, there is no task switch so no other tasks can meddle in the data, and because -interrupts are disabled, ISRs can't corrupt data structures either. +#define portCRITICAL_NESTING_IN_TCB 0 +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 4 +#define portNOP() XT_NOP() -For multiprocessing, things get a bit more hairy. First of all, disabling the interrupts doesn't stop -the tasks or ISRs on the other processors meddling with our CPU. For tasks, this is solved by adding -a spinlock to the portENTER_CRITICAL macro. A task running on the other CPU accessing the same data will -spinlock in the portENTER_CRITICAL code until the first CPU is done. -For ISRs, we now also need muxes: while portENTER_CRITICAL disabling interrupts will stop ISRs on the same -CPU from meddling with the data, it does not stop interrupts on the other cores from interfering with the -data. For this, we also use a spinlock in the routines called by the ISR, but these spinlocks -do not disable the interrupts (because they already are). -This all assumes that interrupts are either entirely disabled or enabled. Interrupt priority levels -will break this scheme. +/* ---------------------------------------------- Forward Declarations ------------------------------------------------- + * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface + * - These must come before definition/declaration of the FreeRTOS porting interface + * ------------------------------------------------------------------------------------------------------------------ */ -Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vPortEnterCritical, meaning -that either function can be called both from ISR as well as task context. This is not standard FreeRTOS -behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations. -*/ -/* "mux" data structure (spinlock) */ -typedef spinlock_t portMUX_TYPE; +// --------------------- Interrupts ------------------------ -#define portMUX_FREE_VAL SPINLOCK_FREE -#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /* When passed for 'timeout_cycles', spin forever if necessary */ -#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /* Try to acquire the spinlock a single time only */ -#define portMUX_INITIALIZER_UNLOCKED SPINLOCK_INITIALIZER +/** + * @brief Checks if the current core is in an ISR context + * + * - ISR context consist of Low/Mid priority ISR, or time tick ISR + * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in ISR + * - pdFALSE otherwise + */ +BaseType_t xPortInIsrContext(void); -#define portCRITICAL_NESTING_IN_TCB 0 +/** + * @brief Asserts if in ISR context + * + * - Asserts on xPortInIsrContext() internally + * + * @note [refactor-todo] Check if this API is still required + * @note [refactor-todo] Check if this should be inlined + */ +void vPortAssertIfInISR(void); -static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux) -{ - spinlock_initialize(mux); -} +/** + * @brief Check if in ISR context from High priority ISRs + * + * - Called from High priority ISR + * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority) + * + * @note [refactor-todo] Check if this should be inlined + * @return + * - pdTRUE if in previous in ISR context + * - pdFALSE otherwise + */ +BaseType_t xPortInterruptedFromISRContext(void); -static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux) -{ - spinlock_acquire(mux, portMUX_NO_TIMEOUT); -} +/** + * @brief Disable interrupts in a nested manner + * + * - Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. + * - They can be called from interrupts too. + * - WARNING Only applies to current CPU. + * @note [refactor-todo] Define this as portSET_INTERRUPT_MASK_FROM_ISR() instead + * @return unsigned Previous interrupt state + */ +static inline unsigned __attribute__((always_inline)) portENTER_CRITICAL_NESTED(void); + +/* ---------------------- Spinlocks ------------------------ + * - Modifications made to critical sections to support SMP + * - See "Critical Sections & Disabling Interrupts" in docs/api-guides/freertos-smp.rst for more details + * - Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vPortEnterCritical, meaning that + * either function can be called both from ISR as well as task context. This is not standard FreeRTOS + * behaviorr; please keep this in mind if you need any compatibility with other FreeRTOS implementations. + * @note [refactor-todo] Check if these comments are still true + * ------------------------------------------------------ */ + +typedef spinlock_t portMUX_TYPE; /**< Spinlock type used by FreeRTOS critical sections */ +#define portMUX_INITIALIZER_UNLOCKED SPINLOCK_INITIALIZER /**< Spinlock initializer */ +#define portMUX_FREE_VAL SPINLOCK_FREE /**< Spinlock is free. [refactor-todo] check if this is still required */ +#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */ +#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */ -static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout) -{ - return (spinlock_acquire(mux, timeout)); -} +/** + * @brief Initialize a spinlock + * + * - Initializes a spinlock that is used by FreeRTOS SMP critical sections + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux) -{ - spinlock_release(mux); -} +/** + * @brief Acquire a spinlock + * + * @note [refactor-todo] check if we still need this + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux); +/** + * @brief Acquire a spinlock but with a specified timeout + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to bool return type) + * + * @param[in] mux Spinlock + * @param timeout + * @return true Spinlock acquired + * @return false Timed out + */ +static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout); + +/** + * @brief Release a spinlock + * + * @note [refactor-todo] check if we still need this + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux); + +/** + * @brief Wrapper for atomic compare-and-set instruction + * + * This subroutine will atomically compare *addr to 'compare'. If *addr == compare, *addr is set to *set. *set is + * updated with the previous value of *addr (either 'compare' or some other value.) + * + * @warning From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the "bitwise inverse" of + * the old mem if the mem wasn't written. This doesn't seem to happen on the ESP32 (portMUX assertions would + * fail). + * + * @note [refactor-todo] check if we still need this + * @note [refactor-todo] Check if this function should be renamed (due to void return type) + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set); + +/** + * @brief Wrapper for atomic compare-and-set instruction in external RAM + * + * Atomic compare-and-set but the target address is placed in external RAM + * + * @note [refactor-todo] check if we still need this + * + * @param[inout] addr Pointer to target address + * @param[in] compare Compare value + * @param[inout] set Pointer to set value + */ +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set); + +// ------------------ Critical Sections -------------------- + +/** + * @brief Enter a SMP critical section + * + * - Disable interrupts + * - Takes spinlock + * - Can be nested + * + * @param[in] mux Spinlock + */ void vPortEnterCritical(portMUX_TYPE *mux); + +/** + * @brief Exit a SMP critical section + * + * - Releases spinlock + * - Reenables interrupts + * - Can be nested + * + * @param[in] mux Spinlock + */ void vPortExitCritical(portMUX_TYPE *mux); -#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() -void vPortAssertIfInISR(void); +/** + * @brief FreeRTOS compliant version of enter critical + * + * - Ensures that critical section is only entered from task context + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux); -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. +/** + * @brief FreeRTOS compliant version of exit critical + * + * @param[in] mux Spinlock */ -BaseType_t xPortInIsrContext(void); +static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux) -{ - if(!xPortInIsrContext()) { - vPortEnterCritical(mux); - } else { - esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } -} +/** + * @brief Safe version of enter critical + * + * - This function can be used to enter a critical section from both task and ISR contexts + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux); -static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux) -{ - if(!xPortInIsrContext()) { - vPortExitCritical(mux); - } else { - esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } -} +/** + * @brief Safe version of exit critical + * + * @param[in] mux Spinlock + */ +static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux); -#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE -/* Calling port*_CRITICAL from ISR context would cause an assert failure. - * If the parent function is called from both ISR and Non-ISR context then call port*_CRITICAL_SAFE +// ---------------------- Yielding ------------------------- + +/** + * @brief Perform a solicited context switch + * + * - Defined in portasm.S + * + * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead */ -#define portENTER_CRITICAL(mux) vPortEnterCriticalCompliance(mux) -#define portEXIT_CRITICAL(mux) vPortExitCriticalCompliance(mux) -#else -#define portENTER_CRITICAL(mux) vPortEnterCritical(mux) -#define portEXIT_CRITICAL(mux) vPortExitCritical(mux) -#endif +void vPortYield( void ); -#define portENTER_CRITICAL_ISR(mux) vPortEnterCritical(mux) -#define portEXIT_CRITICAL_ISR(mux) vPortExitCritical(mux) +/** + * @brief + * + * @note [refactor-todo] Refactor this to avoid va_args + * @param argc + * @param ... Variable arguments to allow for IDF prototype without arguments, and vanilla version WITH argument + */ +void vPortEvaluateYieldFromISR(int argc, ...); -static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux) -{ - if (xPortInIsrContext()) { - portENTER_CRITICAL_ISR(mux); - } else { - portENTER_CRITICAL(mux); - } -} +/** + * @brief Yields the other core + * + * - Send an interrupt to another core in order to make the task running on it yield for a higher-priority task. + * - Can be used to yield current core as well + * + * @note [refactor-todo] Put this into private macros as its only called from task.c and is not public API + * @param coreid ID of core to yield + */ +void vPortYieldOtherCore(BaseType_t coreid); -static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux) -{ - if (xPortInIsrContext()) { - portEXIT_CRITICAL_ISR(mux); - } else { - portEXIT_CRITICAL(mux); - } -} +/** + * @brief Checks if the current core can yield + * + * - A core cannot yield if its in an ISR or in a critical section + * + * @note [refactor-todo] See if this can be separated from port macro + * @return true Core can yield + * @return false Core cannot yield + */ +static inline bool IRAM_ATTR xPortCanYield(void); -#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux) -#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux) +// ------------------- Hook Functions ---------------------- -/* - * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare - * *addr to 'compare'. If *addr == compare, *addr is set to *set. *set is updated with the previous - * value of *addr (either 'compare' or some other value.) +extern void esp_vApplicationIdleHook(void); /* Required by tasks.c */ +extern void esp_vApplicationTickHook(void); /* Required by tasks.c */ + +/** + * @brief Hook function called on entry to tickless idle + * + * - Implemented in pm_impl.c * - * Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the - * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the - * ESP32 (portMUX assertions would fail). + * @param xExpectedIdleTime Expected idle time */ -static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { - compare_and_set_native(addr, compare, set); -} +void vApplicationSleep(TickType_t xExpectedIdleTime); -// Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? -// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. -// -// Only applies to one CPU. See notes above & below for reasons not to use these. -#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) -#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) +// ----------------------- System -------------------------- +/** + * @brief Get the tick rate per second + * + * @note [refactor-todo] make this inline + * @return uint32_t Tick rate in Hz + */ +uint32_t xPortGetTickRateHz(void); -// These FreeRTOS versions are similar to the nested versions above -#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) +/** + * @brief Set a watchpoint to watch the last 32 bytes of the stack + * + * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint + * around. + * + * @param pxStackStart Pointer to the start of the stack + */ +void vPortSetStackWatchpoint( void *pxStackStart ); -//Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force -//the stack memory to always be internal. -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps) -#define pvPortMallocStackMem(size) heap_caps_malloc(size, portStackMemoryCaps) - -//xTaskCreateStatic uses these functions to check incoming memory. -#define portVALID_TCB_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY -#define portVALID_STACK_MEM(ptr) esp_ptr_byte_accessible(ptr) -#else -#define portVALID_STACK_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#endif +/** + * @brief Get the current core's ID + * + * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly + * @return BaseType_t Core ID + */ +static inline BaseType_t IRAM_ATTR xPortGetCoreID(void); -static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) -{ -#ifdef CONFIG_SPIRAM - compare_and_set_extram(addr, compare, set); -#endif -} +/* ------------------------------------------- FreeRTOS Porting Interface ---------------------------------------------- + * - Contains all the mappings of the macros required by FreeRTOS + * - Most come after forward declare as porting macros map to declared functions + * - Maps to forward declared functions + * ------------------------------------------------------------------------------------------------------------------ */ -/*-----------------------------------------------------------*/ +// ----------------------- Memory -------------------------- -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 4 -#define portNOP() XT_NOP() -/*-----------------------------------------------------------*/ +/** + * @brief Task memory allocation macros + * + * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack + * memory to always be internal. + * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes + */ +#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +#define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps) +#define pvPortMallocStackMem(size) heap_caps_malloc(size, portStackMemoryCaps) -/* Fine resolution time */ -#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() -//ccount or esp_timer are initialized elsewhere -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +// --------------------- Interrupts ------------------------ -#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER -/* Coarse resolution time (us) */ -#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do {x = (uint32_t)esp_timer_get_time();} while(0) -#endif +#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) -void vPortYield( void ); -void vPortEvaluateYieldFromISR(int argc, ...); -void _frxt_setup_switch( void ); +/** + * - Only applies to current core + * - These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. + * + * @note [refactor-todo] replace XTOS_SET_INTLEVEL with more efficient version, if any? + */ +#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) +#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) /** - * Macro to count number of arguments of a __VA_ARGS__ used to support portYIELD_FROM_ISR with, - * or without arguments. The macro counts only 0 or 1 arguments. + * ISR versions to enable/disable interrupts + */ +#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) + +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + +// ------------------ Critical Sections -------------------- + +/** + * @brief FreeRTOS critical section macros * - * In the future, we want to switch to C++20. We also want to become compatible with clang. - * Hence, we provide two versions of the following macros which are using variadic arguments. - * The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,). - * This allows users to compile their code with standard C++20 enabled instead of the GNU extension. - * Below C++20, we haven't found any good alternative to using ##__VA_ARGS__. + * - Added a spinlock argument for SMP + * - Can be nested + * - Compliance versions will assert if regular critical section API is used in ISR context + * - Safe versions can be called from either contexts */ -#if defined(__cplusplus) && (__cplusplus > 201703L) -#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0 __VA_OPT__(,) __VA_ARGS__,1,0) +#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE +#define portENTER_CRITICAL(mux) vPortEnterCriticalCompliance(mux) +#define portEXIT_CRITICAL(mux) vPortExitCriticalCompliance(mux) #else -#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0, ##__VA_ARGS__,1,0) -#endif -#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count +#define portENTER_CRITICAL(mux) vPortEnterCritical(mux) +#define portEXIT_CRITICAL(mux) vPortExitCritical(mux) +#endif /* CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE */ +#define portENTER_CRITICAL_ISR(mux) vPortEnterCritical(mux) +#define portEXIT_CRITICAL_ISR(mux) vPortExitCritical(mux) +#define portENTER_CRITICAL_SAFE(mux) vPortEnterCriticalSafe(mux) +#define portEXIT_CRITICAL_SAFE(mux) vPortExitCriticalSafe(mux) -_Static_assert(portGET_ARGUMENT_COUNT() == 0, "portGET_ARGUMENT_COUNT() result does not match for 0 arguments"); -_Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result does not match for 1 argument"); +// ---------------------- Yielding ------------------------- -#define portYIELD() vPortYield() +#define portYIELD() vPortYield() /** * @note The macro below could be used when passing a single argument, or without any argument, * it was developed to support both usages of portYIELD inside of an ISR. Any other usage form - * might result in undesired behaviour + * might result in undesired behavior + * + * @note [refactor-todo] Refactor this to avoid va_args */ #if defined(__cplusplus) && (__cplusplus > 201703L) #define portYIELD_FROM_ISR(...) vPortEvaluateYieldFromISR(portGET_ARGUMENT_COUNT(__VA_ARGS__) __VA_OPT__(,) __VA_ARGS__) @@ -351,121 +483,137 @@ _Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result */ #define portYIELD_WITHIN_API() esp_crosscore_int_send_yield(xPortGetCoreID()) -/*-----------------------------------------------------------*/ - -/* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) - -// When coprocessors are defined, we to maintain a pointer to coprocessors area. -// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: -// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. -// The field is normally used for memory protection. FreeRTOS should create another general purpose field. -typedef struct { - #if XCHAL_CP_NUM > 0 - volatile StackType_t* coproc_area; // Pointer to coprocessor save area; MUST BE FIRST - #endif - - #if portUSING_MPU_WRAPPERS - // Define here mpu_settings, which is port dependent - int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet - #endif - - #if configUSE_TRACE_FACILITY_2 - struct { - // Cf. porttraceStamp() - int taskstamp; /* Stamp from inside task to see where we are */ - int taskstampcount; /* A counter usually incremented when we restart the task's loop */ - } porttrace; - #endif -} xMPU_SETTINGS; - -// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) -#if (XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area - #undef portUSING_MPU_WRAPPERS - #define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area - #define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA -#endif - -extern void esp_vApplicationIdleHook( void ); -extern void esp_vApplicationTickHook( void ); +// ------------------- Hook Functions ---------------------- #ifndef CONFIG_FREERTOS_LEGACY_HOOKS -#define vApplicationIdleHook esp_vApplicationIdleHook -#define vApplicationTickHook esp_vApplicationTickHook +#define vApplicationIdleHook esp_vApplicationIdleHook +#define vApplicationTickHook esp_vApplicationTickHook #endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */ -void vApplicationSleep( TickType_t xExpectedIdleTime ); +#define portSUPPRESS_TICKS_AND_SLEEP(idleTime) vApplicationSleep(idleTime) -#define portSUPPRESS_TICKS_AND_SLEEP( idleTime ) vApplicationSleep( idleTime ) +// ------------------- Run Time Stats ---------------------- -void _xt_coproc_release(volatile void * coproc_sa_base); +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() -/* Architecture specific optimisations. */ -#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 +/** + * - Fine resolution uses ccount + * - ALT is coarse and uses esp_timer + * @note [refactor-todo] Make fine and alt timers mutually exclusive + */ +#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() +#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER +#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do {x = (uint32_t)esp_timer_get_time();} while(0) +#endif +// -------------- Optimized Task Selection ----------------- + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 /* Check the configuration. */ #if( configMAX_PRIORITIES > 32 ) - #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice. +#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice. #endif /* Store/clear the ready priorities in a bit map. */ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) +#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( ( uxReadyPriorities ) ) ) +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -/*-----------------------------------------------------------*/ -#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( ( uxReadyPriorities ) ) ) -#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +/* --------------------------------------------- Inline Implementations ------------------------------------------------ + * - Implementation of inline functions of the forward declares + * - Should come after forward declare and FreeRTOS Porting interface, as implementation may use both. + * - For implementation of non-inlined functions, see port.c + * ------------------------------------------------------------------------------------------------------------------ */ -/* - * Send an interrupt to another core in order to make the task running - * on it yield for a higher-priority task. - */ +// --------------------- Interrupts ------------------------ -void vPortYieldOtherCore( BaseType_t coreid) ; +static inline unsigned portENTER_CRITICAL_NESTED(void) +{ + unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); + portbenchmarkINTERRUPT_DISABLE(); + return state; +} -/* - Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack - watchpoint around. - */ -void vPortSetStackWatchpoint( void* pxStackStart ); +// ---------------------- Spinlocks ------------------------ -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. - */ -BaseType_t xPortInIsrContext(void); +static inline void __attribute__((always_inline)) vPortCPUInitializeMutex(portMUX_TYPE *mux) +{ + spinlock_initialize(mux); +} -/* - * This function will be called in High prio ISRs. Returns true if the current core was in ISR context - * before calling into high prio ISR context. - */ -BaseType_t xPortInterruptedFromISRContext(void); +static inline void __attribute__((always_inline)) vPortCPUAcquireMutex(portMUX_TYPE *mux) +{ + spinlock_acquire(mux, portMUX_NO_TIMEOUT); +} -/* - * The structures and methods of manipulating the MPU are contained within the - * port layer. - * - * Fills the xMPUSettings structure with the memory region information - * contained in xRegions. - */ -#if( portUSING_MPU_WRAPPERS == 1 ) - struct xMEMORY_REGION; - void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION; - void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings ); +static inline bool __attribute__((always_inline)) vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout) +{ + return (spinlock_acquire(mux, timeout)); +} + +static inline void __attribute__((always_inline)) vPortCPUReleaseMutex(portMUX_TYPE *mux) +{ + spinlock_release(mux); +} + +static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ + compare_and_set_native(addr, compare, set); +} + +static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set) +{ +#ifdef CONFIG_SPIRAM + compare_and_set_extram(addr, compare, set); #endif +} -/* Multi-core: get current core ID */ -static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) { - return cpu_hal_get_core_id(); +// ------------------ Critical Sections -------------------- + +static inline void __attribute__((always_inline)) vPortEnterCriticalCompliance(portMUX_TYPE *mux) +{ + if (!xPortInIsrContext()) { + vPortEnterCritical(mux); + } else { + esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } } -/* Get tick rate per second */ -uint32_t xPortGetTickRateHz(void); +static inline void __attribute__((always_inline)) vPortExitCriticalCompliance(portMUX_TYPE *mux) +{ + if (!xPortInIsrContext()) { + vPortExitCritical(mux); + } else { + esp_rom_printf("%s:%d (%s)- port*_CRITICAL called from ISR context!\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } +} + +static inline void __attribute__((always_inline)) vPortEnterCriticalSafe(portMUX_TYPE *mux) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(mux); + } else { + portENTER_CRITICAL(mux); + } +} + +static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_TYPE *mux) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(mux); + } else { + portEXIT_CRITICAL(mux); + } +} + +// ---------------------- Yielding ------------------------- static inline bool IRAM_ATTR xPortCanYield(void) { @@ -484,22 +632,115 @@ static inline bool IRAM_ATTR xPortCanYield(void) return ((ps_reg & PS_INTLEVEL_MASK) == 0); } -// porttrace -#if configUSE_TRACE_FACILITY_2 -#include "porttrace.h" +// ----------------------- System -------------------------- + +static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) +{ + return (uint32_t) cpu_hal_get_core_id(); +} + + + +/* ------------------------------------------------------ Misc --------------------------------------------------------- + * - Miscellaneous porting macros + * - These are not port of the FreeRTOS porting interface, but are used by other FreeRTOS dependent components + * - [refactor-todo] Remove dependency on MPU wrappers by modifying TCB + * ------------------------------------------------------------------------------------------------------------------ */ + +// -------------------- Co-Processor ----------------------- + +// When coprocessors are defined, we maintain a pointer to coprocessors area. +// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: +// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. +// The field is normally used for memory protection. FreeRTOS should create another general purpose field. +typedef struct { +#if XCHAL_CP_NUM > 0 + volatile StackType_t *coproc_area; // Pointer to coprocessor save area; MUST BE FIRST +#endif + +#if portUSING_MPU_WRAPPERS + // Define here mpu_settings, which is port dependent + int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet #endif +} xMPU_SETTINGS; -// configASSERT_2 if requested -#if configASSERT_2 -#include -void exit(int); -#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); } +// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) +#if (XCHAL_CP_NUM > 0) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area +#undef portUSING_MPU_WRAPPERS +#define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area +#define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code +#define PRIVILEGED_FUNCTION +#define PRIVILEGED_DATA #endif -#endif // __ASSEMBLER__ +void _xt_coproc_release(volatile void *coproc_sa_base); + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +struct xMEMORY_REGION; +void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION *const xRegions, StackType_t *pxBottomOfStack, uint32_t usStackDepth ) PRIVILEGED_FUNCTION; +void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings ); +#endif + +// -------------------- VA_ARGS Yield ---------------------- + +/** + * Macro to count number of arguments of a __VA_ARGS__ used to support portYIELD_FROM_ISR with, + * or without arguments. The macro counts only 0 or 1 arguments. + * + * In the future, we want to switch to C++20. We also want to become compatible with clang. + * Hence, we provide two versions of the following macros which are using variadic arguments. + * The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,). + * This allows users to compile their code with standard C++20 enabled instead of the GNU extension. + * Below C++20, we haven't found any good alternative to using ##__VA_ARGS__. + */ +#if defined(__cplusplus) && (__cplusplus > 201703L) +#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0 __VA_OPT__(,) __VA_ARGS__,1,0) +#else +#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0, ##__VA_ARGS__,1,0) +#endif +#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count + +_Static_assert(portGET_ARGUMENT_COUNT() == 0, "portGET_ARGUMENT_COUNT() result does not match for 0 arguments"); +_Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result does not match for 1 argument"); + +// -------------------- Heap Related ----------------------- + +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in port_common.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); + +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) #ifdef __cplusplus } #endif +#endif // __ASSEMBLER__ + #endif /* PORTMACRO_H */ diff --git a/tools/sdk/esp32s2/include/hal/esp32s2/include/hal/rmt_ll.h b/tools/sdk/esp32s2/include/hal/esp32s2/include/hal/rmt_ll.h index 958fe7aef5d..ba73eaa2b75 100644 --- a/tools/sdk/esp32s2/include/hal/esp32s2/include/hal/rmt_ll.h +++ b/tools/sdk/esp32s2/include/hal/esp32s2/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -22,6 +15,8 @@ extern "C" { #endif +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ + #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) diff --git a/tools/sdk/esp32s2/include/hal/include/hal/i2s_hal.h b/tools/sdk/esp32s2/include/hal/include/hal/i2s_hal.h index a08813db808..037970fa2b3 100644 --- a/tools/sdk/esp32s2/include/hal/include/hal/i2s_hal.h +++ b/tools/sdk/esp32s2/include/hal/include/hal/i2s_hal.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -176,28 +168,28 @@ void i2s_hal_enable_slave_fd_mode(i2s_hal_context_t *hal); * * @param hal Context of the HAL layer */ -#define i2s_hal_start_tx(hal) i2s_ll_tx_start((hal)->dev) +void i2s_hal_start_tx(i2s_hal_context_t *hal); /** * @brief Start I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_start_rx(hal) i2s_ll_rx_start((hal)->dev) +void i2s_hal_start_rx(i2s_hal_context_t *hal); /** * @brief Stop I2S tx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_tx(hal) i2s_ll_tx_stop((hal)->dev) +void i2s_hal_stop_tx(i2s_hal_context_t *hal); /** * @brief Stop I2S rx * * @param hal Context of the HAL layer */ -#define i2s_hal_stop_rx(hal) i2s_ll_rx_stop((hal)->dev) +void i2s_hal_stop_rx(i2s_hal_context_t *hal); /** * @brief Set the received data length to trigger `in_suc_eof` interrupt. diff --git a/tools/sdk/esp32s2/include/hal/include/hal/lcd_hal.h b/tools/sdk/esp32s2/include/hal/include/hal/lcd_hal.h index 76e28dda0e4..db255b3d1e4 100644 --- a/tools/sdk/esp32s2/include/hal/include/hal/lcd_hal.h +++ b/tools/sdk/esp32s2/include/hal/include/hal/lcd_hal.h @@ -1,22 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * NOTICE - * The HAL is not public api, don't use in application code. - * See readme.md in soc/README.md - ******************************************************************************/ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/tools/sdk/esp32s2/include/hal/include/hal/lcd_types.h b/tools/sdk/esp32s2/include/hal/include/hal/lcd_types.h index 69dab14801d..01e6d0c2949 100644 --- a/tools/sdk/esp32s2/include/hal/include/hal/lcd_types.h +++ b/tools/sdk/esp32s2/include/hal/include/hal/lcd_types.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -21,15 +13,12 @@ extern "C" { /** * @brief LCD clock source * @note User should select the clock source based on the real requirement: - * ╔═════════════════════╦══════════════════════════╦════════════════════════════╗ - * ║ LCD clock source ║ Features ║ Power Management ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_PLL160M ║ High resolution, fixed ║ ESP_PM_APB_FREQ_MAX lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_APLL ║ Configurable resolution ║ ESP_PM_NO_LIGHT_SLEEP lock ║ - * ╠═════════════════════╬══════════════════════════╬════════════════════════════╣ - * ║ LCD_CLK_SRC_XTAL ║ Medium resolution, fixed ║ No PM lock ║ - * ╚═════════════════════╩══════════════════════════╩════════════════════════════╝ + * + * | LCD clock source | Features | Power Management | + * |---------------------|--------------------------|----------------------------| + * | LCD_CLK_SRC_PLL160M | High resolution, fixed | ESP_PM_APB_FREQ_MAX lock | + * | LCD_CLK_SRC_APLL | Configurable resolution | ESP_PM_NO_LIGHT_SLEEP lock | + * | LCD_CLK_SRC_XTAL | Medium resolution, fixed | No PM lock | */ typedef enum { LCD_CLK_SRC_PLL160M, /*!< Select PLL160M as the source clock */ diff --git a/tools/sdk/esp32s2/include/hal/include/hal/touch_sensor_types.h b/tools/sdk/esp32s2/include/hal/include/hal/touch_sensor_types.h index ec027bf8705..9085f5eecd8 100644 --- a/tools/sdk/esp32s2/include/hal/include/hal/touch_sensor_types.h +++ b/tools/sdk/esp32s2/include/hal/include/hal/touch_sensor_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -155,12 +147,23 @@ typedef enum { TOUCH_PAD_INTR_MASK_INACTIVE = BIT(2), /*! +#include +#include "sdkconfig.h" +#include "esp_err.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#endif +#include "esp_flash.h" +#include "hal/spi_flash_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief To setup Flash chip + */ +esp_err_t spi_flash_init_chip_state(void); + +/** + * @brief Make MSPI work under 20Mhz + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_low_speed_mode(bool control_spi1); + +/** + * @brief Make MSPI work under the frequency as users set + * @param control_spi1 Select whether to control SPI1. For tuning, we need to use SPI1. After tuning (during startup stage), let the flash driver to control SPI1 + */ +void spi_timing_enter_mspi_high_speed_mode(bool control_spi1); + +/** + * @brief Tune MSPI flash timing to make it work under high frequency + */ +void spi_timing_flash_tuning(void); + +/** + * @brief Tune MSPI psram timing to make it work under high frequency + */ +void spi_timing_psram_tuning(void); + +/** + * @brief To initislize the MSPI pins + */ +void esp_mspi_pin_init(void); + +/** + * @brief Set SPI1 registers to make ROM functions work + * @note This function is used for setting SPI1 registers to the state that ROM SPI functions work + */ +void spi_flash_set_rom_required_regs(void); + +/** + * @brief Initialize main flash + * @param chip Pointer to main SPI flash(SPI1 CS0) chip to use.. + */ +esp_err_t esp_flash_init_main(esp_flash_t *chip); + +/** + * @brief Should be only used by SPI1 Flash driver to know the necessary timing registers + * @param out_timing_config Pointer to timing_tuning parameters. + */ +void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing_config); + +/** + * @brief Judge if the flash in tuned + */ +bool spi_timine_config_flash_is_tuned(void); + +/** + * @brief Set Flash chip specifically required MSPI register settings here + */ +void spi_flash_set_vendor_required_regs(void); + + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h b/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h new file mode 100644 index 00000000000..4292213943f --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_mbo.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ESP_MBO_H +#define _ESP_MBO_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum non_pref_chan_reason: Reason for non preference of channel + */ +enum non_pref_chan_reason { + NON_PREF_CHAN_REASON_UNSPECIFIED = 0, + NON_PREF_CHAN_REASON_RSSI = 1, + NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, + NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, +}; + +/** + * @brief Channel structure for non preferred channel + * + * @param reason: enum non_pref_chan_reason + * @param oper_class: operating class for the channel + * @param chan: channel number + * @param preference: channel preference + */ +struct non_pref_chan { + enum non_pref_chan_reason reason; + uint8_t oper_class; + uint8_t chan; + uint8_t preference; +}; + +/** + * @brief Array structure for non preferred channel struct + * + * @param non_pref_chan_num: channel count + * @param chan: array of non_pref_chan type + */ +struct non_pref_chan_s { + size_t non_pref_chan_num; + struct non_pref_chan chan[]; +}; + +/** + * @brief Update channel preference for MBO IE + * + * @param non_pref_chan: Non preference channel list + * + * @return + * - 0: success else failure + */ +int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h b/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h index a1dcfb655c5..4301385d2cf 100644 --- a/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h +++ b/tools/sdk/esp32s2/include/wpa_supplicant/esp_supplicant/include/esp_wnm.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef _ESP_WNM_H @@ -29,11 +19,13 @@ enum btm_query_reason { REASON_UNSPECIFIED = 0, REASON_FRAME_LOSS = 1, REASON_DELAY = 2, - REASON_QOS_CAPACITY = 3, - REASON_FIRST_ASSOC = 4, - REASON_LOAD_BALALNCE = 5, - REASON_BETTER_AP = 6, - REASON_CURRENT_DEAUTH = 7, + REASON_BANDWIDTH = 3, + REASON_LOAD_BALANCE = 4, + REASON_RSSI = 5, + REASON_RETRANSMISSIONS = 6, + REASON_INTERFERENCE = 7, + REASON_GRAY_ZONE = 8, + REASON_PREMIUM_AP = 9, }; /** diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h new file mode 100644 index 00000000000..c6c86bc536f --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_dpp.h @@ -0,0 +1,116 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_DPP_H +#define ESP_DPP_H + +#include + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ +#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */ +#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ + +/** @brief Types of Bootstrap Methods for DPP. */ +typedef enum dpp_bootstrap_type { + DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ + DPP_BOOTSTRAP_PKEX, /**< Proof of Knowledge Method */ + DPP_BOOTSTRAP_NFC_URI, /**< NFC URI record Method */ +} esp_supp_dpp_bootstrap_t; + +/** @brief Types of Callback Events received from DPP Supplicant. */ +typedef enum { + ESP_SUPP_DPP_URI_READY, /**< URI is ready through Bootstrapping */ + ESP_SUPP_DPP_CFG_RECVD, /**< Config received via DPP Authentication */ + ESP_SUPP_DPP_FAIL, /**< DPP Authentication failure */ +} esp_supp_dpp_event_t; + +/** + * @brief Callback function for receiving DPP Events from Supplicant. + * + * Callback function will be called with DPP related information. + * + * @param evt DPP event ID + * @param data Event data payload + */ +typedef void (*esp_supp_dpp_event_cb_t)(esp_supp_dpp_event_t evt, void *data); + +/** + * @brief Initialize DPP Supplicant + * + * Starts DPP Supplicant and initializes related Data Structures. + * + * @param evt_cb Callback function to receive DPP related events + * + * return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t evt_cb); + +/** + * @brief De-initalize DPP Supplicant + * + * Frees memory from DPP Supplicant Data Structures. + */ +void esp_supp_dpp_deinit(void); + +/** + * @brief Generates Bootstrap Information as an Enrollee. + * + * Generates Out Of Band Bootstrap information as an Enrollee which can be + * used by a DPP Configurator to provision the Enrollee. + * + * @param chan_list List of channels device will be available on for listening + * @param type Bootstrap method type, only QR Code method is supported for now. + * @param key (Optional) Private Key used to generate a Bootstrapping Public Key + * @param info (Optional) Ancilliary Device Information like Serial Number + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Failure + */ +esp_err_t +esp_supp_dpp_bootstrap_gen(const char *chan_list, esp_supp_dpp_bootstrap_t type, + const char *key, const char *info); + +/** + * @brief Start listening on Channels provided during esp_supp_dpp_bootstrap_gen. + * + * Listens on every Channel from Channel List for a pre-defined wait time. + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Generic Failure + * - ESP_ERR_INVALID_STATE: ROC attempted before WiFi is started + * - ESP_ERR_NO_MEM: Memory allocation failed while posting ROC request + */ +esp_err_t esp_supp_dpp_start_listen(void); + +/** + * @brief Stop listening on Channels. + * + * Stops listening on Channels and cancels ongoing listen operation. + */ +void esp_supp_dpp_stop_listen(void); + +#ifdef __cplusplus +} +#endif +#endif /* ESP_DPP_H */ diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h new file mode 100644 index 00000000000..1ffcf180475 --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_rrm.h @@ -0,0 +1,52 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_RRM_H +#define _ESP_RRM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Callback function type to get neighbor report + * + * @param ctx: neighbor report context + * @param report: neighbor report + * @param report_len: neighbor report length + * + * @return + * - void + */ +typedef void (*neighbor_rep_request_cb)(void *ctx, const uint8_t *report, size_t report_len); + +/** + * @brief Send Radio measurement neighbor report request to connected AP + * + * @param cb: callback function for neighbor report + * @param cb_ctx: callback context + * + * @return + * - 0: success else failure + */ +int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb, + void *cb_ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h new file mode 100644 index 00000000000..a1dcfb655c5 --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wnm.h @@ -0,0 +1,56 @@ +/** + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ESP_WNM_H +#define _ESP_WNM_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * enum btm_query_reason: Reason code for sending btm query + */ +enum btm_query_reason { + REASON_UNSPECIFIED = 0, + REASON_FRAME_LOSS = 1, + REASON_DELAY = 2, + REASON_QOS_CAPACITY = 3, + REASON_FIRST_ASSOC = 4, + REASON_LOAD_BALALNCE = 5, + REASON_BETTER_AP = 6, + REASON_CURRENT_DEAUTH = 7, +}; + +/** + * @brief Send bss transition query to connected AP + * + * @param query_reason: reason for sending query + * @param btm_candidates: btm candidates list if available + * @param cand_list: whether candidate list to be included from scan results available in supplicant's cache. + * + * @return + * - 0: success else failure + */ +int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, + const char *btm_candidates, + int cand_list); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h new file mode 100644 index 00000000000..f448b737c70 --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa.h @@ -0,0 +1,79 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPA_H__ +#define __ESP_WPA_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_wifi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPA_APIs WPS APIs + * @brief ESP32 Supplicant APIs + * + */ + +/** @addtogroup WPA_APIs + * @{ + */ +/* Crypto callback functions */ +const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; +/* Mesh crypto callback functions */ +const mesh_crypto_funcs_t g_wifi_default_mesh_crypto_funcs; + +/** + * @brief Supplicant initialization + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_NO_MEM : out of memory + */ +esp_err_t esp_supplicant_init(void); + +/** + * @brief Supplicant deinitialization + * + * @return + * - ESP_OK : succeed + * - others: failed + */ +esp_err_t esp_supplicant_deinit(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPA_H__ */ diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h new file mode 100644 index 00000000000..c6c2930a0fe --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wpa2.h @@ -0,0 +1,215 @@ +// Hardware crypto support Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP_WPA2_H +#define _ESP_WPA2_H + +#include + +#include "esp_err.h" + +typedef enum { + ESP_EAP_TTLS_PHASE2_EAP, + ESP_EAP_TTLS_PHASE2_MSCHAPV2, + ESP_EAP_TTLS_PHASE2_MSCHAP, + ESP_EAP_TTLS_PHASE2_PAP, + ESP_EAP_TTLS_PHASE2_CHAP +} esp_eap_ttls_phase2_types ; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_enable(void); + +/** + * @brief Disable wpa2 enterprise authentication. + * + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * + * @return + * - ESP_OK: succeed. + */ +esp_err_t esp_wifi_sta_wpa2_ent_disable(void); + +/** + * @brief Set identity for PEAP/TTLS method. + * + * @attention The API only passes the parameter identity to the global pointer variable in wpa2 enterprise module. + * + * @param identity: point to address where stores the identity; + * @param len: length of identity, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len); + +/** + * @brief Clear identity for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_identity(void); + +/** + * @brief Set username for PEAP/TTLS method. + * + * @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module. + * + * @param username: point to address where stores the username; + * @param len: length of username, limited to 1~127 + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len); + +/** + * @brief Clear username for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_username(void); + +/** + * @brief Set password for PEAP/TTLS method.. + * + * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * + * @param password: point to address where stores the password; + * @param len: length of password(len > 0) + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len); + +/** + * @brief Clear password for PEAP/TTLS method.. + */ +void esp_wifi_sta_wpa2_ent_clear_password(void); + +/** + * @brief Set new password for MSCHAPv2 method.. + * + * @attention 1. The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * @attention 2. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. + * + * @param new_password: point to address where stores the password; + * @param len: length of password + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_INVALID_ARG: fail(len <= 0) + * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) + */ + +esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len); + +/** + * @brief Clear new password for MSCHAPv2 method.. + */ +void esp_wifi_sta_wpa2_ent_clear_new_password(void); + +/** + * @brief Set CA certificate for PEAP/TTLS method. + * + * @attention 1. The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. + * @attention 2. The ca_cert should be zero terminated. + * + * @param ca_cert: point to address where stores the CA certificate; + * @param ca_cert_len: length of ca_cert + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len); + +/** + * @brief Clear CA certificate for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); + +/** + * @brief Set client certificate and key. + * + * @attention 1. The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. + * @attention 2. The client_cert, private_key and private_key_passwd should be zero terminated. + * + * @param client_cert: point to address where stores the client certificate; + * @param client_cert_len: length of client certificate; + * @param private_key: point to address where stores the private key; + * @param private_key_len: length of private key, limited to 1~2048; + * @param private_key_password: point to address where stores the private key password; + * @param private_key_password_len: length of private key password; + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len); + +/** + * @brief Clear client certificate and key. + */ +void esp_wifi_sta_wpa2_ent_clear_cert_key(void); + +/** + * @brief Set wpa2 enterprise certs time check(disable or not). + * + * @param true: disable wpa2 enterprise certs time check + * @param false: enable wpa2 enterprise certs time check + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); + +/** + * @brief Get wpa2 enterprise certs time check(disable or not). + * + * @param disable: store disable value + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); + +/** + * @brief Set wpa2 enterprise ttls phase2 method + * + * @param type: the type of phase 2 method to be used + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wps.h b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wps.h new file mode 100644 index 00000000000..25c06782ecb --- /dev/null +++ b/tools/sdk/esp32s2/include/wpa_supplicant/include/esp_supplicant/esp_wps.h @@ -0,0 +1,141 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPS_H__ +#define __ESP_WPS_H__ + +#include +#include +#include "esp_err.h" +#include "esp_wifi_crypto_types.h" +#include "esp_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP32 WPS APIs + * + * WPS can only be used when ESP32 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +#define ESP_ERR_WIFI_REGISTRAR (ESP_ERR_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ +#define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_MAX, +} wps_type_t; + +#define WPS_MAX_MANUFACTURER_LEN 65 +#define WPS_MAX_MODEL_NUMBER_LEN 33 +#define WPS_MAX_MODEL_NAME_LEN 33 +#define WPS_MAX_DEVICE_NAME_LEN 33 + +typedef struct { + char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer, null-terminated string. The default manufcturer is used if the string is empty */ + char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number, null-terminated string. The default model number is used if the string is empty */ + char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name, null-terminated string. The default model name is used if the string is empty */ + char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name, null-terminated string. The default device name is used if the string is empty */ +} wps_factory_information_t; + +typedef struct { + wps_type_t wps_type; + wps_factory_information_t factory_info; +} esp_wps_config_t; + +#define WPS_CONFIG_INIT_DEFAULT(type) { \ + .wps_type = type, \ + .factory_info = { \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP32") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_name, "ESPRESSIF IOT") \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(device_name, "ESP STATION") \ + } \ +} + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_enable(const esp_wps_config_t *config); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + */ +esp_err_t esp_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time (not supported in IDF v1.0) + * + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_FAIL : wps initialization fails + */ +esp_err_t esp_wifi_wps_start(int timeout_ms); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPS_H__ */ diff --git a/tools/sdk/esp32s2/ld/libcat_face_detect.a b/tools/sdk/esp32s2/ld/libcat_face_detect.a index 1bc5162b09f..98527ca429a 100644 Binary files a/tools/sdk/esp32s2/ld/libcat_face_detect.a and b/tools/sdk/esp32s2/ld/libcat_face_detect.a differ diff --git a/tools/sdk/esp32s2/ld/libdetection.a b/tools/sdk/esp32s2/ld/libdetection.a new file mode 100644 index 00000000000..8d5081bdfd9 Binary files /dev/null and b/tools/sdk/esp32s2/ld/libdetection.a differ diff --git a/tools/sdk/esp32s2/ld/libdetection_cat_face.a b/tools/sdk/esp32s2/ld/libdetection_cat_face.a new file mode 100644 index 00000000000..e1d42e756b8 Binary files /dev/null and b/tools/sdk/esp32s2/ld/libdetection_cat_face.a differ diff --git a/tools/sdk/esp32s2/ld/libdl.a b/tools/sdk/esp32s2/ld/libdl.a index 1e6c8c48421..efe06e32edb 100644 Binary files a/tools/sdk/esp32s2/ld/libdl.a and b/tools/sdk/esp32s2/ld/libdl.a differ diff --git a/tools/sdk/esp32s2/ld/libfd.a b/tools/sdk/esp32s2/ld/libfd.a new file mode 100644 index 00000000000..9f58faef4a2 Binary files /dev/null and b/tools/sdk/esp32s2/ld/libfd.a differ diff --git a/tools/sdk/esp32s2/ld/libfr.a b/tools/sdk/esp32s2/ld/libfr.a new file mode 100644 index 00000000000..c824bcd9a3e Binary files /dev/null and b/tools/sdk/esp32s2/ld/libfr.a differ diff --git a/tools/sdk/esp32s2/ld/libhuman_face_detect.a b/tools/sdk/esp32s2/ld/libhuman_face_detect.a index 72fd6f5eb49..2e04b6d2a42 100644 Binary files a/tools/sdk/esp32s2/ld/libhuman_face_detect.a and b/tools/sdk/esp32s2/ld/libhuman_face_detect.a differ diff --git a/tools/sdk/esp32s2/ld/libpe.a b/tools/sdk/esp32s2/ld/libpe.a new file mode 100644 index 00000000000..b859f2429eb Binary files /dev/null and b/tools/sdk/esp32s2/ld/libpe.a differ diff --git a/tools/sdk/esp32s2/ld/sections.ld b/tools/sdk/esp32s2/ld/sections.ld index 94bf03d6a9f..197a6d90670 100644 --- a/tools/sdk/esp32s2/ld/sections.ld +++ b/tools/sdk/esp32s2/ld/sections.ld @@ -1,6 +1,6 @@ /* Automatically generated file; DO NOT EDIT */ /* Espressif IoT Development Framework Linker Script */ -/* Generated from: /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32s2/sections.ld.in */ +/* Generated from: /home/rocorbera/esp32-arduino-lib-builder/esp-idf/components/esp_system/ld/esp32s2/sections.ld.in */ /* * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD @@ -371,8 +371,8 @@ SECTIONS *(.ext_ram.bss*) *(.bss .bss.*) - *(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem) *(.ext_ram.bss .ext_ram.bss.*) + *(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem) *(COMMON) _bt_bss_start = ABSOLUTE(.); *libbt.a:(.bss .bss.* COMMON) diff --git a/tools/sdk/esp32s2/lib/libapp_trace.a b/tools/sdk/esp32s2/lib/libapp_trace.a index 65b1f96e83b..c8673c34dec 100644 Binary files a/tools/sdk/esp32s2/lib/libapp_trace.a and b/tools/sdk/esp32s2/lib/libapp_trace.a differ diff --git a/tools/sdk/esp32s2/lib/libapp_update.a b/tools/sdk/esp32s2/lib/libapp_update.a index 36db9c85c17..0267911be0a 100644 Binary files a/tools/sdk/esp32s2/lib/libapp_update.a and b/tools/sdk/esp32s2/lib/libapp_update.a differ diff --git a/tools/sdk/esp32s2/lib/libarduino_tinyusb.a b/tools/sdk/esp32s2/lib/libarduino_tinyusb.a index e004a2db069..96c73be7f62 100644 Binary files a/tools/sdk/esp32s2/lib/libarduino_tinyusb.a and b/tools/sdk/esp32s2/lib/libarduino_tinyusb.a differ diff --git a/tools/sdk/esp32s2/lib/libasio.a b/tools/sdk/esp32s2/lib/libasio.a index 3a23faf503f..4f8424e9518 100644 Binary files a/tools/sdk/esp32s2/lib/libasio.a and b/tools/sdk/esp32s2/lib/libasio.a differ diff --git a/tools/sdk/esp32s2/lib/libbootloader_support.a b/tools/sdk/esp32s2/lib/libbootloader_support.a index ffa6ff3b490..eeddc4359db 100644 Binary files a/tools/sdk/esp32s2/lib/libbootloader_support.a and b/tools/sdk/esp32s2/lib/libbootloader_support.a differ diff --git a/tools/sdk/esp32s2/lib/libcbor.a b/tools/sdk/esp32s2/lib/libcbor.a index 0e973091ed6..1c62db34f0c 100644 Binary files a/tools/sdk/esp32s2/lib/libcbor.a and b/tools/sdk/esp32s2/lib/libcbor.a differ diff --git a/tools/sdk/esp32s2/lib/libcmock.a b/tools/sdk/esp32s2/lib/libcmock.a index 8c67b445ecf..1e317cdd767 100644 Binary files a/tools/sdk/esp32s2/lib/libcmock.a and b/tools/sdk/esp32s2/lib/libcmock.a differ diff --git a/tools/sdk/esp32s2/lib/libcoap.a b/tools/sdk/esp32s2/lib/libcoap.a index 6a5173eb19d..b2f311ad028 100644 Binary files a/tools/sdk/esp32s2/lib/libcoap.a and b/tools/sdk/esp32s2/lib/libcoap.a differ diff --git a/tools/sdk/esp32s2/lib/libcoexist.a b/tools/sdk/esp32s2/lib/libcoexist.a index 0f146c2c899..cfc9be30fc2 100644 Binary files a/tools/sdk/esp32s2/lib/libcoexist.a and b/tools/sdk/esp32s2/lib/libcoexist.a differ diff --git a/tools/sdk/esp32s2/lib/libconsole.a b/tools/sdk/esp32s2/lib/libconsole.a index 3f95dd5e32d..e2ca4c3bbb7 100644 Binary files a/tools/sdk/esp32s2/lib/libconsole.a and b/tools/sdk/esp32s2/lib/libconsole.a differ diff --git a/tools/sdk/esp32s2/lib/libcore.a b/tools/sdk/esp32s2/lib/libcore.a index e017a1006a3..0ea53525c5b 100644 Binary files a/tools/sdk/esp32s2/lib/libcore.a and b/tools/sdk/esp32s2/lib/libcore.a differ diff --git a/tools/sdk/esp32s2/lib/libcxx.a b/tools/sdk/esp32s2/lib/libcxx.a index 9202ad02b03..8e37a2d3bca 100644 Binary files a/tools/sdk/esp32s2/lib/libcxx.a and b/tools/sdk/esp32s2/lib/libcxx.a differ diff --git a/tools/sdk/esp32s2/lib/libdriver.a b/tools/sdk/esp32s2/lib/libdriver.a index 271f07c3d00..81289c142be 100644 Binary files a/tools/sdk/esp32s2/lib/libdriver.a and b/tools/sdk/esp32s2/lib/libdriver.a differ diff --git a/tools/sdk/esp32s2/lib/libefuse.a b/tools/sdk/esp32s2/lib/libefuse.a index 45e85b5b281..f1edd6ac5fb 100644 Binary files a/tools/sdk/esp32s2/lib/libefuse.a and b/tools/sdk/esp32s2/lib/libefuse.a differ diff --git a/tools/sdk/esp32s2/lib/libesp-dsp.a b/tools/sdk/esp32s2/lib/libesp-dsp.a index bba63702a29..757dbd5e4e4 100644 Binary files a/tools/sdk/esp32s2/lib/libesp-dsp.a and b/tools/sdk/esp32s2/lib/libesp-dsp.a differ diff --git a/tools/sdk/esp32s2/lib/libesp-face.a b/tools/sdk/esp32s2/lib/libesp-face.a new file mode 100644 index 00000000000..b5de62de45e Binary files /dev/null and b/tools/sdk/esp32s2/lib/libesp-face.a differ diff --git a/tools/sdk/esp32s2/lib/libesp-tls.a b/tools/sdk/esp32s2/lib/libesp-tls.a index 0fbddfec7bd..27e135fdb21 100644 Binary files a/tools/sdk/esp32s2/lib/libesp-tls.a and b/tools/sdk/esp32s2/lib/libesp-tls.a differ diff --git a/tools/sdk/esp32s2/lib/libesp32-camera.a b/tools/sdk/esp32s2/lib/libesp32-camera.a index b6dff3e52a3..ecb2641baa8 100644 Binary files a/tools/sdk/esp32s2/lib/libesp32-camera.a and b/tools/sdk/esp32s2/lib/libesp32-camera.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_adc_cal.a b/tools/sdk/esp32s2/lib/libesp_adc_cal.a index a400ccd3958..994e10284d4 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_adc_cal.a and b/tools/sdk/esp32s2/lib/libesp_adc_cal.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_common.a b/tools/sdk/esp32s2/lib/libesp_common.a index 3d55f543596..78d530fd6a7 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_common.a and b/tools/sdk/esp32s2/lib/libesp_common.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_eth.a b/tools/sdk/esp32s2/lib/libesp_eth.a index 5a3c5d1ec1f..db263aaa3fc 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_eth.a and b/tools/sdk/esp32s2/lib/libesp_eth.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_event.a b/tools/sdk/esp32s2/lib/libesp_event.a index 3ba390e2ef4..9dab5f6e91e 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_event.a and b/tools/sdk/esp32s2/lib/libesp_event.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_gdbstub.a b/tools/sdk/esp32s2/lib/libesp_gdbstub.a index 2432b1aeced..c10a56f5c46 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_gdbstub.a and b/tools/sdk/esp32s2/lib/libesp_gdbstub.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_hid.a b/tools/sdk/esp32s2/lib/libesp_hid.a index 82ea9ff4cbb..fc8744e2568 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_hid.a and b/tools/sdk/esp32s2/lib/libesp_hid.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_http_client.a b/tools/sdk/esp32s2/lib/libesp_http_client.a index 557786f2310..23932f290fd 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_http_client.a and b/tools/sdk/esp32s2/lib/libesp_http_client.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_http_server.a b/tools/sdk/esp32s2/lib/libesp_http_server.a index 7dcb8e9bdb5..5253d353b66 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_http_server.a and b/tools/sdk/esp32s2/lib/libesp_http_server.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_https_ota.a b/tools/sdk/esp32s2/lib/libesp_https_ota.a index 31fadcfb272..8015a63306d 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_https_ota.a and b/tools/sdk/esp32s2/lib/libesp_https_ota.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_https_server.a b/tools/sdk/esp32s2/lib/libesp_https_server.a index fe3cf5581d8..0da4a22d579 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_https_server.a and b/tools/sdk/esp32s2/lib/libesp_https_server.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_hw_support.a b/tools/sdk/esp32s2/lib/libesp_hw_support.a index 2dacebef4e3..b3620b30309 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_hw_support.a and b/tools/sdk/esp32s2/lib/libesp_hw_support.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_ipc.a b/tools/sdk/esp32s2/lib/libesp_ipc.a index a846df70856..b44a2486eb7 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_ipc.a and b/tools/sdk/esp32s2/lib/libesp_ipc.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_lcd.a b/tools/sdk/esp32s2/lib/libesp_lcd.a index 4bcdbecb1ca..1aee9f6bbe4 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_lcd.a and b/tools/sdk/esp32s2/lib/libesp_lcd.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_littlefs.a b/tools/sdk/esp32s2/lib/libesp_littlefs.a index 16cb7dea9b6..4bb50319d2c 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_littlefs.a and b/tools/sdk/esp32s2/lib/libesp_littlefs.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_local_ctrl.a b/tools/sdk/esp32s2/lib/libesp_local_ctrl.a index fabc0fe34f0..7d91bb10db9 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_local_ctrl.a and b/tools/sdk/esp32s2/lib/libesp_local_ctrl.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_netif.a b/tools/sdk/esp32s2/lib/libesp_netif.a index e30fa30a9b5..9c8acc0a6a7 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_netif.a and b/tools/sdk/esp32s2/lib/libesp_netif.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_phy.a b/tools/sdk/esp32s2/lib/libesp_phy.a index 10c41de3f84..5ed42dd8715 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_phy.a and b/tools/sdk/esp32s2/lib/libesp_phy.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_pm.a b/tools/sdk/esp32s2/lib/libesp_pm.a index ffa717deb5d..7ac5d005c6b 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_pm.a and b/tools/sdk/esp32s2/lib/libesp_pm.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_ringbuf.a b/tools/sdk/esp32s2/lib/libesp_ringbuf.a index 46a0abb1b61..e7fd9eeeb97 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_ringbuf.a and b/tools/sdk/esp32s2/lib/libesp_ringbuf.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_rom.a b/tools/sdk/esp32s2/lib/libesp_rom.a index 0febf6d1d1b..d97c81d484a 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_rom.a and b/tools/sdk/esp32s2/lib/libesp_rom.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_serial_slave_link.a b/tools/sdk/esp32s2/lib/libesp_serial_slave_link.a index eb9d9aa7d49..0e841e7b2d4 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_serial_slave_link.a and b/tools/sdk/esp32s2/lib/libesp_serial_slave_link.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_system.a b/tools/sdk/esp32s2/lib/libesp_system.a index 338875d18ca..6a116cde392 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_system.a and b/tools/sdk/esp32s2/lib/libesp_system.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_timer.a b/tools/sdk/esp32s2/lib/libesp_timer.a index c869d63ec01..74f03161edf 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_timer.a and b/tools/sdk/esp32s2/lib/libesp_timer.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_websocket_client.a b/tools/sdk/esp32s2/lib/libesp_websocket_client.a index 86d2344ffa3..c4c113f5f4f 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_websocket_client.a and b/tools/sdk/esp32s2/lib/libesp_websocket_client.a differ diff --git a/tools/sdk/esp32s2/lib/libesp_wifi.a b/tools/sdk/esp32s2/lib/libesp_wifi.a index 8b21c2fc5a0..b88f18f4233 100644 Binary files a/tools/sdk/esp32s2/lib/libesp_wifi.a and b/tools/sdk/esp32s2/lib/libesp_wifi.a differ diff --git a/tools/sdk/esp32s2/lib/libespcoredump.a b/tools/sdk/esp32s2/lib/libespcoredump.a index 25b0cc93cad..ba60e661e49 100644 Binary files a/tools/sdk/esp32s2/lib/libespcoredump.a and b/tools/sdk/esp32s2/lib/libespcoredump.a differ diff --git a/tools/sdk/esp32s2/lib/libespnow.a b/tools/sdk/esp32s2/lib/libespnow.a index debe3c57249..1c9c4851315 100644 Binary files a/tools/sdk/esp32s2/lib/libespnow.a and b/tools/sdk/esp32s2/lib/libespnow.a differ diff --git a/tools/sdk/esp32s2/lib/libexpat.a b/tools/sdk/esp32s2/lib/libexpat.a index acca6db56f4..936db49c186 100644 Binary files a/tools/sdk/esp32s2/lib/libexpat.a and b/tools/sdk/esp32s2/lib/libexpat.a differ diff --git a/tools/sdk/esp32s2/lib/libfatfs.a b/tools/sdk/esp32s2/lib/libfatfs.a index 9a65e421336..c8dd745974f 100644 Binary files a/tools/sdk/esp32s2/lib/libfatfs.a and b/tools/sdk/esp32s2/lib/libfatfs.a differ diff --git a/tools/sdk/esp32s2/lib/libfb_gfx.a b/tools/sdk/esp32s2/lib/libfb_gfx.a index f2dce54418f..e2f18fd139e 100644 Binary files a/tools/sdk/esp32s2/lib/libfb_gfx.a and b/tools/sdk/esp32s2/lib/libfb_gfx.a differ diff --git a/tools/sdk/esp32s2/lib/libfreemodbus.a b/tools/sdk/esp32s2/lib/libfreemodbus.a index 50511f3c123..9a33a2f50e7 100644 Binary files a/tools/sdk/esp32s2/lib/libfreemodbus.a and b/tools/sdk/esp32s2/lib/libfreemodbus.a differ diff --git a/tools/sdk/esp32s2/lib/libfreertos.a b/tools/sdk/esp32s2/lib/libfreertos.a index 733f6a3ee3a..15a13497b96 100644 Binary files a/tools/sdk/esp32s2/lib/libfreertos.a and b/tools/sdk/esp32s2/lib/libfreertos.a differ diff --git a/tools/sdk/esp32s2/lib/libhal.a b/tools/sdk/esp32s2/lib/libhal.a index c13b15b5ff4..323114b5e6b 100644 Binary files a/tools/sdk/esp32s2/lib/libhal.a and b/tools/sdk/esp32s2/lib/libhal.a differ diff --git a/tools/sdk/esp32s2/lib/libheap.a b/tools/sdk/esp32s2/lib/libheap.a index 7ed09f63f9c..5e5c8a241f3 100644 Binary files a/tools/sdk/esp32s2/lib/libheap.a and b/tools/sdk/esp32s2/lib/libheap.a differ diff --git a/tools/sdk/esp32s2/lib/libjsmn.a b/tools/sdk/esp32s2/lib/libjsmn.a index 6003fb46def..887c506716e 100644 Binary files a/tools/sdk/esp32s2/lib/libjsmn.a and b/tools/sdk/esp32s2/lib/libjsmn.a differ diff --git a/tools/sdk/esp32s2/lib/libjson.a b/tools/sdk/esp32s2/lib/libjson.a index a68d1c0e1dc..56516e094ab 100644 Binary files a/tools/sdk/esp32s2/lib/libjson.a and b/tools/sdk/esp32s2/lib/libjson.a differ diff --git a/tools/sdk/esp32s2/lib/liblibsodium.a b/tools/sdk/esp32s2/lib/liblibsodium.a index d7bf4c3da7b..d035dea7dd3 100644 Binary files a/tools/sdk/esp32s2/lib/liblibsodium.a and b/tools/sdk/esp32s2/lib/liblibsodium.a differ diff --git a/tools/sdk/esp32s2/lib/liblog.a b/tools/sdk/esp32s2/lib/liblog.a index cd6ad238403..0c6bae1c89f 100644 Binary files a/tools/sdk/esp32s2/lib/liblog.a and b/tools/sdk/esp32s2/lib/liblog.a differ diff --git a/tools/sdk/esp32s2/lib/liblwip.a b/tools/sdk/esp32s2/lib/liblwip.a index 84c9a7cbc7c..bd0c1170ff4 100644 Binary files a/tools/sdk/esp32s2/lib/liblwip.a and b/tools/sdk/esp32s2/lib/liblwip.a differ diff --git a/tools/sdk/esp32s2/lib/libmbedcrypto.a b/tools/sdk/esp32s2/lib/libmbedcrypto.a index c11c0cb50c2..5bda65be138 100644 Binary files a/tools/sdk/esp32s2/lib/libmbedcrypto.a and b/tools/sdk/esp32s2/lib/libmbedcrypto.a differ diff --git a/tools/sdk/esp32s2/lib/libmbedtls.a b/tools/sdk/esp32s2/lib/libmbedtls.a index c69d43d797a..6f228b03075 100644 Binary files a/tools/sdk/esp32s2/lib/libmbedtls.a and b/tools/sdk/esp32s2/lib/libmbedtls.a differ diff --git a/tools/sdk/esp32s2/lib/libmbedx509.a b/tools/sdk/esp32s2/lib/libmbedx509.a index 55a4fb5da7e..86a67c690eb 100644 Binary files a/tools/sdk/esp32s2/lib/libmbedx509.a and b/tools/sdk/esp32s2/lib/libmbedx509.a differ diff --git a/tools/sdk/esp32s2/lib/libmdns.a b/tools/sdk/esp32s2/lib/libmdns.a index 863f659c447..8c45fc45578 100644 Binary files a/tools/sdk/esp32s2/lib/libmdns.a and b/tools/sdk/esp32s2/lib/libmdns.a differ diff --git a/tools/sdk/esp32s2/lib/libmesh.a b/tools/sdk/esp32s2/lib/libmesh.a index 8f4fbde53cd..4a43e09b1c2 100644 Binary files a/tools/sdk/esp32s2/lib/libmesh.a and b/tools/sdk/esp32s2/lib/libmesh.a differ diff --git a/tools/sdk/esp32s2/lib/libmqtt.a b/tools/sdk/esp32s2/lib/libmqtt.a index 56d63e439e0..ad06c8c31be 100644 Binary files a/tools/sdk/esp32s2/lib/libmqtt.a and b/tools/sdk/esp32s2/lib/libmqtt.a differ diff --git a/tools/sdk/esp32s2/lib/libnet80211.a b/tools/sdk/esp32s2/lib/libnet80211.a index 93351e991c8..69800846e43 100644 Binary files a/tools/sdk/esp32s2/lib/libnet80211.a and b/tools/sdk/esp32s2/lib/libnet80211.a differ diff --git a/tools/sdk/esp32s2/lib/libnewlib.a b/tools/sdk/esp32s2/lib/libnewlib.a index 1f724357d57..c2013d3f6b2 100644 Binary files a/tools/sdk/esp32s2/lib/libnewlib.a and b/tools/sdk/esp32s2/lib/libnewlib.a differ diff --git a/tools/sdk/esp32s2/lib/libnghttp.a b/tools/sdk/esp32s2/lib/libnghttp.a index b264a45cd59..cc1421b38aa 100644 Binary files a/tools/sdk/esp32s2/lib/libnghttp.a and b/tools/sdk/esp32s2/lib/libnghttp.a differ diff --git a/tools/sdk/esp32s2/lib/libnvs_flash.a b/tools/sdk/esp32s2/lib/libnvs_flash.a index a75e4c5782c..03498c32d73 100644 Binary files a/tools/sdk/esp32s2/lib/libnvs_flash.a and b/tools/sdk/esp32s2/lib/libnvs_flash.a differ diff --git a/tools/sdk/esp32s2/lib/libopenssl.a b/tools/sdk/esp32s2/lib/libopenssl.a index 0c02d23769a..3917cd32dce 100644 Binary files a/tools/sdk/esp32s2/lib/libopenssl.a and b/tools/sdk/esp32s2/lib/libopenssl.a differ diff --git a/tools/sdk/esp32s2/lib/libperfmon.a b/tools/sdk/esp32s2/lib/libperfmon.a index 226764c3eae..977718fb363 100644 Binary files a/tools/sdk/esp32s2/lib/libperfmon.a and b/tools/sdk/esp32s2/lib/libperfmon.a differ diff --git a/tools/sdk/esp32s2/lib/libpp.a b/tools/sdk/esp32s2/lib/libpp.a index 3aa7310ee69..f6b7fc13fee 100644 Binary files a/tools/sdk/esp32s2/lib/libpp.a and b/tools/sdk/esp32s2/lib/libpp.a differ diff --git a/tools/sdk/esp32s2/lib/libprotobuf-c.a b/tools/sdk/esp32s2/lib/libprotobuf-c.a index 104d1fb6539..bd72361b281 100644 Binary files a/tools/sdk/esp32s2/lib/libprotobuf-c.a and b/tools/sdk/esp32s2/lib/libprotobuf-c.a differ diff --git a/tools/sdk/esp32s2/lib/libprotocomm.a b/tools/sdk/esp32s2/lib/libprotocomm.a index 42d5c8885f5..e74662f9bbd 100644 Binary files a/tools/sdk/esp32s2/lib/libprotocomm.a and b/tools/sdk/esp32s2/lib/libprotocomm.a differ diff --git a/tools/sdk/esp32s2/lib/libpthread.a b/tools/sdk/esp32s2/lib/libpthread.a index 9bbcb0516fd..6d62d05663e 100644 Binary files a/tools/sdk/esp32s2/lib/libpthread.a and b/tools/sdk/esp32s2/lib/libpthread.a differ diff --git a/tools/sdk/esp32s2/lib/libsdmmc.a b/tools/sdk/esp32s2/lib/libsdmmc.a index ba4320bc74d..ac4661cead4 100644 Binary files a/tools/sdk/esp32s2/lib/libsdmmc.a and b/tools/sdk/esp32s2/lib/libsdmmc.a differ diff --git a/tools/sdk/esp32s2/lib/libsmartconfig.a b/tools/sdk/esp32s2/lib/libsmartconfig.a index 29134ba9039..d1b81cbf1ea 100644 Binary files a/tools/sdk/esp32s2/lib/libsmartconfig.a and b/tools/sdk/esp32s2/lib/libsmartconfig.a differ diff --git a/tools/sdk/esp32s2/lib/libsoc.a b/tools/sdk/esp32s2/lib/libsoc.a index 57560c731e3..6090aa85fe5 100644 Binary files a/tools/sdk/esp32s2/lib/libsoc.a and b/tools/sdk/esp32s2/lib/libsoc.a differ diff --git a/tools/sdk/esp32s2/lib/libspi_flash.a b/tools/sdk/esp32s2/lib/libspi_flash.a index 7d19d683fd9..8587f7b6c09 100644 Binary files a/tools/sdk/esp32s2/lib/libspi_flash.a and b/tools/sdk/esp32s2/lib/libspi_flash.a differ diff --git a/tools/sdk/esp32s2/lib/libspiffs.a b/tools/sdk/esp32s2/lib/libspiffs.a index eb8c65fa83b..5d74ba04291 100644 Binary files a/tools/sdk/esp32s2/lib/libspiffs.a and b/tools/sdk/esp32s2/lib/libspiffs.a differ diff --git a/tools/sdk/esp32s2/lib/libtcp_transport.a b/tools/sdk/esp32s2/lib/libtcp_transport.a index 993d07d6661..74704e0eead 100644 Binary files a/tools/sdk/esp32s2/lib/libtcp_transport.a and b/tools/sdk/esp32s2/lib/libtcp_transport.a differ diff --git a/tools/sdk/esp32s2/lib/libtcpip_adapter.a b/tools/sdk/esp32s2/lib/libtcpip_adapter.a index 6c20dd87b02..7119cb6e2d6 100644 Binary files a/tools/sdk/esp32s2/lib/libtcpip_adapter.a and b/tools/sdk/esp32s2/lib/libtcpip_adapter.a differ diff --git a/tools/sdk/esp32s2/lib/libtouch_element.a b/tools/sdk/esp32s2/lib/libtouch_element.a index 8720a0c1b40..a2a9772e603 100644 Binary files a/tools/sdk/esp32s2/lib/libtouch_element.a and b/tools/sdk/esp32s2/lib/libtouch_element.a differ diff --git a/tools/sdk/esp32s2/lib/libulp.a b/tools/sdk/esp32s2/lib/libulp.a index b69794e91a2..22d3400a7ce 100644 Binary files a/tools/sdk/esp32s2/lib/libulp.a and b/tools/sdk/esp32s2/lib/libulp.a differ diff --git a/tools/sdk/esp32s2/lib/libunity.a b/tools/sdk/esp32s2/lib/libunity.a index c4b917780c3..57868c7b89e 100644 Binary files a/tools/sdk/esp32s2/lib/libunity.a and b/tools/sdk/esp32s2/lib/libunity.a differ diff --git a/tools/sdk/esp32s2/lib/libusb.a b/tools/sdk/esp32s2/lib/libusb.a index c6004586a2f..63e3ec9a4b0 100644 Binary files a/tools/sdk/esp32s2/lib/libusb.a and b/tools/sdk/esp32s2/lib/libusb.a differ diff --git a/tools/sdk/esp32s2/lib/libvfs.a b/tools/sdk/esp32s2/lib/libvfs.a index 94902934bd2..3865c1c84c7 100644 Binary files a/tools/sdk/esp32s2/lib/libvfs.a and b/tools/sdk/esp32s2/lib/libvfs.a differ diff --git a/tools/sdk/esp32s2/lib/libwapi.a b/tools/sdk/esp32s2/lib/libwapi.a index 91bddc368c8..8914130654f 100644 Binary files a/tools/sdk/esp32s2/lib/libwapi.a and b/tools/sdk/esp32s2/lib/libwapi.a differ diff --git a/tools/sdk/esp32s2/lib/libwear_levelling.a b/tools/sdk/esp32s2/lib/libwear_levelling.a index f27dd314042..c31cf1de422 100644 Binary files a/tools/sdk/esp32s2/lib/libwear_levelling.a and b/tools/sdk/esp32s2/lib/libwear_levelling.a differ diff --git a/tools/sdk/esp32s2/lib/libwifi_provisioning.a b/tools/sdk/esp32s2/lib/libwifi_provisioning.a index 40d6d4fc7f7..eb121721b4c 100644 Binary files a/tools/sdk/esp32s2/lib/libwifi_provisioning.a and b/tools/sdk/esp32s2/lib/libwifi_provisioning.a differ diff --git a/tools/sdk/esp32s2/lib/libwpa_supplicant.a b/tools/sdk/esp32s2/lib/libwpa_supplicant.a index 5afc5fd0100..e680f7542b9 100644 Binary files a/tools/sdk/esp32s2/lib/libwpa_supplicant.a and b/tools/sdk/esp32s2/lib/libwpa_supplicant.a differ diff --git a/tools/sdk/esp32s2/lib/libxtensa.a b/tools/sdk/esp32s2/lib/libxtensa.a index c7ff5169849..583d9e0bf8b 100644 Binary files a/tools/sdk/esp32s2/lib/libxtensa.a and b/tools/sdk/esp32s2/lib/libxtensa.a differ diff --git a/tools/sdk/esp32s2/sdkconfig b/tools/sdk/esp32s2/sdkconfig index be0df95cf98..15bd9ca2603 100644 --- a/tools/sdk/esp32s2/sdkconfig +++ b/tools/sdk/esp32s2/sdkconfig @@ -62,7 +62,6 @@ CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x10 # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Bootloader config # @@ -94,7 +93,6 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set @@ -286,6 +284,36 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # CONFIG_ASIO_SSL_SUPPORT is not set # end of ESP-ASIO +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +CONFIG_BT_RESERVE_DRAM=0 +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y + # # CoAP Configuration # @@ -306,12 +334,6 @@ CONFIG_COAP_LOG_DEFAULT_LEVEL=0 CONFIG_ADC_DISABLE_DAC=y # end of ADC configuration -# -# MCPWM configuration -# -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# end of MCPWM configuration - # # SPI configuration # @@ -348,8 +370,6 @@ CONFIG_EFUSE_MAX_BLK_LEN=256 CONFIG_ESP_TLS_USING_MBEDTLS=y CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y CONFIG_ESP_TLS_SERVER=y -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS @@ -409,7 +429,6 @@ CONFIG_SPIRAM_USE_MALLOC=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 -# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set # end of SPI RAM config # CONFIG_ESP32S2_TRAX is not set @@ -525,27 +544,12 @@ CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 # # Sleep Config # -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND is not set -# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set # end of Sleep Config # end of Hardware Settings -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -# end of IPC (Inter-Processor Call) - # # LCD and Touch Panel # - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# end of LCD Peripheral Configuration # end of LCD and Touch Panel # @@ -587,11 +591,8 @@ CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y # # Memory protection # -CONFIG_ESP_SYSTEM_MEMPROT_DEPCHECK=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y -CONFIG_ESP_SYSTEM_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 -CONFIG_ESP_SYSTEM_MEMPROT_MEM_ALIGN_SIZE=4 # end of Memory protection CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 @@ -615,8 +616,8 @@ CONFIG_ESP_TASK_WDT=y CONFIG_ESP_TASK_WDT_PANIC=y CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 # CONFIG_ESP_PANIC_HANDLER_IRAM is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y # end of ESP System Settings # @@ -734,8 +735,6 @@ CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 CONFIG_FMB_TIMER_PORT_ENABLED=y CONFIG_FMB_TIMER_GROUP=0 CONFIG_FMB_TIMER_INDEX=0 -CONFIG_FMB_MASTER_TIMER_GROUP=0 -CONFIG_FMB_MASTER_TIMER_INDEX=0 # CONFIG_FMB_TIMER_ISR_IN_IRAM is not set # end of Modbus configuration @@ -744,10 +743,8 @@ CONFIG_FMB_MASTER_TIMER_INDEX=0 # CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y CONFIG_FREERTOS_HZ=1000 # CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION is not set @@ -776,8 +773,6 @@ CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set # end of FreeRTOS # @@ -842,7 +837,6 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LWIP_LOCAL_HOSTNAME="espressif" # CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # CONFIG_LWIP_L2_TO_L3_COPY is not set # CONFIG_LWIP_IRAM_OPTIMIZATION is not set @@ -881,6 +875,7 @@ CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=0 # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -958,8 +953,7 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # # SNTP # -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 # end of SNTP @@ -1051,7 +1045,6 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set CONFIG_MBEDTLS_SSL_PROTO_DTLS=y CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1122,7 +1115,6 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 # CONFIG_MDNS_STRICT_MODE is not set CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set # end of mDNS # @@ -1263,10 +1255,10 @@ CONFIG_WS_BUFFER_SIZE=1024 # end of TCP Transport # -# TinyUSB Stack +# TinyUSB # -# CONFIG_TINYUSB is not set -# end of TinyUSB Stack +# CONFIG_USB_ENABLED is not set +# end of TinyUSB # # Unity unit testing library @@ -1280,16 +1272,6 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library -# -# USB-OTG -# -CONFIG_USB_OTG_SUPPORTED=y -CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 -CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y -# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set -# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set -# end of USB-OTG - # # Virtual file system # @@ -1348,6 +1330,37 @@ CONFIG_DSP_MAX_FFT_SIZE_4096=y CONFIG_DSP_MAX_FFT_SIZE=4096 # end of DSP Library +CONFIG_C_IMPL=y +# CONFIG_XTENSA_IMPL is not set + +# +# ESP-FACE Configuration +# +CONFIG_MTMN_LITE_QUANT=y +# CONFIG_MTMN_LITE_FLOAT is not set +# CONFIG_MTMN_HEAVY_QUANT is not set +# CONFIG_FRMN is not set +CONFIG_MFN56_1X=y +# CONFIG_MFN56_2X is not set +# CONFIG_MFN56_3X is not set +# CONFIG_MFN56_4X is not set + +# +# Object Detection +# +# CONFIG_DETECT_WITH_LANDMARK is not set +# end of Object Detection + +# +# Pose Estimation +# +CONFIG_HD_NANO1=y +# CONFIG_HD_LITE1 is not set +CONFIG_HP_NANO1=y +# CONFIG_HP_LITE1 is not set +# end of Pose Estimation +# end of ESP-FACE Configuration + # # Camera configuration # @@ -1420,15 +1433,6 @@ CONFIG_MONITOR_BAUD_115200B=y # CONFIG_MONITOR_BAUD_OTHER is not set CONFIG_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_MONITOR_BAUD=115200 -CONFIG_USB_CDC_ENABLED=y -CONFIG_USB_DESC_CDC_STRING="Espressif CDC Device" -CONFIG_USB_CDC_RX_BUFSIZE=64 -CONFIG_USB_CDC_TX_BUFSIZE=64 -CONFIG_USB_MSC_ENABLED=y -CONFIG_USB_DESC_MSC_STRING="Espressif MSC Device" -CONFIG_USB_MSC_BUFSIZE=512 -CONFIG_USB_DESC_HID_STRING="Espressif HID Device" -CONFIG_USB_DEBUG_LEVEL=0 # CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set # CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y @@ -1447,11 +1451,14 @@ CONFIG_WARN_WRITE_STRINGS=y # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 CONFIG_ADC2_DISABLE_DAC=y # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_IPC_TASK_STACK_SIZE=1024 # CONFIG_ESP32S2_PANIC_PRINT_HALT is not set CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y # CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set @@ -1474,6 +1481,7 @@ CONFIG_TASK_WDT=y CONFIG_TASK_WDT_PANIC=y CONFIG_TASK_WDT_TIMEOUT_S=5 # CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=4096 # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set @@ -1533,16 +1541,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_USB_ENABLED is not set -CONFIG_USB_DEBUG_LEVEL=0 -CONFIG_USB_DESC_CDC_STRING="Espressif CDC Device" -CONFIG_USB_DESC_MSC_STRING="Espressif MSC Device" -CONFIG_USB_DESC_HID_STRING="Espressif HID Device" -CONFIG_USB_MSC_ENABLED=y -CONFIG_USB_MSC_BUFSIZE=512 -CONFIG_USB_CDC_ENABLED=y -CONFIG_USB_CDC_RX_BUFSIZE=64 -CONFIG_USB_CDC_TX_BUFSIZE=64 CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1