Raspberry BASIC

Author Topic: Pico  (Read 7463 times)

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Pico
« on: January 27, 2021, 08:53:40 PM »
I'm in the process of creating a ScriptBasic build for the new RPi Pico. ScriptBasic by design is an embeddable highly configurable micro controller scripting engine. It is used commercially by Banner Engineering and Controlled Soutions with their micro controller solutions.

If you have interest in joining me in this adventure, send support@raspberrybasic.org a request to join the forum.
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #1 on: January 29, 2021, 09:55:11 PM »
My Pico arrived. I installed the Pico development system on my RPi 4B running Ubuntu 20.04 64 bit.

The blink example compiled and ran fine on the Pico.
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #2 on: January 30, 2021, 03:20:48 PM »
After taking a peek at the MicroPython implementation on the Pico. I can't see having to run ScripBasic in single step debug mode. C is the language best fit for the Pico.
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #3 on: January 31, 2021, 06:19:00 PM »
I've decided to put my ScriptBasic embedded controller efforts into the Zero. A few bucks more and not a crippled toy like the Pico. I'm sure the Pico has a purpose but I don't know what it is yet.
I have yet to discover any resemblance of an OS.

Sort of like a microwave CPU being repurposed to control the stove.
« Last Edit: February 01, 2021, 05:25:31 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #4 on: February 26, 2021, 08:11:27 AM »
After getting over ruining my first Pico installing the headers, my hybrid Pico arrived today. Headers, reset button and WIFI. Now to have some fun with CBASIC.
 
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #5 on: February 27, 2021, 08:56:35 AM »
I was able to get the Hello World to work with my new DIYMall ESP32-PICO board. Setting this up was a job.

Code: C
  1. /* Hello World Example
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9. #include <stdio.h>
  10. #include "sdkconfig.h"
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "esp_system.h"
  14. #include "esp_spi_flash.h"
  15.  
  16. void app_main(void)
  17. {
  18.     printf("Hello world!\n");
  19.  
  20.     /* Print chip information */
  21.     esp_chip_info_t chip_info;
  22.     esp_chip_info(&chip_info);
  23.     printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
  24.             CONFIG_IDF_TARGET,
  25.             chip_info.cores,
  26.             (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
  27.             (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
  28.  
  29.     printf("silicon revision %d, ", chip_info.revision);
  30.  
  31.     printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
  32.             (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
  33.  
  34.     printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
  35.  
  36.     for (int i = 10; i >= 0; i--) {
  37.         printf("Restarting in %d seconds...\n", i);
  38.         vTaskDelay(1000 / portTICK_PERIOD_MS);
  39.     }
  40.     printf("Restarting now.\n");
  41.     fflush(stdout);
  42.     esp_restart();
  43. }
  44.  


pi@RPi3B:~/esp/hello_world $ idf.py -p /dev/ttyUSB0 monitor
WARNING: Support for Python 2 is deprecated and will be removed in future versions.
Executing action: monitor
Running idf_monitor in directory /home/pi/esp/hello_world
Executing "/home/pi/.espressif/python_env/idf4.4_py2.7_env/bin/python /home/pi/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix xtensa-esp32-elf- /home/pi/esp/hello_world/build/hello-world.elf -m '/home/pi/.espressif/python_env/idf4.4_py2.7_env/bin/python' '/home/pi/esp/esp-idf/tools/idf.py' '-p' '/dev/ttyUSB0'"...
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6916
load:0x40078000,len:14336
ho 0 tail 12 room 4
load:0x40080400,len:3672
0x40080400: _init at ??:?

entry 0x40080678
I (29) boot: ESP-IDF v4.4-dev-4-g73db14240 2nd stage bootloader
I (30) boot: compile time 00:12:01
I (30) boot: chip revision: 1
I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (41) boot.esp32: SPI Speed      : 40MHz
I (45) boot.esp32: SPI Mode       : DIO
I (50) boot.esp32: SPI Flash Size : 2MB
I (54) boot: Enabling RNG early entropy source...
I (60) boot: Partition Table:
I (63) boot: ## Label            Usage          Type ST Offset   Length
I (71) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (78) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (86) boot:  2 factory          factory app      00 00 00010000 00100000
I (93) boot: End of partition table
I (97) boot_comm: chip revision: 1, min. application chip revision: 0
I (104) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=05f24h ( 24356) map
I (122) esp_image: segment 1: paddr=00015f4c vaddr=3ffb0000 size=02880h ( 10368) load
I (126) esp_image: segment 2: paddr=000187d4 vaddr=40080000 size=07844h ( 30788) load
I (142) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=138e4h ( 80100) map
I (171) esp_image: segment 4: paddr=0003390c vaddr=40087844 size=032f0h ( 13040) load
I (182) boot: Loaded app from partition at offset 0x10000
I (182) boot: Disabling RNG early entropy source...
I (194) cpu_start: Pro cpu up.
I (194) cpu_start: Starting app cpu, entry point is 0x40080f30
0x40080f30: call_start_cpu1 at /home/pi/esp/esp-idf/components/esp_system/port/cpu_start.c:143

I (0) cpu_start: App cpu up.
I (208) cpu_start: Pro cpu start user code
I (208) cpu_start: cpu freq: 160000000
I (208) cpu_start: Application information:
I (213) cpu_start: Project name:     hello-world
I (218) cpu_start: App version:      1
I (223) cpu_start: Compile time:     Feb 27 2021 00:14:37
I (229) cpu_start: ELF file SHA256:  bd8ca58e2e4262a6...
I (235) cpu_start: ESP-IDF:          v4.4-dev-4-g73db14240
I (241) heap_init: Initializing. RAM available for dynamic allocation:
I (248) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (254) heap_init: At 3FFB30B8 len 0002CF48 (179 KiB): DRAM
I (260) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (267) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (273) heap_init: At 4008AB34 len 000154CC (85 KiB): IRAM
I (280) spi_flash: detected chip: gd
I (284) spi_flash: flash io: dio
W (288) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (302) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision 1, 2MB embedded flash
Minimum free heap size: 291656 bytes
Restarting in 10 seconds...

ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #6 on: February 28, 2021, 12:09:14 PM »
I was able to get CBASIC working with the ESP32-PICO. This is an example of random number generation and calculating the mean value. This example shows using a separate C program as a component.

Code: C
  1. #include <stdio.h>
  2. #include "esp_system.h"
  3. #include "testable.h"
  4. #include "cbasic.h"
  5.  
  6. SUB app_main(void)
  7. BEGIN_SUB
  8.   CONST int count = 32;
  9.   CONST int max = 100;
  10.   PRINT("In main application. Collecting %d random numbers from 1 to %d:\n", count, max);
  11.   DIM int AS PTR numbers = calloc(count, sizeof(numbers[0]));
  12.   DEF_FOR(int i = 0 TO i < count STEP INCR i)
  13.   BEGIN_FOR
  14.     numbers[i] = 1 + esp_random() MOD (max - 1);
  15.     PRINT("%4d ", numbers[i]);
  16.     IF ((i + 1) MOD 10 == 0) THEN
  17.       PRINT("\n");
  18.     END_IF
  19.   NEXT
  20.   DIM int AS mean = testable_mean(numbers, count);
  21.   PRINT ("\nMean: %d\n", mean);
  22.   free(numbers);
  23. END_SUB
  24.  

mean.c
Code: C
  1. #include "testable.h"
  2. #include "cbasic.h"
  3.  
  4. FUNCTION int testable_mean(const int PTR values, int count)
  5. BEGIN_FUNCTION
  6.   IF (count == 0) THEN
  7.     RETURN_FUNCTION(0);
  8.   END_IF
  9.   DIM int AS sum = 0;
  10.   DEF_FOR (int i = 0 TO i < count STEP INCR i)
  11.   BEGIN_FOR
  12.      sum += values[i];
  13.   NEXT
  14.   RETURN_FUNCTION(sum / count);
  15. END_FUNCTION
  16.  

testable.h
Code: C
  1. #pragma once
  2.  
  3. /**
  4.  * @brief Calculate arithmetic mean of integer values
  5.  * @param values  array of values
  6.  * @param count   number of elements in the array
  7.  * @return arithmetic mean of values, or zero count is zero
  8.  */
  9. int testable_mean(const int* values, int count);
  10.  


pi@RPi3B:~/esp/unit_test $ idf.py -p /dev/ttyUSB0 monitor
WARNING: Python 3 versions older than 3.6 are not supported.
Executing action: monitor
Running idf_monitor in directory /home/pi/esp/unit_test
Executing "/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python /home/pi/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix xtensa-esp32-elf- /home/pi/esp/unit_test/build/unit_test.elf -m '/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python' '/home/pi/esp/esp-idf/tools/idf.py' '-p' '/dev/ttyUSB0'"...
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6916
load:0x40078000,len:14336
ho 0 tail 12 room 4
load:0x40080400,len:3672
0x40080400: _init at ??:?

entry 0x40080678
I (30) boot: ESP-IDF v4.4-dev-4-g73db14240 2nd stage bootloader
I (30) boot: compile time 03:48:52
I (30) boot: chip revision: 1
I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (41) boot.esp32: SPI Speed      : 40MHz
I (46) boot.esp32: SPI Mode       : DIO
I (50) boot.esp32: SPI Flash Size : 2MB
I (55) boot: Enabling RNG early entropy source...
I (60) boot: Partition Table:
I (64) boot: ## Label            Usage          Type ST Offset   Length
I (71) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (78) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (86) boot:  2 factory          factory app      00 00 00010000 00100000
I (93) boot: End of partition table
I (97) boot_comm: chip revision: 1, min. application chip revision: 0
I (105) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=05bbch ( 23484) map
I (121) esp_image: segment 1: paddr=00015be4 vaddr=3ffb0000 size=02860h ( 10336) load
I (126) esp_image: segment 2: paddr=0001844c vaddr=40080000 size=07bcch ( 31692) load
I (143) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1337ch ( 78716) map
I (171) esp_image: segment 4: paddr=000333a4 vaddr=40087bcc size=02f6ch ( 12140) load
I (182) boot: Loaded app from partition at offset 0x10000
I (182) boot: Disabling RNG early entropy source...
I (194) cpu_start: Pro cpu up.
I (194) cpu_start: Starting app cpu, entry point is 0x40080f34
0x40080f34: call_start_cpu1 at /home/pi/esp/esp-idf/components/esp_system/port/cpu_start.c:143

I (0) cpu_start: App cpu up.
I (208) cpu_start: Pro cpu start user code
I (208) cpu_start: cpu freq: 160000000
I (208) cpu_start: Application information:
I (212) cpu_start: Project name:     unit_test
I (218) cpu_start: App version:      1
I (222) cpu_start: Compile time:     Feb 28 2021 03:51:29
I (228) cpu_start: ELF file SHA256:  39e44e816ec30d58...
I (234) cpu_start: ESP-IDF:          v4.4-dev-4-g73db14240
I (241) heap_init: Initializing. RAM available for dynamic allocation:
I (248) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (254) heap_init: At 3FFB3088 len 0002CF78 (179 KiB): DRAM
I (260) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (266) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (273) heap_init: At 4008AB38 len 000154C8 (85 KiB): IRAM
I (280) spi_flash: detected chip: gd
I (283) spi_flash: flash io: dio
W (287) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (301) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
In main application. Collecting 32 random numbers from 1 to 100:
  76   26   40    9   74   28   37   19   78   66
  99   75   29   63   48   22    2    1   65   37
  54   63   25   24   20   75    4   31   32   75
  30   90
Mean: 44

pi@RPi3B:~/esp/unit_test $

« Last Edit: February 28, 2021, 11:26:50 PM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #7 on: March 01, 2021, 02:30:41 AM »
The following a the ESP32-Pico application build process.

Code: Text
  1. pi@RPi3B:~/esp $ . $HOME/esp/esp-idf/export.sh
  2. Setting IDF_PATH to '/home/pi/esp/esp-idf'
  3. Adding ESP-IDF tools to PATH...
  4. Using Python interpreter in /home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python
  5. Checking if Python packages are up to date...
  6. Python requirements from /home/pi/esp/esp-idf/requirements.txt are satisfied.
  7. Added the following directories to PATH:
  8.   /home/pi/esp/esp-idf/components/esptool_py/esptool
  9.   /home/pi/esp/esp-idf/components/espcoredump
  10.   /home/pi/esp/esp-idf/components/partition_table
  11.   /home/pi/esp/esp-idf/components/app_update
  12.   /home/pi/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin
  13.   /home/pi/.espressif/tools/xtensa-esp32s2-elf/esp-2020r3-8.4.0/xtensa-esp32s2-elf/bin
  14.   /home/pi/.espressif/tools/xtensa-esp32s3-elf/esp-2020r3-8.4.0/xtensa-esp32s3-elf/bin
  15.   /home/pi/.espressif/tools/riscv32-esp-elf/1.24.0.123_64eb9ff-8.4.0/riscv32-esp-elf/bin
  16.   /home/pi/.espressif/tools/esp32ulp-elf/2.28.51-esp-20191205/esp32ulp-elf-binutils/bin
  17.   /home/pi/.espressif/tools/esp32s2ulp-elf/2.28.51-esp-20191205/esp32s2ulp-elf-binutils/bin
  18.   /home/pi/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/bin
  19.   /home/pi/.espressif/python_env/idf4.4_py3.5_env/bin
  20.   /home/pi/esp/esp-idf/tools
  21. Done! You can now compile ESP-IDF projects.
  22. Go to the project directory and run:
  23.  
  24.   idf.py build
  25.  
  26. pi@RPi3B:~/esp $ cd unit_test
  27. pi@RPi3B:~/esp/unit_test $ idf.py build
  28. WARNING: Python 3 versions older than 3.6 are not supported.
  29. Executing action: all (aliases: build)
  30. Running make in directory /home/pi/esp/unit_test/build
  31. Executing "make -j 6 all"...
  32. [  0%] Built target custom_bundle
  33. [  0%] Built target _project_elf_src
  34. [  0%] Built target partition_table_bin
  35. [  0%] Built target esp32_linker_script
  36. [  0%] Performing build step for 'bootloader'
  37. [  0%] Built target __idf_ulp
  38. [  0%] Built target __idf_esp_serial_slave_link
  39. [  1%] Built target _project_elf_src
  40. [  5%] Built target __idf_log
  41. [  1%] Built target __idf_sdmmc
  42. [ 10%] Built target __idf_esp_rom
  43. [  1%] Built target __idf_esp_https_ota
  44. [ 22%] Built target __idf_esp_hw_support
  45. [ 31%] Built target __idf_efuse
  46. [  2%] Built target __idf_esp_http_server
  47. [  2%] Built target __idf_esp_http_client
  48. [ 58%] Built target __idf_bootloader_support
  49. [  2%] Built target __idf_tcp_transport
  50. [ 61%] Built target __idf_spi_flash
  51. [ 63%] Built target __idf_micro-ecc
  52. [  3%] Built target __idf_esp-tls
  53. [ 89%] Built target __idf_soc
  54. [ 92%] Built target __idf_hal
  55. [  5%] Built target __idf_nghttp
  56. [ 95%] Built target __idf_main
  57. [  5%] Built target __idf_app_trace
  58. [ 98%] Built target bootloader.elf
  59. [  5%] Built target __idf_cxx
  60. [100%] Built target gen_project_binary
  61. [100%] Built target app
  62. [  6%] Built target __idf_newlib
  63. [  7%] No install step for 'bootloader'
  64. [  7%] Completed 'bootloader'
  65. [  9%] Built target __idf_freertos
  66. [  9%] Built target bootloader
  67. [  9%] Built target __idf_esp_timer
  68. [ 10%] Built target __idf_esp_common
  69. [ 11%] Built target __idf_esp32
  70. [ 11%] Built target __idf_perfmon
  71. [ 11%] Built target __idf_espcoredump
  72. [ 12%] Built target __idf_xtensa
  73. [ 16%] Built target __idf_driver
  74. [ 17%] Built target __idf_esp_ringbuf
  75. [ 18%] Built target __idf_esp_hw_support
  76. [ 20%] Built target __idf_soc
  77. [ 21%] Built target __idf_heap
  78. [ 21%] Built target __idf_log
  79. [ 30%] Built target __idf_lwip
  80. [ 31%] Built target __idf_esp_wifi
  81. [ 40%] Built target __idf_wpa_supplicant
  82. [ 41%] Built target __idf_esp_event
  83. [ 42%] Built target __idf_esp_netif
  84. [ 42%] Built target __idf_tcpip_adapter
  85. [ 43%] Built target __idf_esp_eth
  86. [ 44%] Built target __idf_vfs
  87. [ 48%] Built target __idf_hal
  88. [ 48%] Built target __idf_esp_rom
  89. [ 50%] Built target __idf_esp_system
  90. [ 50%] Built target __idf_esp_gdbstub
  91. [ 51%] Built target __idf_pthread
  92. [ 53%] Built target __idf_nvs_flash
  93. [ 55%] Built target __idf_spi_flash
  94. [ 56%] Built target __idf_esp_ipc
  95. [ 56%] Built target __idf_app_update
  96. [ 57%] Built target __idf_bootloader_support
  97. [ 57%] Built target __idf_efuse
  98. [ 58%] Built target mbedx509
  99. [ 59%] Built target mbedtls
  100. [ 67%] Built target mbedcrypto
  101. [ 68%] Built target __idf_mbedtls
  102. [ 68%] Built target __idf_esp_pm
  103. Scanning dependencies of target __idf_testable
  104. [ 68%] Building C object esp-idf/testable/CMakeFiles/__idf_testable.dir/mean.c.obj
  105. [ 68%] Built target __idf_console
  106. [ 68%] Built target __idf_unity
  107. [ 69%] Built target __idf_asio
  108. [ 70%] Built target __idf_cbor
  109. [ 70%] Built target __idf_esp_adc_cal
  110. [ 71%] Built target __idf_esp_hid
  111. [ 71%] Built target __idf_protobuf-c
  112. [ 71%] Built target __idf_mdns
  113. [ 72%] Built target __idf_esp_websocket_client
  114. [ 75%] Built target __idf_coap
  115. [ 76%] Built target __idf_expat
  116. [ 76%] Built target __idf_wear_levelling
  117. [ 76%] Built target __idf_jsmn
  118. [ 76%] Built target __idf_json
  119. [ 77%] Built target __idf_mqtt
  120. [ 78%] Built target __idf_spiffs
  121. [ 79%] Linking C static library libtestable.a
  122. [ 80%] Built target __idf_openssl
  123. [ 80%] Built target __idf_cmock
  124. [ 84%] Built target __idf_freemodbus
  125. [ 85%] Built target __idf_protocomm
  126. [ 97%] Built target __idf_libsodium
  127. [ 97%] Built target __idf_testable
  128. [ 98%] Built target __idf_fatfs
  129. [ 98%] Built target __idf_esp_local_ctrl
  130. [ 99%] Built target __idf_wifi_provisioning
  131. [ 99%] Built target __idf_main
  132. [ 99%] Generating ld/esp32.project.ld
  133. [ 99%] Built target __ldgen_output_esp32.project.ld
  134. [100%] Linking CXX executable unit_test.elf
  135. [100%] Built target unit_test.elf
  136. [100%] Generating binary image from built executable
  137. esptool.py v3.1-dev
  138. Merged 1 ELF section
  139. Generated /home/pi/esp/unit_test/build/unit_test.bin
  140. [100%] Built target gen_project_binary
  141. [100%] Built target app
  142.  
  143. Project build complete. To flash, run this command:
  144. /home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python ../esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/unit_test.bin
  145. or run 'idf.py -p (PORT) flash'
  146. pi@RPi3B:~/esp/unit_test $ idf.py -p /dev/ttyUSB0 flash
  147. WARNING: Python 3 versions older than 3.6 are not supported.
  148. Executing action: flash
  149. Running make in directory /home/pi/esp/unit_test/build
  150. Executing "make -j 6 flash"...
  151. [  0%] Built target custom_bundle
  152. [  0%] Built target esp32_linker_script
  153. [  0%] Built target partition_table_bin
  154. [  0%] Built target _project_elf_src
  155. [  0%] Performing build step for 'bootloader'
  156. [  0%] Built target __idf_ulp
  157. [  0%] Built target __idf_esp_serial_slave_link
  158. [  1%] Built target _project_elf_src
  159. [  5%] Built target __idf_log
  160. [  1%] Built target __idf_sdmmc
  161. [ 10%] Built target __idf_esp_rom
  162. [  1%] Built target __idf_esp_https_ota
  163. [ 22%] Built target __idf_esp_hw_support
  164. [  2%] Built target __idf_esp_http_server
  165. [ 31%] Built target __idf_efuse
  166. [  2%] Built target __idf_esp_http_client
  167. [ 58%] Built target __idf_bootloader_support
  168. [  2%] Built target __idf_tcp_transport
  169. [ 61%] Built target __idf_spi_flash
  170. [ 63%] Built target __idf_micro-ecc
  171. [  3%] Built target __idf_esp-tls
  172. [ 89%] Built target __idf_soc
  173. [  5%] Built target __idf_nghttp
  174. [ 92%] Built target __idf_hal
  175. [  5%] Built target __idf_app_trace
  176. [ 95%] Built target __idf_main
  177. [ 98%] Built target bootloader.elf
  178. [  5%] Built target __idf_cxx
  179. [100%] Built target gen_project_binary
  180. [  6%] Built target __idf_newlib
  181. [100%] Built target app
  182. [  7%] No install step for 'bootloader'
  183. [  9%] Built target __idf_freertos
  184. [  9%] Completed 'bootloader'
  185. [  9%] Built target __idf_esp_timer
  186. [  9%] Built target bootloader
  187. [ 10%] Built target __idf_esp_common
  188. [ 11%] Built target __idf_esp32
  189. [ 11%] Built target __idf_perfmon
  190. [ 11%] Built target __idf_espcoredump
  191. [ 12%] Built target __idf_xtensa
  192. [ 16%] Built target __idf_driver
  193. [ 17%] Built target __idf_esp_ringbuf
  194. [ 18%] Built target __idf_esp_hw_support
  195. [ 20%] Built target __idf_soc
  196. [ 21%] Built target __idf_heap
  197. [ 21%] Built target __idf_log
  198. [ 30%] Built target __idf_lwip
  199. [ 31%] Built target __idf_esp_wifi
  200. [ 40%] Built target __idf_wpa_supplicant
  201. [ 41%] Built target __idf_esp_event
  202. [ 42%] Built target __idf_esp_netif
  203. [ 42%] Built target __idf_tcpip_adapter
  204. [ 43%] Built target __idf_esp_eth
  205. [ 44%] Built target __idf_vfs
  206. [ 48%] Built target __idf_hal
  207. [ 48%] Built target __idf_esp_rom
  208. [ 50%] Built target __idf_esp_system
  209. [ 50%] Built target __idf_esp_gdbstub
  210. [ 51%] Built target __idf_pthread
  211. [ 53%] Built target __idf_nvs_flash
  212. [ 55%] Built target __idf_spi_flash
  213. [ 56%] Built target __idf_esp_ipc
  214. [ 56%] Built target __idf_app_update
  215. [ 57%] Built target __idf_bootloader_support
  216. [ 57%] Built target __idf_efuse
  217. [ 58%] Built target mbedx509
  218. [ 59%] Built target mbedtls
  219. [ 67%] Built target mbedcrypto
  220. [ 68%] Built target __idf_mbedtls
  221. [ 68%] Built target __idf_esp_pm
  222. [ 69%] Built target __idf_testable
  223. [ 69%] Built target __idf_unity
  224. [ 69%] Built target __idf_console
  225. [ 70%] Built target __idf_cbor
  226. [ 70%] Built target __idf_esp_adc_cal
  227. [ 71%] Built target __idf_asio
  228. [ 71%] Built target __idf_protobuf-c
  229. [ 72%] Built target __idf_esp_hid
  230. [ 75%] Built target __idf_coap
  231. [ 76%] Built target __idf_expat
  232. [ 76%] Built target __idf_mdns
  233. [ 77%] Built target __idf_esp_websocket_client
  234. [ 77%] Built target __idf_wear_levelling
  235. [ 77%] Built target __idf_jsmn
  236. [ 77%] Built target __idf_json
  237. [ 78%] Built target __idf_openssl
  238. [ 79%] Built target __idf_mqtt
  239. [ 79%] Built target __idf_cmock
  240. [ 80%] Built target __idf_spiffs
  241. [ 91%] Built target __idf_freemodbus
  242. [ 96%] Built target __idf_libsodium
  243. [ 97%] Built target __idf_protocomm
  244. [ 98%] Built target __idf_fatfs
  245. [ 98%] Built target __idf_esp_local_ctrl
  246. [ 99%] Built target __idf_wifi_provisioning
  247. [ 99%] Built target __idf_main
  248. [ 99%] Built target __ldgen_output_esp32.project.ld
  249. [100%] Built target unit_test.elf
  250. [100%] Built target gen_project_binary
  251. [100%] Built target app
  252. esptool.py esp32 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x10000 unit_test.bin
  253. esptool.py v3.1-dev
  254. Serial port /dev/ttyUSB0
  255. Connecting....
  256. Chip is ESP32-PICO-D4 (revision 1)
  257. Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
  258. Crystal is 40MHz
  259. MAC: d8:a0:1d:5f:c1:54
  260. Uploading stub...
  261. Running stub...
  262. Stub running...
  263. Changing baud rate to 460800
  264. Changed.
  265. Configuring flash size...
  266. Compressed 3072 bytes to 103...
  267. Writing at 0x00008000... (100 %)
  268. Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 446.5 kbit/s)...
  269. Hash of data verified.
  270. Compressed 25008 bytes to 15398...
  271. Writing at 0x00001000... (100 %)
  272. Wrote 25008 bytes (15398 compressed) at 0x00001000 in 0.8 seconds (effective 264.9 kbit/s)...
  273. Hash of data verified.
  274. Compressed 156480 bytes to 82233...
  275. Writing at 0x00010000... (16 %)
  276. Writing at 0x0001a249... (33 %)
  277. Writing at 0x0001fbce... (50 %)
  278. Writing at 0x00025464... (66 %)
  279. Writing at 0x0002e9bc... (83 %)
  280. Writing at 0x000361ae... (100 %)
  281. Wrote 156480 bytes (82233 compressed) at 0x00010000 in 2.4 seconds (effective 529.1 kbit/s)...
  282. Hash of data verified.
  283.  
  284. Leaving...
  285. Hard resetting via RTS pin...
  286. [100%] Built target flash
  287. Done
  288. pi@RPi3B:~/esp/unit_test $ idf.py -p /dev/ttyUSB0 monitor
  289. WARNING: Python 3 versions older than 3.6 are not supported.
  290. Executing action: monitor
  291. Running idf_monitor in directory /home/pi/esp/unit_test
  292. Executing "/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python /home/pi/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix xtensa-esp32-elf- /home/pi/esp/unit_test/build/unit_test.elf -m '/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python' '/home/pi/esp/esp-idf/tools/idf.py' '-p' '/dev/ttyUSB0'"...
  293. --- idf_monitor on /dev/ttyUSB0 115200 ---
  294. --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
  295. ets Jun  8 2016 00:22:57
  296.  
  297. rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
  298. configsip: 188777542, SPIWP:0xee
  299. clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  300. mode:DIO, clock div:2
  301. load:0x3fff0030,len:6916
  302. load:0x40078000,len:14336
  303. ho 0 tail 12 room 4
  304. load:0x40080400,len:3672
  305. 0x40080400: _init at ??:?
  306.  
  307. entry 0x40080678
  308. I (30) boot: ESP-IDF v4.4-dev-4-g73db14240 2nd stage bootloader
  309. I (30) boot: compile time 03:48:52
  310. I (30) boot: chip revision: 1
  311. I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0
  312. I (41) boot.esp32: SPI Speed      : 40MHz
  313. I (46) boot.esp32: SPI Mode       : DIO
  314. I (50) boot.esp32: SPI Flash Size : 2MB
  315. I (55) boot: Enabling RNG early entropy source...
  316. I (60) boot: Partition Table:
  317. I (64) boot: ## Label            Usage          Type ST Offset   Length
  318. I (71) boot:  0 nvs              WiFi data        01 02 00009000 00006000
  319. I (78) boot:  1 phy_init         RF data          01 01 0000f000 00001000
  320. I (86) boot:  2 factory          factory app      00 00 00010000 00100000
  321. I (93) boot: End of partition table
  322. I (97) boot_comm: chip revision: 1, min. application chip revision: 0
  323. I (105) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=05bbch ( 23484) map
  324. I (121) esp_image: segment 1: paddr=00015be4 vaddr=3ffb0000 size=02860h ( 10336) load
  325. I (126) esp_image: segment 2: paddr=0001844c vaddr=40080000 size=07bcch ( 31692) load
  326. I (143) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=1337ch ( 78716) map
  327. I (171) esp_image: segment 4: paddr=000333a4 vaddr=40087bcc size=02f6ch ( 12140) load
  328. I (182) boot: Loaded app from partition at offset 0x10000
  329. I (182) boot: Disabling RNG early entropy source...
  330. I (194) cpu_start: Pro cpu up.
  331. I (194) cpu_start: Starting app cpu, entry point is 0x40080f34
  332. 0x40080f34: call_start_cpu1 at /home/pi/esp/esp-idf/components/esp_system/port/cpu_start.c:143
  333.  
  334. I (0) cpu_start: App cpu up.
  335. I (208) cpu_start: Pro cpu start user code
  336. I (208) cpu_start: cpu freq: 160000000
  337. I (208) cpu_start: Application information:
  338. I (212) cpu_start: Project name:     unit_test
  339. I (218) cpu_start: App version:      1
  340. I (222) cpu_start: Compile time:     Feb 28 2021 03:51:29
  341. I (228) cpu_start: ELF file SHA256:  3807515689fe0775...
  342. I (234) cpu_start: ESP-IDF:          v4.4-dev-4-g73db14240
  343. I (241) heap_init: Initializing. RAM available for dynamic allocation:
  344. I (248) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
  345. I (254) heap_init: At 3FFB3088 len 0002CF78 (179 KiB): DRAM
  346. I (260) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
  347. I (266) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
  348. I (273) heap_init: At 4008AB38 len 000154C8 (85 KiB): IRAM
  349. I (280) spi_flash: detected chip: gd
  350. I (283) spi_flash: flash io: dio
  351. W (287) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
  352. I (301) cpu_start: Starting scheduler on PRO CPU.
  353. I (0) cpu_start: Starting scheduler on APP CPU.
  354. In main application. Collecting 32 random numbers from 1 to 100:
  355.   26    6   30   38    4   34   39    9   57   99
  356.   49   75   73   80   96   94   16   46   94   73
  357.   30   42   86   90   30   41   99   95   23   45
  358.   75   51
  359. Mean: 54
  360.  
  361. pi@RPi3B:~/esp/unit_test $
  362.  
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #8 on: March 01, 2021, 05:31:41 PM »
This example uses the timer group driver to generate timer interrupts at two specified alarm intervals.

Functionality Overview
  • Two timers are configured
  • Each timer is set with some sample alarm interval
  • On reaching the interval value each timer will generate an alarm
  • One of the timers is configured to automatically reload it's counter value on the alarm
  • The other timer is configured to keep incrementing and is reloaded by the application each time the alarm happens
  • Alarms trigger subsequent interrupts, that is tracked with messages printed on the terminal:

Code: C
  1. /* Timer group-hardware timer example
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9. #include <stdio.h>
  10. #include "esp_types.h"
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "freertos/queue.h"
  14. #include "driver/periph_ctrl.h"
  15. #include "driver/timer.h"
  16.  
  17. #define TIMER_DIVIDER         16  //  Hardware timer clock divider
  18. #define TIMER_SCALE           (TIMER_BASE_CLK / TIMER_DIVIDER)  // convert counter value to seconds
  19. #define TIMER_INTERVAL0_SEC   (3.4179) // sample test interval for the first timer
  20. #define TIMER_INTERVAL1_SEC   (5.78)   // sample test interval for the second timer
  21. #define TEST_WITHOUT_RELOAD   0        // testing will be done without auto reload
  22. #define TEST_WITH_RELOAD      1        // testing will be done with auto reload
  23.  
  24. /*
  25.  * A sample structure to pass events
  26.  * from the timer interrupt handler to the main program.
  27.  */
  28. typedef struct {
  29.     int type;  // the type of timer's event
  30.     int timer_group;
  31.     int timer_idx;
  32.     uint64_t timer_counter_value;
  33. } timer_event_t;
  34.  
  35. xQueueHandle timer_queue;
  36.  
  37. /*
  38.  * A simple helper function to print the raw timer counter value
  39.  * and the counter value converted to seconds
  40.  */
  41. static void inline print_timer_counter(uint64_t counter_value)
  42. {
  43.     printf("Counter: 0x%08x%08x\n", (uint32_t) (counter_value >> 32),
  44.            (uint32_t) (counter_value));
  45.     printf("Time   : %.8f s\n", (double) counter_value / TIMER_SCALE);
  46. }
  47.  
  48. /*
  49.  * Timer group0 ISR handler
  50.  *
  51.  * Note:
  52.  * We don't call the timer API here because they are not declared with IRAM_ATTR.
  53.  * If we're okay with the timer irq not being serviced while SPI flash cache is disabled,
  54.  * we can allocate this interrupt without the ESP_INTR_FLAG_IRAM flag and use the normal API.
  55.  */
  56. void IRAM_ATTR timer_group0_isr(void *para)
  57. {
  58.     timer_spinlock_take(TIMER_GROUP_0);
  59.     int timer_idx = (int) para;
  60.  
  61.     /* Retrieve the interrupt status and the counter value
  62.        from the timer that reported the interrupt */
  63.     uint32_t timer_intr = timer_group_get_intr_status_in_isr(TIMER_GROUP_0);
  64.     uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(TIMER_GROUP_0, timer_idx);
  65.  
  66.     /* Prepare basic event data
  67.        that will be then sent back to the main program task */
  68.     timer_event_t evt;
  69.     evt.timer_group = 0;
  70.     evt.timer_idx = timer_idx;
  71.     evt.timer_counter_value = timer_counter_value;
  72.  
  73.     /* Clear the interrupt
  74.        and update the alarm time for the timer with without reload */
  75.     if (timer_intr & TIMER_INTR_T0) {
  76.         evt.type = TEST_WITHOUT_RELOAD;
  77.         timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
  78.         timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE);
  79.         timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, timer_idx, timer_counter_value);
  80.     } else if (timer_intr & TIMER_INTR_T1) {
  81.         evt.type = TEST_WITH_RELOAD;
  82.         timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_1);
  83.     } else {
  84.         evt.type = -1; // not supported even type
  85.     }
  86.  
  87.     /* After the alarm has been triggered
  88.       we need enable it again, so it is triggered the next time */
  89.     timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx);
  90.  
  91.     /* Now just send the event data back to the main program task */
  92.     xQueueSendFromISR(timer_queue, &evt, NULL);
  93.     timer_spinlock_give(TIMER_GROUP_0);
  94. }
  95.  
  96. /*
  97.  * Initialize selected timer of the timer group 0
  98.  *
  99.  * timer_idx - the timer number to initialize
  100.  * auto_reload - should the timer auto reload on alarm?
  101.  * timer_interval_sec - the interval of alarm to set
  102.  */
  103. static void example_tg0_timer_init(int timer_idx,
  104.                                    bool auto_reload, double timer_interval_sec)
  105. {
  106.     /* Select and initialize basic parameters of the timer */
  107.     timer_config_t config = {
  108.         .divider = TIMER_DIVIDER,
  109.         .counter_dir = TIMER_COUNT_UP,
  110.         .counter_en = TIMER_PAUSE,
  111.         .alarm_en = TIMER_ALARM_EN,
  112.         .auto_reload = auto_reload,
  113.     }; // default clock source is APB
  114.     timer_init(TIMER_GROUP_0, timer_idx, &config);
  115.  
  116.     /* Timer's counter will initially start from value below.
  117.        Also, if auto_reload is set, this value will be automatically reload on alarm */
  118.     timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0x00000000ULL);
  119.  
  120.     /* Configure the alarm value and the interrupt on alarm. */
  121.     timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE);
  122.     timer_enable_intr(TIMER_GROUP_0, timer_idx);
  123.     timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
  124.                        (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
  125.  
  126.     timer_start(TIMER_GROUP_0, timer_idx);
  127. }
  128.  
  129. /*
  130.  * The main task of this example program
  131.  */
  132. static void timer_example_evt_task(void *arg)
  133. {
  134.     while (1) {
  135.         timer_event_t evt;
  136.         xQueueReceive(timer_queue, &evt, portMAX_DELAY);
  137.  
  138.         /* Print information that the timer reported an event */
  139.         if (evt.type == TEST_WITHOUT_RELOAD) {
  140.             printf("\n    Example timer without reload\n");
  141.         } else if (evt.type == TEST_WITH_RELOAD) {
  142.             printf("\n    Example timer with auto reload\n");
  143.         } else {
  144.             printf("\n    UNKNOWN EVENT TYPE\n");
  145.         }
  146.         printf("Group[%d], timer[%d] alarm event\n", evt.timer_group, evt.timer_idx);
  147.  
  148.         /* Print the timer values passed by event */
  149.         printf("------- EVENT TIME --------\n");
  150.         print_timer_counter(evt.timer_counter_value);
  151.  
  152.         /* Print the timer values as visible by this task */
  153.         printf("-------- TASK TIME --------\n");
  154.         uint64_t task_counter_value;
  155.         timer_get_counter_value(evt.timer_group, evt.timer_idx, &task_counter_value);
  156.         print_timer_counter(task_counter_value);
  157.     }
  158. }
  159.  
  160. /*
  161.  * In this example, we will test hardware timer0 and timer1 of timer group0.
  162.  */
  163. void app_main(void)
  164. {
  165.     timer_queue = xQueueCreate(10, sizeof(timer_event_t));
  166.     example_tg0_timer_init(TIMER_0, TEST_WITHOUT_RELOAD, TIMER_INTERVAL0_SEC);
  167.     example_tg0_timer_init(TIMER_1, TEST_WITH_RELOAD,    TIMER_INTERVAL1_SEC);
  168.     xTaskCreate(timer_example_evt_task, "timer_evt_task", 2048, NULL, 5, NULL);
  169. }
  170.  


    Example timer without reload
Group[0], timer[0] alarm event
------- EVENT TIME --------
Counter: 0x000000000104c415
Time   : 3.41791140 s
-------- TASK TIME --------
Counter: 0x000000000105371b
Time   : 3.42380060 s

    Example timer with auto reload
Group[0], timer[1] alarm event
------- EVENT TIME --------
Counter: 0x0000000000000011
Time   : 0.00000340 s
-------- TASK TIME --------
Counter: 0x000000000000ab12
Time   : 0.00875880 s

    Example timer without reload
Group[0], timer[0] alarm event
------- EVENT TIME --------
Counter: 0x0000000002098802
Time   : 6.83581480 s
-------- TASK TIME --------
Counter: 0x00000000020a2039
Time   : 6.84360820 s

    Example timer without reload
Group[0], timer[0] alarm event
------- EVENT TIME --------
Counter: 0x00000000030e4bef
Time   : 10.25371820 s
-------- TASK TIME --------
Counter: 0x00000000030eacc4
Time   : 10.25867600 s

    Example timer with auto reload
Group[0], timer[1] alarm event
------- EVENT TIME --------
Counter: 0x0000000000000011
Time   : 0.00000340 s
-------- TASK TIME --------
Counter: 0x000000000000a94d
Time   : 0.00866820 s

    Example timer without reload
Group[0], timer[0] alarm event
------- EVENT TIME --------
Counter: 0x0000000004130fdc
Time   : 13.67162160 s
-------- TASK TIME --------
Counter: 0x000000000413997d
Time   : 13.67866820 s

ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #9 on: March 02, 2021, 02:20:56 AM »
Simple HTTPD Server Example

This example consists of HTTPD server demo using URI handling :
1. URI \hello for GET command returns "Hello World!" message
2. URI \echo for POST command echoes back the POSTed message

The ESP32-Pico HTTPD server is connected via WIFI to my router.

Code: C
  1. /* Simple HTTP Server Example
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9.  
  10. #include <esp_wifi.h>
  11. #include <esp_event.h>
  12. #include <esp_log.h>
  13. #include <esp_system.h>
  14. #include <nvs_flash.h>
  15. #include <sys/param.h>
  16. #include "nvs_flash.h"
  17. #include "esp_netif.h"
  18. #include "esp_eth.h"
  19. #include "protocol_examples_common.h"
  20.  
  21. #include <esp_http_server.h>
  22.  
  23. /* A simple example that demonstrates how to create GET and POST
  24.  * handlers for the web server.
  25.  */
  26.  
  27. static const char *TAG = "example";
  28.  
  29. /* An HTTP GET handler */
  30. static esp_err_t hello_get_handler(httpd_req_t *req)
  31. {
  32.     char*  buf;
  33.     size_t buf_len;
  34.  
  35.     /* Get header value string length and allocate memory for length + 1,
  36.      * extra byte for null termination */
  37.     buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
  38.     if (buf_len > 1) {
  39.         buf = malloc(buf_len);
  40.         /* Copy null terminated value string into buffer */
  41.         if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
  42.             ESP_LOGI(TAG, "Found header => Host: %s", buf);
  43.         }
  44.         free(buf);
  45.     }
  46.  
  47.     buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
  48.     if (buf_len > 1) {
  49.         buf = malloc(buf_len);
  50.         if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
  51.             ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
  52.         }
  53.         free(buf);
  54.     }
  55.  
  56.     buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
  57.     if (buf_len > 1) {
  58.         buf = malloc(buf_len);
  59.         if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
  60.             ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
  61.         }
  62.         free(buf);
  63.     }
  64.  
  65.     /* Read URL query string length and allocate memory for length + 1,
  66.      * extra byte for null termination */
  67.     buf_len = httpd_req_get_url_query_len(req) + 1;
  68.     if (buf_len > 1) {
  69.         buf = malloc(buf_len);
  70.         if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
  71.             ESP_LOGI(TAG, "Found URL query => %s", buf);
  72.             char param[32];
  73.             /* Get value of expected key from query string */
  74.             if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
  75.                 ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
  76.             }
  77.             if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
  78.                 ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
  79.             }
  80.             if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
  81.                 ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
  82.             }
  83.         }
  84.         free(buf);
  85.     }
  86.  
  87.     /* Set some custom headers */
  88.     httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
  89.     httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
  90.  
  91.     /* Send response with custom headers and body set as the
  92.      * string passed in user context*/
  93.     const char* resp_str = (const char*) req->user_ctx;
  94.     httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
  95.  
  96.     /* After sending the HTTP response the old HTTP request
  97.      * headers are lost. Check if HTTP request headers can be read now. */
  98.     if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
  99.         ESP_LOGI(TAG, "Request headers lost");
  100.     }
  101.     return ESP_OK;
  102. }
  103.  
  104. static const httpd_uri_t hello = {
  105.     .uri       = "/hello",
  106.     .method    = HTTP_GET,
  107.     .handler   = hello_get_handler,
  108.     /* Let's pass response string in user
  109.      * context to demonstrate it's usage */
  110.     .user_ctx  = "Hello World!"
  111. };
  112.  
  113. /* An HTTP POST handler */
  114. static esp_err_t echo_post_handler(httpd_req_t *req)
  115. {
  116.     char buf[100];
  117.     int ret, remaining = req->content_len;
  118.  
  119.     while (remaining > 0) {
  120.         /* Read the data for the request */
  121.         if ((ret = httpd_req_recv(req, buf,
  122.                         MIN(remaining, sizeof(buf)))) <= 0) {
  123.             if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
  124.                 /* Retry receiving if timeout occurred */
  125.                 continue;
  126.             }
  127.             return ESP_FAIL;
  128.         }
  129.  
  130.         /* Send back the same data */
  131.         httpd_resp_send_chunk(req, buf, ret);
  132.         remaining -= ret;
  133.  
  134.         /* Log data received */
  135.         ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
  136.         ESP_LOGI(TAG, "%.*s", ret, buf);
  137.         ESP_LOGI(TAG, "====================================");
  138.     }
  139.  
  140.     // End response
  141.     httpd_resp_send_chunk(req, NULL, 0);
  142.     return ESP_OK;
  143. }
  144.  
  145. static const httpd_uri_t echo = {
  146.     .uri       = "/echo",
  147.     .method    = HTTP_POST,
  148.     .handler   = echo_post_handler,
  149.     .user_ctx  = NULL
  150. };
  151.  
  152. /* This handler allows the custom error handling functionality to be
  153.  * tested from client side. For that, when a PUT request 0 is sent to
  154.  * URI /ctrl, the /hello and /echo URIs are unregistered and following
  155.  * custom error handler http_404_error_handler() is registered.
  156.  * Afterwards, when /hello or /echo is requested, this custom error
  157.  * handler is invoked which, after sending an error message to client,
  158.  * either closes the underlying socket (when requested URI is /echo)
  159.  * or keeps it open (when requested URI is /hello). This allows the
  160.  * client to infer if the custom error handler is functioning as expected
  161.  * by observing the socket state.
  162.  */
  163. esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
  164. {
  165.     if (strcmp("/hello", req->uri) == 0) {
  166.         httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
  167.         /* Return ESP_OK to keep underlying socket open */
  168.         return ESP_OK;
  169.     } else if (strcmp("/echo", req->uri) == 0) {
  170.         httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
  171.         /* Return ESP_FAIL to close underlying socket */
  172.         return ESP_FAIL;
  173.     }
  174.     /* For any other URI send 404 and close socket */
  175.     httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
  176.     return ESP_FAIL;
  177. }
  178.  
  179. /* An HTTP PUT handler. This demonstrates realtime
  180.  * registration and deregistration of URI handlers
  181.  */
  182. static esp_err_t ctrl_put_handler(httpd_req_t *req)
  183. {
  184.     char buf;
  185.     int ret;
  186.  
  187.     if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) {
  188.         if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
  189.             httpd_resp_send_408(req);
  190.         }
  191.         return ESP_FAIL;
  192.     }
  193.  
  194.     if (buf == '0') {
  195.         /* URI handlers can be unregistered using the uri string */
  196.         ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
  197.         httpd_unregister_uri(req->handle, "/hello");
  198.         httpd_unregister_uri(req->handle, "/echo");
  199.         /* Register the custom error handler */
  200.         httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);
  201.     }
  202.     else {
  203.         ESP_LOGI(TAG, "Registering /hello and /echo URIs");
  204.         httpd_register_uri_handler(req->handle, &hello);
  205.         httpd_register_uri_handler(req->handle, &echo);
  206.         /* Unregister custom error handler */
  207.         httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);
  208.     }
  209.  
  210.     /* Respond with empty body */
  211.     httpd_resp_send(req, NULL, 0);
  212.     return ESP_OK;
  213. }
  214.  
  215. static const httpd_uri_t ctrl = {
  216.     .uri       = "/ctrl",
  217.     .method    = HTTP_PUT,
  218.     .handler   = ctrl_put_handler,
  219.     .user_ctx  = NULL
  220. };
  221.  
  222. static httpd_handle_t start_webserver(void)
  223. {
  224.     httpd_handle_t server = NULL;
  225.     httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  226.     config.lru_purge_enable = true;
  227.  
  228.     // Start the httpd server
  229.     ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
  230.     if (httpd_start(&server, &config) == ESP_OK) {
  231.         // Set URI handlers
  232.         ESP_LOGI(TAG, "Registering URI handlers");
  233.         httpd_register_uri_handler(server, &hello);
  234.         httpd_register_uri_handler(server, &echo);
  235.         httpd_register_uri_handler(server, &ctrl);
  236.         return server;
  237.     }
  238.  
  239.     ESP_LOGI(TAG, "Error starting server!");
  240.     return NULL;
  241. }
  242.  
  243. static void stop_webserver(httpd_handle_t server)
  244. {
  245.     // Stop the httpd server
  246.     httpd_stop(server);
  247. }
  248.  
  249. static void disconnect_handler(void* arg, esp_event_base_t event_base,
  250.                                int32_t event_id, void* event_data)
  251. {
  252.     httpd_handle_t* server = (httpd_handle_t*) arg;
  253.     if (*server) {
  254.         ESP_LOGI(TAG, "Stopping webserver");
  255.         stop_webserver(*server);
  256.         *server = NULL;
  257.     }
  258. }
  259.  
  260. static void connect_handler(void* arg, esp_event_base_t event_base,
  261.                             int32_t event_id, void* event_data)
  262. {
  263.     httpd_handle_t* server = (httpd_handle_t*) arg;
  264.     if (*server == NULL) {
  265.         ESP_LOGI(TAG, "Starting webserver");
  266.         *server = start_webserver();
  267.     }
  268. }
  269.  
  270.  
  271. void app_main(void)
  272. {
  273.     static httpd_handle_t server = NULL;
  274.  
  275.     ESP_ERROR_CHECK(nvs_flash_init());
  276.     ESP_ERROR_CHECK(esp_netif_init());
  277.     ESP_ERROR_CHECK(esp_event_loop_create_default());
  278.  
  279.     /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
  280.      * Read "Establishing Wi-Fi or Ethernet Connection" section in
  281.      * examples/protocols/README.md for more information about this function.
  282.      */
  283.     ESP_ERROR_CHECK(example_connect());
  284.  
  285.     /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected,
  286.      * and re-start it upon connection.
  287.      */
  288. #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
  289.     ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
  290.     ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
  291. #endif // CONFIG_EXAMPLE_CONNECT_WIFI
  292. #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
  293.     ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
  294.     ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
  295. #endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
  296.  
  297.     /* Start the server for the first time */
  298.     server = start_webserver();
  299. }
  300.  

ESP32-Pico - Monitor - Webserver

pi@RPi3B:~/esp/simple $ idf.py -p /dev/ttyUSB0 monitor
WARNING: Python 3 versions older than 3.6 are not supported.
Executing action: monitor
Running idf_monitor in directory /home/pi/esp/simple
Executing "/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python /home/pi/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix xtensa-esp32-elf- /home/pi/esp/simple/build/simple.elf -m '/home/pi/.espressif/python_env/idf4.4_py3.5_env/bin/python' '/home/pi/esp/esp-idf/tools/idf.py' '-p' '/dev/ttyUSB0'"...
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6916
load:0x40078000,len:14336
ho 0 tail 12 room 4
load:0x40080400,len:3672
0x40080400: _init at ??:?

entry 0x40080678
I (29) boot: ESP-IDF v4.4-dev-4-g73db14240 2nd stage bootloader
I (30) boot: compile time 16:45:21
I (30) boot: chip revision: 1
I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (41) boot.esp32: SPI Speed      : 40MHz
I (45) boot.esp32: SPI Mode       : DIO
I (50) boot.esp32: SPI Flash Size : 2MB
I (54) boot: Enabling RNG early entropy source...
I (60) boot: Partition Table:
I (63) boot: ## Label            Usage          Type ST Offset   Length
I (71) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (78) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (86) boot:  2 factory          factory app      00 00 00010000 00100000
I (93) boot: End of partition table
I (97) boot_comm: chip revision: 1, min. application chip revision: 0
I (104) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=18fc0h (102336) map
I (149) esp_image: segment 1: paddr=00028fe8 vaddr=3ffb0000 size=0424ch ( 16972) load
I (156) esp_image: segment 2: paddr=0002d23c vaddr=40080000 size=02ddch ( 11740) load
I (161) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=7c564h (509284) map
I (343) esp_image: segment 4: paddr=000ac58c vaddr=40082ddc size=12c54h ( 76884) load
I (386) boot: Loaded app from partition at offset 0x10000
I (386) boot: Disabling RNG early entropy source...
I (397) cpu_start: Pro cpu up.
I (397) cpu_start: Starting app cpu, entry point is 0x4008123c
0x4008123c: call_start_cpu1 at /home/pi/esp/esp-idf/components/esp_system/port/cpu_start.c:143

I (0) cpu_start: App cpu up.
I (412) cpu_start: Pro cpu start user code
I (412) cpu_start: cpu freq: 160000000
I (412) cpu_start: Application information:
I (416) cpu_start: Project name:     simple
I (421) cpu_start: App version:      1
I (425) cpu_start: Compile time:     Mar  1 2021 17:46:19
I (432) cpu_start: ELF file SHA256:  3f399528bea977d5...
I (437) cpu_start: ESP-IDF:          v4.4-dev-4-g73db14240
I (444) heap_init: Initializing. RAM available for dynamic allocation:
I (451) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (457) heap_init: At 3FFB7F98 len 00028068 (160 KiB): DRAM
I (463) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (470) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (476) heap_init: At 40095A30 len 0000A5D0 (41 KiB): IRAM
I (483) spi_flash: detected chip: gd
I (486) spi_flash: flash io: dio
W (490) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (505) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (605) wifi:wifi driver task: 3ffc1688, prio:23, stack:6656, core=0
I (605) system_api: Base MAC address is not set
I (605) system_api: read default base MAC address from EFUSE
I (625) wifi:wifi firmware version: 6b2834e
I (625) wifi:wifi certification version: v7.0
I (625) wifi:config NVS flash: enabled
I (625) wifi:config nano formating: disabled
I (635) wifi:Init data frame dynamic rx buffer num: 32
I (635) wifi:Init management frame dynamic rx buffer num: 32
I (645) wifi:Init management short buffer num: 32
I (645) wifi:Init dynamic tx buffer num: 32
I (655) wifi:Init static rx buffer size: 1600
I (655) wifi:Init static rx buffer num: 10
I (655) wifi:Init dynamic rx buffer num: 32
I (665) wifi_init: rx ba win: 6
I (665) wifi_init: tcpip mbox: 32
I (675) wifi_init: udp mbox: 6
I (675) wifi_init: tcp mbox: 6
I (675) wifi_init: tcp tx win: 5744
I (685) wifi_init: tcp rx win: 5744
I (685) wifi_init: tcp mss: 1440
I (695) wifi_init: WiFi IRAM OP enabled
I (695) wifi_init: WiFi RX IRAM OP enabled
I (705) example_connect: Connecting to jrs...
I (705) phy_init: phy_version 4660,0162888,Dec 23 2020
I (805) wifi:mode : sta (d8:a0:1d:5f:c1:54)
I (805) wifi:enable tsf
I (815) example_connect: Waiting for IP(s)
I (1915) wifi:new:<10,0>, old:<1,0>, ap:<255,255>, sta:<10,0>, prof:1
I (2845) wifi:state: init -> auth (b0)
I (2855) wifi:state: auth -> assoc (0)
I (2855) wifi:state: assoc -> run (10)
I (2865) wifi:connected with jrs, aid = 7, channel 10, BW20, bssid = d8:07:b6:f8:b1:97
I (2865) wifi:security: WPA2-PSK, phy: bgn, rssi: -28
I (2865) wifi:pm start, type: 1

W (2885) wifi:<ba-add>idx:0 (ifx:0, d8:07:b6:f8:b1:97), tid:0, ssn:0, winSize:64
I (2935) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (3595) esp_netif_handlers: example_connect: sta ip: 192.168.0.246, mask: 255.255.255.0, gw: 192.168.0.1
I (3595) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.0.246
I (3605) example_connect: Connected to example_connect: sta
I (3605) example_connect: - IPv4 address: 192.168.0.246
I (3615) example: Starting server on port: '80'
I (3625) example: Registering URI handlers
I (10935) example: Found header => Host: 192.168.0.246
I (10945) example: Request headers lost
I (360815) example: =========== RECEIVED DATA ==========
I (360815) example: Set ESP Environment:

. $HOME/esp/esp-idf/export.sh


Copy Project for build:

cd ~/esp
cp -r /home/
I (360825) example: ====================================
I (360825) example: =========== RECEIVED DATA ==========
I (360835) example: pi/esp/examples/get-started/hello_world .


Configure Project:

cd ~/esp/hello_world
idf.py set-targ
I (360845) example: ====================================
I (360855) example: =========== RECEIVED DATA ==========
I (360855) example: et esp32
idf.py menuconfig


Build Project:

idf.py build


Flash Project:

idf.py -p /dev/ttyUSB0 f
I (360865) example: ====================================
I (360875) example: =========== RECEIVED DATA ==========
I (360885) example: lash


Run / Monitor Project:

idf.py -p /dev/ttyUSB0 monitor

I (360885) example: ====================================


Second console executing Curl Commands to the ESP32-Pico HTTPD server

pi@RPi3B:~ $ curl 192.168.0.246:80/hello
Hello World!
pi@RPi3B:

pi@RPi3B:~/esp $ curl -X POST --data-binary @esp_usage.txt 192.168.0.246:80/echo > tmpfile
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   724    0   362  100   362    230    230  0:00:01  0:00:01 --:--:--   230
pi@RPi3B:
pi@RPi3B:~/esp $ cat tmpfile
Set ESP Environment:

. $HOME/esp/esp-idf/export.sh


Copy Project for build:

cd ~/esp
cp -r /home/pi/esp/examples/get-started/hello_world .


Configure Project:

cd ~/esp/hello_world
idf.py set-target esp32
idf.py menuconfig


Build Project:

idf.py build


Flash Project:

idf.py -p /dev/ttyUSB0 flash


Run / Monitor Project:

idf.py -p /dev/ttyUSB0 monitor
pi@RPi3B:~/esp $

pi@RPi3B:~/esp/simple $ curl -X POST --data-binary @hellostring 192.168.0.246:80/echo
Hello WIFI user.
This is the ESP32-PICO you're connected to.

pi@RPi3B:~/esp/simple $ cat hellostring
Hello WIFI user.
This is the ESP32-PICO you're connected to.

pi@RPi3B:~/esp/simple $



« Last Edit: March 02, 2021, 04:57:04 PM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #10 on: March 02, 2021, 07:03:44 PM »
This is an example of the ESP32-PICO acting as a TCP Echo Server over WIFI. I'm connecting to it with ScriptBasic using its built in socket support.

TCP Server
Code: C
  1. /* BSD Socket API Example
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9. #include <string.h>
  10. #include <sys/param.h>
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "esp_system.h"
  14. #include "esp_wifi.h"
  15. #include "esp_event.h"
  16. #include "esp_log.h"
  17. #include "nvs_flash.h"
  18. #include "esp_netif.h"
  19. #include "protocol_examples_common.h"
  20.  
  21. #include "lwip/err.h"
  22. #include "lwip/sockets.h"
  23. #include "lwip/sys.h"
  24. #include <lwip/netdb.h>
  25.  
  26.  
  27. #define PORT CONFIG_EXAMPLE_PORT
  28.  
  29. static const char *TAG = "example";
  30.  
  31. static void do_retransmit(const int sock)
  32. {
  33.     int len;
  34.     char rx_buffer[128];
  35.  
  36.     do {
  37.         len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
  38.         if (len < 0) {
  39.             ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
  40.         } else if (len == 0) {
  41.             ESP_LOGW(TAG, "Connection closed");
  42.         } else {
  43.             rx_buffer[len] = 0; // Null-terminate whatever is received and treat it like a string
  44.             ESP_LOGI(TAG, "Received %d bytes: %s", len, rx_buffer);
  45.  
  46.             // send() can return less bytes than supplied length.
  47.             // Walk-around for robust implementation.
  48.             int to_write = len;
  49.             while (to_write > 0) {
  50.                 int written = send(sock, rx_buffer + (len - to_write), to_write, 0);
  51.                 if (written < 0) {
  52.                     ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
  53.                 }
  54.                 to_write -= written;
  55.             }
  56.         }
  57.     } while (len > 0);
  58. }
  59.  
  60. static void tcp_server_task(void *pvParameters)
  61. {
  62.     char addr_str[128];
  63.     int addr_family = (int)pvParameters;
  64.     int ip_protocol = 0;
  65.     struct sockaddr_in6 dest_addr;
  66.  
  67.     if (addr_family == AF_INET) {
  68.         struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
  69.         dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
  70.         dest_addr_ip4->sin_family = AF_INET;
  71.         dest_addr_ip4->sin_port = htons(PORT);
  72.         ip_protocol = IPPROTO_IP;
  73.     } else if (addr_family == AF_INET6) {
  74.         bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un));
  75.         dest_addr.sin6_family = AF_INET6;
  76.         dest_addr.sin6_port = htons(PORT);
  77.         ip_protocol = IPPROTO_IPV6;
  78.     }
  79.  
  80.     int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
  81.     if (listen_sock < 0) {
  82.         ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
  83.         vTaskDelete(NULL);
  84.         return;
  85.     }
  86. #if defined(CONFIG_EXAMPLE_IPV4) && defined(CONFIG_EXAMPLE_IPV6)
  87.     // Note that by default IPV6 binds to both protocols, it is must be disabled
  88.     // if both protocols used at the same time (used in CI)
  89.     int opt = 1;
  90.     setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  91.     setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
  92. #endif
  93.  
  94.     ESP_LOGI(TAG, "Socket created");
  95.  
  96.     int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
  97.     if (err != 0) {
  98.         ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
  99.         ESP_LOGE(TAG, "IPPROTO: %d", addr_family);
  100.         goto CLEAN_UP;
  101.     }
  102.     ESP_LOGI(TAG, "Socket bound, port %d", PORT);
  103.  
  104.     err = listen(listen_sock, 1);
  105.     if (err != 0) {
  106.         ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
  107.         goto CLEAN_UP;
  108.     }
  109.  
  110.     while (1) {
  111.  
  112.         ESP_LOGI(TAG, "Socket listening");
  113.  
  114.         struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
  115.         socklen_t addr_len = sizeof(source_addr);
  116.         int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
  117.         if (sock < 0) {
  118.             ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
  119.             break;
  120.         }
  121.  
  122.         // Convert ip address to string
  123.         if (source_addr.ss_family == PF_INET) {
  124.             inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
  125.         } else if (source_addr.ss_family == PF_INET6) {
  126.             inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
  127.         }
  128.         ESP_LOGI(TAG, "Socket accepted ip address: %s", addr_str);
  129.  
  130.         do_retransmit(sock);
  131.  
  132.         shutdown(sock, 0);
  133.         close(sock);
  134.     }
  135.  
  136. CLEAN_UP:
  137.     close(listen_sock);
  138.     vTaskDelete(NULL);
  139. }
  140.  
  141. void app_main(void)
  142. {
  143.     ESP_ERROR_CHECK(nvs_flash_init());
  144.     ESP_ERROR_CHECK(esp_netif_init());
  145.     ESP_ERROR_CHECK(esp_event_loop_create_default());
  146.  
  147.     /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
  148.      * Read "Establishing Wi-Fi or Ethernet Connection" section in
  149.      * examples/protocols/README.md for more information about this function.
  150.      */
  151.     ESP_ERROR_CHECK(example_connect());
  152.  
  153. #ifdef CONFIG_EXAMPLE_IPV4
  154.     xTaskCreate(tcp_server_task, "tcp_server", 4096, (void*)AF_INET, 5, NULL);
  155. #endif
  156. #ifdef CONFIG_EXAMPLE_IPV6
  157.     xTaskCreate(tcp_server_task, "tcp_server", 4096, (void*)AF_INET6, 5, NULL);
  158. #endif
  159. }
  160.  

TCP Client
Code: Script BASIC
  1. ' ScriptBasic TCP Echo Client
  2.  
  3. OPEN "192.168.0.246:3333" FOR SOCKET AS #1
  4. PRINT #1, "Hello ESP32-PICO\n"
  5. LINE INPUT #1, response
  6. PRINT response
  7. CLOSE(1)
  8.  


pi@RPi3B:~/esp/tcp_server $ scriba tcp_client.sb
Hello ESP32-PICO
pi@RPi3B:~/esp/tcp_server $

« Last Edit: March 02, 2021, 07:11:17 PM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • Moderator
  • *****
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Pico
« Reply #11 on: March 03, 2021, 07:49:12 AM »
FreeRTOS Real Time Stats Example

FreeRTOS provides the function vTaskGetRunTimeStats() to obtain CPU usage statistics of tasks. However, these statistics are with respect to the entire runtime of FreeRTOS (i.e. run time stats). Furthermore, statistics of vTaskGetRunTimeStats() are only valid whilst the timer for run time statistics has not overflowed.

This example demonstrates how to get CPU usage statistics of tasks with respect to a specified duration (i.e. real time stats) rather than over the entire runtime of FreeRTOS. The print_real_time_stats() function of this example demonstrates how this can be achieved.

Example Breakdown

Spin tasks

During the examples initialization process, multiple spin tasks are created. These tasks will simply spin a certain number of CPU cycles to consume CPU time, then block for a predetermined period.

Understanding the stats

From the log output, it can be seen that the spin tasks consume nearly an equal amount of time over the specified stats collection period of print_real_time_stats(). The real time stats also display the CPU time consumption of other tasks created by default in ESP-IDF (e.g. IDLE and ipc tasks).

Code: C
  1. /* FreeRTOS Real Time Stats Example
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "freertos/FreeRTOS.h"
  13. #include "freertos/task.h"
  14. #include "freertos/semphr.h"
  15. #include "esp_err.h"
  16.  
  17. #define NUM_OF_SPIN_TASKS   6
  18. #define SPIN_ITER           500000  //Actual CPU cycles used will depend on compiler optimization
  19. #define SPIN_TASK_PRIO      2
  20. #define STATS_TASK_PRIO     3
  21. #define STATS_TICKS         pdMS_TO_TICKS(1000)
  22. #define ARRAY_SIZE_OFFSET   5   //Increase this if print_real_time_stats returns ESP_ERR_INVALID_SIZE
  23.  
  24. static char task_names[NUM_OF_SPIN_TASKS][configMAX_TASK_NAME_LEN];
  25. static SemaphoreHandle_t sync_spin_task;
  26. static SemaphoreHandle_t sync_stats_task;
  27.  
  28. /**
  29.  * @brief   Function to print the CPU usage of tasks over a given duration.
  30.  *
  31.  * This function will measure and print the CPU usage of tasks over a specified
  32.  * number of ticks (i.e. real time stats). This is implemented by simply calling
  33.  * uxTaskGetSystemState() twice separated by a delay, then calculating the
  34.  * differences of task run times before and after the delay.
  35.  *
  36.  * @note    If any tasks are added or removed during the delay, the stats of
  37.  *          those tasks will not be printed.
  38.  * @note    This function should be called from a high priority task to minimize
  39.  *          inaccuracies with delays.
  40.  * @note    When running in dual core mode, each core will correspond to 50% of
  41.  *          the run time.
  42.  *
  43.  * @param   xTicksToWait    Period of stats measurement
  44.  *
  45.  * @return
  46.  *  - ESP_OK                Success
  47.  *  - ESP_ERR_NO_MEM        Insufficient memory to allocated internal arrays
  48.  *  - ESP_ERR_INVALID_SIZE  Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET
  49.  *  - ESP_ERR_INVALID_STATE Delay duration too short
  50.  */
  51. static esp_err_t print_real_time_stats(TickType_t xTicksToWait)
  52. {
  53.     TaskStatus_t *start_array = NULL, *end_array = NULL;
  54.     UBaseType_t start_array_size, end_array_size;
  55.     uint32_t start_run_time, end_run_time;
  56.     esp_err_t ret;
  57.  
  58.     //Allocate array to store current task states
  59.     start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
  60.     start_array = malloc(sizeof(TaskStatus_t) * start_array_size);
  61.     if (start_array == NULL) {
  62.         ret = ESP_ERR_NO_MEM;
  63.         goto exit;
  64.     }
  65.     //Get current task states
  66.     start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time);
  67.     if (start_array_size == 0) {
  68.         ret = ESP_ERR_INVALID_SIZE;
  69.         goto exit;
  70.     }
  71.  
  72.     vTaskDelay(xTicksToWait);
  73.  
  74.     //Allocate array to store tasks states post delay
  75.     end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
  76.     end_array = malloc(sizeof(TaskStatus_t) * end_array_size);
  77.     if (end_array == NULL) {
  78.         ret = ESP_ERR_NO_MEM;
  79.         goto exit;
  80.     }
  81.     //Get post delay task states
  82.     end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time);
  83.     if (end_array_size == 0) {
  84.         ret = ESP_ERR_INVALID_SIZE;
  85.         goto exit;
  86.     }
  87.  
  88.     //Calculate total_elapsed_time in units of run time stats clock period.
  89.     uint32_t total_elapsed_time = (end_run_time - start_run_time);
  90.     if (total_elapsed_time == 0) {
  91.         ret = ESP_ERR_INVALID_STATE;
  92.         goto exit;
  93.     }
  94.  
  95.     printf("| Task | Run Time | Percentage\n");
  96.     //Match each task in start_array to those in the end_array
  97.     for (int i = 0; i < start_array_size; i++) {
  98.         int k = -1;
  99.         for (int j = 0; j < end_array_size; j++) {
  100.             if (start_array[i].xHandle == end_array[j].xHandle) {
  101.                 k = j;
  102.                 //Mark that task have been matched by overwriting their handles
  103.                 start_array[i].xHandle = NULL;
  104.                 end_array[j].xHandle = NULL;
  105.                 break;
  106.             }
  107.         }
  108.         //Check if matching task found
  109.         if (k >= 0) {
  110.             uint32_t task_elapsed_time = end_array[k].ulRunTimeCounter - start_array[i].ulRunTimeCounter;
  111.             uint32_t percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * portNUM_PROCESSORS);
  112.             printf("| %s | %d | %d%%\n", start_array[i].pcTaskName, task_elapsed_time, percentage_time);
  113.         }
  114.     }
  115.  
  116.     //Print unmatched tasks
  117.     for (int i = 0; i < start_array_size; i++) {
  118.         if (start_array[i].xHandle != NULL) {
  119.             printf("| %s | Deleted\n", start_array[i].pcTaskName);
  120.         }
  121.     }
  122.     for (int i = 0; i < end_array_size; i++) {
  123.         if (end_array[i].xHandle != NULL) {
  124.             printf("| %s | Created\n", end_array[i].pcTaskName);
  125.         }
  126.     }
  127.     ret = ESP_OK;
  128.  
  129. exit:    //Common return path
  130.     free(start_array);
  131.     free(end_array);
  132.     return ret;
  133. }
  134.  
  135. static void spin_task(void *arg)
  136. {
  137.     xSemaphoreTake(sync_spin_task, portMAX_DELAY);
  138.     while (1) {
  139.         //Consume CPU cycles
  140.         for (int i = 0; i < SPIN_ITER; i++) {
  141.             __asm__ __volatile__("NOP");
  142.         }
  143.         vTaskDelay(pdMS_TO_TICKS(100));
  144.     }
  145. }
  146.  
  147. static void stats_task(void *arg)
  148. {
  149.     xSemaphoreTake(sync_stats_task, portMAX_DELAY);
  150.  
  151.     //Start all the spin tasks
  152.     for (int i = 0; i < NUM_OF_SPIN_TASKS; i++) {
  153.         xSemaphoreGive(sync_spin_task);
  154.     }
  155.  
  156.     //Print real time stats periodically
  157.     while (1) {
  158.         printf("\n\nGetting real time stats over %d ticks\n", STATS_TICKS);
  159.         if (print_real_time_stats(STATS_TICKS) == ESP_OK) {
  160.             printf("Real time stats obtained\n");
  161.         } else {
  162.             printf("Error getting real time stats\n");
  163.         }
  164.         vTaskDelay(pdMS_TO_TICKS(1000));
  165.     }
  166. }
  167.  
  168. void app_main(void)
  169. {
  170.     //Allow other core to finish initialization
  171.     vTaskDelay(pdMS_TO_TICKS(100));
  172.  
  173.     //Create semaphores to synchronize
  174.     sync_spin_task = xSemaphoreCreateCounting(NUM_OF_SPIN_TASKS, 0);
  175.     sync_stats_task = xSemaphoreCreateBinary();
  176.  
  177.     //Create spin tasks
  178.     for (int i = 0; i < NUM_OF_SPIN_TASKS; i++) {
  179.         snprintf(task_names[i], configMAX_TASK_NAME_LEN, "spin%d", i);
  180.         xTaskCreatePinnedToCore(spin_task, task_names[i], 1024, NULL, SPIN_TASK_PRIO, NULL, tskNO_AFFINITY);
  181.     }
  182.  
  183.     //Create and start stats task
  184.     xTaskCreatePinnedToCore(stats_task, "stats", 4096, NULL, STATS_TASK_PRIO, NULL, tskNO_AFFINITY);
  185.     xSemaphoreGive(sync_stats_task);
  186. }
  187.  


Getting real time stats over 100 ticks
| Task | Run Time | Percentage
| stats | 1468 | 0%
| spin3 | 209100 | 10%
| spin4 | 225361 | 11%
| spin5 | 225360 | 11%
| spin1 | 217281 | 10%
| spin2 | 225387 | 11%
| spin0 | 225371 | 11%
| IDLE | 269997 | 13%
| IDLE | 394701 | 19%
| esp_timer | 0 | 0%
| ipc1 | 0 | 0%
| ipc0 | 0 | 0%
Real time stats obtained


Getting real time stats over 100 ticks
| Task | Run Time | Percentage
| stats | 988 | 0%
| spin3 | 225354 | 11%
| spin1 | 225357 | 11%
| IDLE | 443980 | 22%
| IDLE | 202904 | 10%
| spin2 | 225354 | 11%
| spin5 | 225355 | 11%
| spin0 | 225354 | 11%
| spin4 | 225354 | 11%
| ipc0 | 0 | 0%
| esp_timer | 0 | 0%
| ipc1 | 0 | 0%
Real time stats obtained


Getting real time stats over 100 ticks
| Task | Run Time | Percentage
| stats | 965 | 0%
| spin1 | 225354 | 11%
| IDLE | 202929 | 10%
| IDLE | 443980 | 22%
| spin2 | 225354 | 11%
| spin5 | 225355 | 11%
| spin0 | 225354 | 11%
| spin3 | 225355 | 11%
| spin4 | 225354 | 11%
| ipc1 | 0 | 0%
| ipc0 | 0 | 0%
| esp_timer | 0 | 0%
Real time stats obtained


Getting real time stats over 100 ticks
| Task | Run Time | Percentage
| stats | 965 | 0%
| IDLE | 443980 | 22%
| IDLE | 202929 | 10%
| spin2 | 225354 | 11%
| spin5 | 225355 | 11%
| spin0 | 225354 | 11%
| spin3 | 225355 | 11%
| spin1 | 225354 | 11%
| spin4 | 225354 | 11%
| esp_timer | 0 | 0%
| ipc1 | 0 | 0%
| ipc0 | 0 | 0%
Real time stats obtained

ScriptBasic Project Manager/Facilitator