Unverified Commit 0e18f098 authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Enable IPv4 or IPv4/IPv6 stacks, Ethernet class (#695)

IPv4-only mode saves 20KB+ of flash memory.

Add some backwards compatibility with the global Arduino Ethernet
class when running in IPv4 only mode.

Fixes #687

* Speed P.IO build by not cloning 2GB of sources
* Document P.IO new option
parent 40f4fdf2
......@@ -185,7 +185,14 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
submodules: 'true'
- name: Initialize needed submodules
run: |
cd pico-sdk
git submodule update --init
cd ../libraries/Adafruit_TinyUSB_Arduino
git submodule update --init
cd ../..
- name: Cache pip
uses: actions/cache@v2
with:
......
This diff is collapsed.
......@@ -179,8 +179,10 @@ bool IPAddress::isValid(const char* arg) {
return IPAddress().fromString(arg);
}
namespace arduino {
const IPAddress INADDR_ANY; // generic "0.0.0.0" for IPv4 & IPv6
const IPAddress INADDR_NONE(255,255,255,255);
};
void IPAddress::clear() {
(*this) = INADDR_ANY;
......
......@@ -27,11 +27,14 @@
#include <lwip/ip_addr.h>
#include <lwip/ip4_addr.h>
namespace arduino {
#if !LWIP_IPV6
struct ip_addr: ipv4_addr { };
#endif // !LWIP_IPV6
// forward declarations of global name space friend classes
class EthernetClass;
class DhcpClass;
class DNSClient;
namespace arduino {
// to display a netif id with printf:
#define NETIFID_STR "%c%c%u"
......@@ -48,8 +51,19 @@ struct ip_addr: ipv4_addr { };
class IPAddress: public Printable {
private:
#if !LWIP_IPV6
// Ugly hack to allow Arduino Ethernet library to twiddle internal bits.
// This can only work in IPv4-only mode, of course.
union {
ip_addr_t _ip;
struct {
uint8_t bytes[4];
} _address;
};
static_assert(sizeof(_ip) == sizeof(_address), "IP_ADDR_T size != _ADDRESS size");
#else
ip_addr_t _ip;
#endif
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
......@@ -149,6 +163,10 @@ class IPAddress: public Printable {
friend class DhcpClass;
friend class DNSClient;
friend ::EthernetClass;
friend ::DhcpClass;
friend ::DNSClient;
/*
lwIP address compatibility
*/
......@@ -167,7 +185,6 @@ class IPAddress: public Printable {
bool isLocal () const { return ip_addr_islinklocal(&_ip); }
#if LWIP_IPV6
IPAddress(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); }
IPAddress(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); }
......@@ -175,6 +192,7 @@ class IPAddress: public Printable {
IPAddress& operator=(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); return *this; }
IPAddress& operator=(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); return *this; }
#if LWIP_IPV6
uint16_t* raw6()
{
setV6();
......
......@@ -222,6 +222,18 @@ default Pico SDK USB stack. To change it, add
Note that the special "No USB" setting is also supported, through the
shortcut-define ``PIO_FRAMEWORK_ARDUINO_NO_USB``.
IP Stack
---------
The lwIP stack can be configured to support only IPv4 (default) or additionally IPv6. To activate IPv6 support, add
.. code:: ini
; IPv6
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
to the ``platformio.ini``.
Selecting a different core version
----------------------------------
......
No preview for this file type
......@@ -179,7 +179,7 @@ int LwipIntfDev<RawDev>::hostByName(const char* aHostname, IPAddress& aResult, i
#if LWIP_IPV4 && LWIP_IPV6
err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &_dns_found_callback, &cb, LWIP_DNS_ADDRTYPE_DEFAULT);
#else
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &cb);
err_t err = dns_gethostbyname(aHostname, &addr, &_dns_found_callback, &cb);
#endif
if (err == ERR_OK) {
aResult = IPAddress(&addr);
......
......@@ -41,12 +41,11 @@ compiler.warning_flags.default=-Werror=return-type
compiler.warning_flags.more=-Wall -Werror=return-type -Wno-ignored-qualifiers
compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualifiers
compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 -DLWIP_IPV6=1 -DLWIP_IPV4=1 -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1
compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 {build.lwipdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines}
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt" "-I{runtime.platform.path}/include"
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect}
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
compiler.libpico="{runtime.platform.path}/lib/libpico.a"
compiler.libbearssl="{runtime.platform.path}/lib/libbearssl.a"
compiler.c.cmd=arm-none-eabi-gcc
......@@ -92,8 +91,9 @@ build.usbstack_flags=
build.flags.libstdcpp=-lstdc++
build.flags.exceptions=-fno-exceptions
build.flags.stackprotect=
build.libpico=libpico.a
build.boot2=boot2_generic_03h_4_padded_checksum
build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1
# Allow Pico boards do be auto-discovered by the IDE
discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/discovery.py"
......@@ -123,7 +123,7 @@ recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3
recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.S.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -c "{runtime.platform.path}/boot2/{build.boot2}.S" "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" -o "{build.path}/boot2.o"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libraries.ldflags} {compiler.libpico} {compiler.libbearssl} -lm -lc {build.flags.libstdcpp} -lc -Wl,--end-group
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libraries.ldflags} "{runtime.platform.path}/lib/{build.libpico}" {compiler.libbearssl} -lm -lc {build.flags.libstdcpp} -lc -Wl,--end-group
## Create output (UF2 file)
recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2"
......
......@@ -21,7 +21,7 @@ target_compile_definitions(pico PUBLIC
PICO_FLASH_SIZE_BYTES=16777216
PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
LWIP_IPV4=1
LWIP_IPV6=1
LWIP_IPV6=${IPV6}
LWIP_UDP=1
LWIP_IGMP=1
LWIP_CHECKSUM_CTRL_PER_NETIF=1
......
......@@ -8,7 +8,7 @@ export PATH="$(cd ../../system/arm-none-eabi/bin; pwd):$PATH"
rm -rf build
mkdir build
cd build
cmake ..
cmake .. -DIPV6=0
make -j
# Put everything in its place
......@@ -17,6 +17,14 @@ mv generated/pico_base/pico/version.h ../../../include/pico_base/pico/.
cp ../lwipopts.h ../../../include/.
cp ../tusb_config.h ../../../include/.
cd ..
rm -rf build
mkdir build
cd build
cmake .. -DIPV6=1
make -j
mv libpico.a ../../../lib/libpico-ipv6.a
rm -rf boot
mkdir boot
cd boot
......
......@@ -83,6 +83,14 @@ def BuildWithoutUSBStack(name):
print("%s.menu.usbstack.nousb=No USB" % (name))
print('%s.menu.usbstack.nousb.build.usbstack_flags="-DNO_USB -DDISABLE_USB_SERIAL -I{runtime.platform.path}/tools/libpico"' % (name))
def BuildIPStack(name):
print("%s.menu.ipstack.ipv4only=IPv4 Only" % (name))
print('%s.menu.ipstack.ipv4only.build.libpico=libpico.a' % (name))
print('%s.menu.ipstack.ipv4only.build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1' % (name))
print("%s.menu.ipstack.ipv4ipv6=IPv4 and IPv6" % (name))
print('%s.menu.ipstack.ipv4ipv6.build.libpico=libpico-ipv6.a' % (name))
print('%s.menu.ipstack.ipv4ipv6.build.lwipdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1' % (name))
def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, pwr, boarddefine, variant, uploadtool, flashsize, ramsize, boot2):
prettyname = vendor_name + " " + product_name
print()
......@@ -133,7 +141,7 @@ def BuildGlobalMenuList():
print("menu.dbglvl=Debug Level")
print("menu.boot2=Boot Stage 2")
print("menu.usbstack=USB Stack")
print("menu.ipstack=IP Stack")
def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2):
for a, b, c in [ ["", "", "uf2conv"], ["picoprobe", " (Picoprobe)", "picoprobe"], ["picodebug", " (pico-debug)", "picodebug"]]:
......@@ -171,6 +179,7 @@ def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flash
BuildWithoutUSBStack(n)
else:
BuildUSBStack(n)
BuildIPStack(n)
if name == "generic":
BuildBoot(n)
MakeBoardJSON(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2)
......
......@@ -79,6 +79,12 @@ env.Replace(
SIZEPROGREGEXP=r"^(?:\.boot2|\.text|\.data|\.rodata|\.text.align|\.ARM.exidx)\s+(\d+).*"
)
# pico support library depends on ipv6 enable/disable
if "PIO_FRAMEWORK_ARDUINO_ENABLE_IPV6" in flatten_cppdefines:
libpico = File(os.path.join(FRAMEWORK_DIR, "lib", "libpico-ipv6.a"))
else:
libpico = File(os.path.join(FRAMEWORK_DIR, "lib", "libpico.a"))
env.Append(
ASFLAGS=env.get("CCFLAGS", [])[:],
......@@ -106,13 +112,6 @@ env.Append(
"ARDUINO_ARCH_RP2040",
("F_CPU", "$BOARD_F_CPU"),
("BOARD_NAME", '\\"%s\\"' % env.subst("$BOARD")),
# LWIP-related
("PICO_CYW43_ARCH_THREADSAFE_BACKGROUND", 1),
("CYW43_LWIP", 0),
("LWIP_IPV6", 1),
("LWIP_IPV4", 1),
("LWIP_IGMP", 1),
("LWIP_LWIP_CHECKSUM_CTRL_PER_NETIF", 1),
],
CPPPATH=[
......@@ -147,7 +146,7 @@ env.Append(
# link lib/libpico.a by full path, ignore libstdc++
LIBS=[
File(os.path.join(FRAMEWORK_DIR, "lib", "libpico.a")),
libpico,
File(os.path.join(FRAMEWORK_DIR, "lib", "libbearssl.a")),
"m", "c", stdcpp_lib, "c"]
)
......@@ -228,15 +227,19 @@ def configure_usb_flags(cpp_defines):
board.update("build.hwids", hw_ids)
board.update("upload.maximum_ram_size", ram_size)
def configure_network_flags():
def configure_network_flags(cpp_defines):
env.Append(CPPDEFINES=[
("PICO_CYW43_ARCH_THREADSAFE_BACKGROUND", 1),
("CYW43_LWIP", 0),
("LWIP_IPV6", 1),
("LWIP_IPV4", 1),
("LWIP_IGMP", 1),
("LWIP_CHECKSUM_CTRL_PER_NETIF", 1)
])
if "PIO_FRAMEWORK_ARDUINO_ENABLE_IPV6" in cpp_defines:
env.Append(CPPDEFINES=[("LWIP_IPV6", 1)])
else:
env.Append(CPPDEFINES=[("LWIP_IPV6", 0)])
#
# Process configuration flags
#
......@@ -255,7 +258,7 @@ if not "USE_TINYUSB" in cpp_defines:
)
# configure USB stuff
configure_usb_flags(cpp_defines)
configure_network_flags()
configure_network_flags(cpp_defines)
# ensure LWIP headers are in path after any TINYUSB distributed versions, also PicoSDK USB path headers
env.Append(CPPPATH=[os.path.join(FRAMEWORK_DIR, "include")])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment