Improved Raspberry Pi Pico support

Fixes and improvements for RP2040 and added RP2350 support:

* Made UART `printf` output optional
* Made WiFi support optional
* Added compile support for RP2350
* Added compile support for RP2350 in RISC-V mode
* Re-wrote README
* Fixed compile issues
pull/468/head
Andrew Hutchings 2024-11-06 16:41:31 +00:00 committed by Andrew Hutchings
parent 14dfeeb4df
commit 0f195c94e6
5 changed files with 208 additions and 48 deletions

View File

@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
# Pull in Pico and FreeRTOS # Pull in Pico and FreeRTOS
include(pico_sdk_import.cmake) include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
include(pico_extras_import_optional.cmake) #include(pico_extras_import_optional.cmake)
#include($ENV{FREERTOS_KERNEL_PATH}/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake) #include($ENV{FREERTOS_KERNEL_PATH}/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake)
@ -17,6 +17,15 @@ set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK # Initialize the SDK
pico_sdk_init() pico_sdk_init()
option(USE_UART "Output over UART instead of USB" OFF)
option(USE_WIFI "Enable WiFi" OFF)
option(WIFI_SSID "The WiFi SSID to connect to" "")
option(WIFI_PASSWORD "The WiFi password" "")
option(TEST_TCP_SERVER_IP "The TCP test server IP" "")
if (USE_WIFI AND NOT PICO_CYW43_SUPPORTED)
message(FATAL_ERROR "You can only set USE_WIFI when a PICO_BOARD with wifi is used")
endif()
### Global Include Path ### Global Include Path
include_directories(config) include_directories(config)
@ -32,9 +41,10 @@ pico_sdk_init()
### wolfSSL/wolfCrypt library ### wolfSSL/wolfCrypt library
file(GLOB_RECURSE WOLFSSL_SRC file(GLOB WOLFSSL_SRC
"${WOLFSSL_ROOT}/src/*.c" "${WOLFSSL_ROOT}/src/*.c"
"${WOLFSSL_ROOT}/wolfcrypt/src/*.c" "${WOLFSSL_ROOT}/wolfcrypt/src/*.c"
"${WOLFSSL_ROOT}/wolfcrypt/src/port/rpi_pico/*"
) )
list(REMOVE_ITEM WOLFSSL_SRC EXCLUDE REGEX list(REMOVE_ITEM WOLFSSL_SRC EXCLUDE REGEX
"${WOLFSSL_ROOT}/src/bio.c" "${WOLFSSL_ROOT}/src/bio.c"
@ -56,25 +66,48 @@ pico_sdk_init()
target_compile_definitions(wolfssl PUBLIC target_compile_definitions(wolfssl PUBLIC
WOLFSSL_USER_SETTINGS WOLFSSL_USER_SETTINGS
) )
if (${PICO_PLATFORM} STREQUAL "rp2350")
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
target_link_libraries(wolfssl
pico_stdlib
pico_rand
)
### End of wolfSSL/wolfCrypt library ### End of wolfSSL/wolfCrypt library
### Test wolfCrypt algorithms ### Test wolfCrypt algorithms
add_executable(testwolfcrypt add_executable(testwolfcrypt
src/test_main.c src/test_main.c
src/blink.c
${WOLFSSL_ROOT}/wolfcrypt/test/test.c ${WOLFSSL_ROOT}/wolfcrypt/test/test.c
) )
target_link_libraries(testwolfcrypt target_link_libraries(testwolfcrypt
wolfssl wolfssl
pico_stdlib pico_stdlib
pico_cyw43_arch_none
pico_rand pico_rand
) )
pico_enable_stdio_usb(testwolfcrypt 1) if (USE_UART)
pico_enable_stdio_uart(testwolfcrypt 0) pico_enable_stdio_usb(testwolfcrypt 0)
pico_enable_stdio_uart(testwolfcrypt 1)
else()
pico_enable_stdio_usb(testwolfcrypt 1)
pico_enable_stdio_uart(testwolfcrypt 0)
endif()
if (${PICO_PLATFORM} STREQUAL "rp2350")
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
pico_add_extra_outputs(testwolfcrypt) pico_add_extra_outputs(testwolfcrypt)
### End of Test wolfCrypt algorithms ### End of Test wolfCrypt algorithms
@ -83,29 +116,42 @@ pico_sdk_init()
### Benchmark wolfCrypt algorithms ### Benchmark wolfCrypt algorithms
add_executable(benchmark add_executable(benchmark
src/bench_main.c src/bench_main.c
src/blink.c
${WOLFSSL_ROOT}/wolfcrypt/benchmark/benchmark.c ${WOLFSSL_ROOT}/wolfcrypt/benchmark/benchmark.c
) )
target_link_libraries(benchmark target_link_libraries(benchmark
wolfssl wolfssl
pico_stdlib pico_stdlib
pico_cyw43_arch_none
pico_rand pico_rand
) )
pico_enable_stdio_usb(benchmark 1) if (USE_UART)
pico_enable_stdio_uart(benchmark 0) pico_enable_stdio_usb(benchmark 0)
pico_enable_stdio_uart(benchmark 1)
else()
pico_enable_stdio_usb(benchmark 1)
pico_enable_stdio_uart(benchmark 0)
endif()
if (${PICO_PLATFORM} STREQUAL "rp2350")
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
pico_add_extra_outputs(benchmark) pico_add_extra_outputs(benchmark)
### End of Benchmark wolfCrypt algorithms ### End of Benchmark wolfCrypt algorithms
if (USE_WIFI)
### Wifi connection ### Wifi connection
add_executable(Wifi add_executable(Wifi
src/blink.c src/blink.c
src/wifi.c src/wifi.c
src/Wifi_main.c src/wifi_main.c
) )
target_compile_definitions(Wifi PRIVATE target_compile_definitions(Wifi PRIVATE
@ -124,14 +170,27 @@ pico_sdk_init()
pico_async_context_poll pico_async_context_poll
) )
if (USE_UART)
pico_enable_stdio_usb(Wifi 0)
pico_enable_stdio_uart(Wifi 1)
else()
pico_enable_stdio_usb(Wifi 1)
pico_enable_stdio_uart(Wifi 0)
endif()
pico_enable_stdio_usb(Wifi 1) if (${PICO_PLATFORM} STREQUAL "rp2350")
pico_enable_stdio_uart(Wifi 0) add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
pico_add_extra_outputs(Wifi) pico_add_extra_outputs(Wifi)
### End of Wifi connection ### End of Wifi connection
endif()
if (USE_WIFI)
### TCP Client ### TCP Client
add_executable(tcp_Client add_executable(tcp_Client
src/blink.c src/blink.c
@ -157,14 +216,27 @@ pico_sdk_init()
pico_async_context_poll pico_async_context_poll
) )
if (USE_UART)
pico_enable_stdio_usb(tcp_Client 0)
pico_enable_stdio_uart(tcp_Client 1)
else()
pico_enable_stdio_usb(tcp_Client 1)
pico_enable_stdio_uart(tcp_Client 0)
endif()
pico_enable_stdio_usb(tcp_Client 1) if (${PICO_PLATFORM} STREQUAL "rp2350")
pico_enable_stdio_uart(tcp_Client 0) add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
pico_add_extra_outputs(tcp_Client) pico_add_extra_outputs(tcp_Client)
### End of TCP Client ### End of TCP Client
endif()
if (USE_WIFI)
### TLS Client ### TLS Client
add_executable(tls_Client add_executable(tls_Client
src/blink.c src/blink.c
@ -191,8 +263,22 @@ pico_sdk_init()
wolfssl wolfssl
) )
pico_enable_stdio_usb(tls_Client 1) if (USE_UART)
pico_enable_stdio_uart(tls_Client 0) pico_enable_stdio_usb(tls_Client 0)
pico_enable_stdio_uart(tls_Client 1)
else()
pico_enable_stdio_usb(tls_Client 1)
pico_enable_stdio_uart(tls_Client 0)
endif()
if (${PICO_PLATFORM} STREQUAL "rp2350")
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_CORTEX_M_ASM)
elseif (${PICO_PLATFORM} STREQUAL "rp2350-riscv")
add_compile_definitions(wolfSSL WOLFSSL_SP_RISCV32)
else()
add_compile_definitions(wolfssl WOLFSSL_SP_ARM_THUMB_ASM)
endif()
pico_add_extra_outputs(tls_Client) pico_add_extra_outputs(tls_Client)
### End of TLS Client ### End of TLS Client
endif()

View File

@ -1,18 +1,89 @@
## Getting Started ## Getting Started
1. Put wolfSSL source files under this directory. Details of the Pi Pico support in wolfSSL can be found in the
RPi-Pico/wolfssl `wolfcrypt/src/port/pi_pico/README.md`.
2. Setup pico-sdk and set PICO_SDK_PATH This demonstration compiles several different utilities, including the wolfCrypt
export PICO_SDK_PATH=/your/pico-sdk/path benchmark and test suite.
3. cmake and make ### Prerequisites
$ cd RPi-Pico
$ mkdir build
$ cd build
$ cmake -DPICO_BOARD=pico_w ..
$ make
4. Output is to USB serial You of course need a Pi Pico based board. Any RP2040 / RP2350 based board should
work, as long as it has a USB port to upload firmware to.
You need to have the [Raspberry Pi Pico SDK GitHub repository](https://github.com/raspberrypi/pico-sdk)
somewhere on your system. You also need the ARM compiler and CMake installed,
in Debian / Ubuntu you can do this using:
```
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
```
If you wish to use RISC-V with the RP2350 (ARM mode is default), you will need a
`riscv32-unknown-elf-gcc` compiler. You can search for binaries for this, or
compile the [RISC-V GNU Toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain)
in multilib mode. You will also need to add symlinks from `riscv64-unknown-*` to
`riscv32-unknown-elf-*` if you build the toolchain from source. This is because
the multilib mode compiler is both 32bit and 64bit.
### 1. Set an export to the wolfSSL source directory.
```
export WOLFSSL_ROOT=/path/to/wolfssl/source
```
### 2. Setup pico-sdk and set `PICO_SDK_PATH`
```
export PICO_SDK_PATH=/path/to/pico-sdk
```
### 3. cmake and make
The following CMAKE options are available:
* `PICO_BOARD` - This should be set to `pico` for a Pi Pico, `pico_w` for a Pi Pico with WiFi or `pico2` for a Pi Pico 2. A full list of boards for this option can be found [here](https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards), just ignore the `.h` at the end.
* `USE_WIFI` - Build the tests that use WiFi, only works when `PICO_BOARD` defined has a CYW43 WiFi chip.
* `USE_UART` - Output to UART instead of USB, for the Pi Debug Probe.
* `WIFI_SSID` - The SSID to connect to (if `USE_WIFI` is set).
* `WIFI_PASSWORD` - The password used for the WiFi network (if `USE_WIFI` is set).
* `TEST_TCP_SERVER_IP` - The test server to connect to for the TCP client test (if `USE_WIFI` is set).
To use the RP2350 in RISC-V mode, add `-DPICO_PLATFORM=rp2350-riscv`.
```
$ cd RPi-Pico
$ mkdir build
$ cd build
$ cmake -DPICO_BOARD=pico_w ..
$ make
```
### 4. Upload to the Pico
Hold the boot button and plug the Pico into your computer, you can then
drag/drop a `.uf2` to the Pico. It will stop becoming a USB mass storage device
and run immediately once the upload is complete. Alternatively, you can use
[picotool](https://github.com/raspberrypi/picotool) to upload a file:
```
sudo picotool load benchmark.uf2
sudo picotool reboot
```
### 5. Serial output
If you have not set `USE_UART`, once rebooted the USB port will turn into an
"Abstract Control Module" serial port. On Linux this will likely be
`/dev/ttyACM0`, or a number higher than `0` if you already have one. On macOS
this will be something like `/dev/cu.usbmodemXXXX`. The baud rate of this port
is 115200.
In Linux, most repositories have `minicom`. Install this using your package
manager and run:
```
minicom -b 115200 -o -D /dev/ttyACM0
```
If you need to exit at any time, it is CTRL-A followed by CTRL-X.

View File

@ -33,8 +33,11 @@ extern "C"
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <time.h>
#define TARGET_EMBEDDED #define TARGET_EMBEDDED
#define WOLFSSL_RPIPICO
extern time_t myTime(time_t *); extern time_t myTime(time_t *);
#define XTIME(t) myTime(t) #define XTIME(t) myTime(t)
@ -85,11 +88,12 @@ extern time_t myTime(time_t *);
/* SP Assembly Speedups - specific to chip type */ /* SP Assembly Speedups - specific to chip type */
#define WOLFSSL_SP_ASM #define WOLFSSL_SP_ASM
#endif #endif
/* Handled in CMake */
// #define WOLFSSL_SP_X86_64 // #define WOLFSSL_SP_X86_64
// #define WOLFSSL_SP_X86 // #define WOLFSSL_SP_X86
// #define WOLFSSL_SP_ARM32_ASM // #define WOLFSSL_SP_ARM32_ASM
// #define WOLFSSL_SP_ARM64_ASM // #define WOLFSSL_SP_ARM64_ASM
#define WOLFSSL_SP_ARM_THUMB_ASM // #define WOLFSSL_SP_ARM_THUMB_ASM
// #define WOLFSSL_SP_ARM_CORTEX_M_ASM // #define WOLFSSL_SP_ARM_CORTEX_M_ASM
#elif 1 #elif 1
/* Fast Math (tfm.c) (stack based and timing resistant) */ /* Fast Math (tfm.c) (stack based and timing resistant) */
@ -423,7 +427,7 @@ extern time_t myTime(time_t *);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Choose RNG method */ /* Choose RNG method */
#if 1 #if 0
/* Custom Seed Source */ /* Custom Seed Source */
/* Size of returned HW RNG value */ /* Size of returned HW RNG value */
//#define CUSTOM_RAND_TYPE unsigned int //#define CUSTOM_RAND_TYPE unsigned int
@ -432,7 +436,7 @@ unsigned long get_rand_32(void);
#define CUSTOM_RAND_GENERATE get_rand_32 #define CUSTOM_RAND_GENERATE get_rand_32
#endif #endif
#if 1 #if 0
/* Use built-in P-RNG (SHA256 based) with HW RNG */ /* Use built-in P-RNG (SHA256 based) with HW RNG */
/* P-RNG + HW RNG (P-RNG is ~8K) */ /* P-RNG + HW RNG (P-RNG is ~8K) */
#undef HAVE_HASHDRBG #undef HAVE_HASHDRBG
@ -442,11 +446,12 @@ unsigned long get_rand_32(void);
#define WC_NO_HASHDRBG #define WC_NO_HASHDRBG
#endif #endif
#if 0
#if 1
/* Bypass P-RNG and use only HW RNG */ /* Bypass P-RNG and use only HW RNG */
extern int my_rng_gen_block(unsigned char *output, unsigned int sz); //extern int my_rng_gen_block(unsigned char *output, unsigned int sz);
#undef CUSTOM_RAND_GENERATE_BLOCK #undef CUSTOM_RAND_GENERATE_BLOCK
#define CUSTOM_RAND_GENERATE_BLOCK my_rng_gen_block #define CUSTOM_RAND_GENERATE_BLOCK wc_pico_rng_gen_block
#endif #endif
@ -515,7 +520,7 @@ extern int my_rng_gen_block(unsigned char *output, unsigned int sz);
// #define WOLFCRYPT_ONLY // #define WOLFCRYPT_ONLY
/* do not warm when file is included to be built and not required to be */ /* do not warm when file is included to be built and not required to be */
#//define WOLFSSL_IGNORE_FILE_WARN #define WOLFSSL_IGNORE_FILE_WARN
/* In-lining of misc.c functions */ /* In-lining of misc.c functions */
/* If defined, must include wolfcrypt/src/misc.c in build */ /* If defined, must include wolfcrypt/src/misc.c in build */

View File

@ -27,7 +27,6 @@
#include <stdio.h> #include <stdio.h>
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "wolf/blink.h" #include "wolf/blink.h"
#include "hardware/clocks.h" #include "hardware/clocks.h"
@ -37,7 +36,7 @@ int main(int argc, char **argv)
int i; int i;
int ret; int ret;
blink(10, WOLF_BLINK_INIT); stdio_init_all();
printf("\nSystem clock = %dMHz\n\n", clock_get_hz(clk_sys)/1000000); printf("\nSystem clock = %dMHz\n\n", clock_get_hz(clk_sys)/1000000);
ret = benchmark_test(NULL); ret = benchmark_test(NULL);
printf("End: %d\n", ret); printf("End: %d\n", ret);
@ -49,4 +48,4 @@ time_t myTime(time_t *t)
{ {
*t = (((2023 - 1970) * 12 + 8) * 30 * 24 * 60 * 60); *t = (((2023 - 1970) * 12 + 8) * 30 * 24 * 60 * 60);
return *t; return *t;
} }

View File

@ -22,25 +22,24 @@
#include <stdint.h> #include <stdint.h>
#include "wolfssl/wolfcrypt/settings.h" #include "wolfssl/wolfcrypt/settings.h"
#include "wolfssl/ssl.h" #include <wolfssl/ssl.h>
#include <wolfcrypt/test/test.h> #include <wolfcrypt/test/test.h>
#include <stdio.h> #include <stdio.h>
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "wolf/blink.h"
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int i; int i;
int ret; int ret;
blink(10, WOLF_BLINK_INIT); stdio_init_all();
wolfSSL_Init(); wolfSSL_Init();
wolfSSL_Debugging_ON(); wolfSSL_Debugging_ON();
ret = wolfcrypt_test(NULL); ret = wolfcrypt_test(NULL);
printf("End: %d\n", ret); printf("End: %d\n", ret);
return ret; return ret;
} }
@ -50,4 +49,4 @@ time_t myTime(time_t *t)
{ {
*t = (((2023 - 1970) * 12 + 8) * 30 * 24 * 60 * 60); *t = (((2023 - 1970) * 12 + 8) * 30 * 24 * 60 * 60);
return *t; return *t;
} }