8000 Enable IPv4 or IPv4/IPv6 stacks, Ethernet class (#695) · ZZKK000/arduino-pico@0e18f09 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0e18f09

Browse files
Enable IPv4 or IPv4/IPv6 stacks, Ethernet class (earlephilhower#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 earlephilhower#687 * Speed P.IO build by not cloning 2GB of sources * Document P.IO new option
1 parent 40f4fdf commit 0e18f09

File tree

13 files changed

+662
-26
lines changed

13 files changed

+662
-26
lines changed

.github/workflows/pull-request.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ jobs:
185185
steps:
186186
- uses: actions/checkout@v3
187187
with:
188-
submodules: 'recursive'
188+
submodules: 'true'
189+
- name: Initialize needed submodules
190+
run: |
191+
cd pico-sdk
192+
git submodule update --init
193+
cd ../libraries/Adafruit_TinyUSB_Arduino
194+
git submodule update --init
195+
cd ../..
189196
- name: Cache pip
190197
uses: actions/cache@v2
191198
with:

boards.txt

Lines changed: 577 additions & 0 deletions
Large diffs are not rendered by default.

cores/rp2040/api/IPAddress.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,10 @@ bool IPAddress::isValid(const char* arg) {
179179
return IPAddress().fromString(arg);
180180
}
181181

182+
namespace arduino {
182183
const IPAddress INADDR_ANY; // generic "0.0.0.0" for IPv4 & IPv6
183184
const IPAddress INADDR_NONE(255,255,255,255);
185+
};
184186

185187
void IPAddress::clear() {
186188
(*this) = INADDR_ANY;

cores/rp2040/api/IPAddress.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
#include <lwip/ip_addr.h>
2828
#include <lwip/ip4_addr.h>
2929

30-
namespace arduino {
3130

32-
#if !LWIP_IPV6
33-
struct ip_addr: ipv4_addr { };
34-
#endif // !LWIP_IPV6
31+
// forward declarations of global name space friend classes
32+
class EthernetClass;
33+
class DhcpClass;
34+
class DNSClient;
35+
36+
37+
namespace arduino {
3538

3639
// to display a netif id with printf:
3740
#define NETIFID_STR "%c%c%u"
@@ -48,8 +51,19 @@ struct ip_addr: ipv4_addr { };
4851

4952
class IPAddress: public Printable {
5053
private:
51-
54+
#if !LWIP_IPV6
55+
// Ugly hack to allow Arduino Ethernet library to twiddle internal bits.
56+
// This can only work in IPv4-only mode, of course.
57+
union {
58+
ip_addr_t _ip;
59+
struct {
60+
uint8_t bytes[4];
61+
} _address;
62+
};
63+
static_assert(sizeof(_ip) == sizeof(_address), "IP_ADDR_T size != _ADDRESS size");
64+
#else
5265
ip_addr_t _ip;
66+
#endif
5367

5468
// Access the raw byte array containing the address. Because this returns a pointer
5569
// to the internal structure rather than a copy of the address this function should only
@@ -149,6 +163,10 @@ class IPAddress: public Printable {
149163
friend class DhcpClass;
150164
friend class DNSClient;
151165

166+
friend ::EthernetClass;
167+
friend ::DhcpClass;
168+
friend ::DNSClient;
169+
152170
/*
153171
lwIP address compatibility
154172
*/
@@ -167,14 +185,14 @@ class IPAddress: public Printable {
167185

168186
bool isLocal () const { return ip_addr_islinklocal(&_ip); }
169187

170-
#if LWIP_IPV6
171188

172189
IPAddress(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); }
173190
IPAddress(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); }
174191

175192
IPAddress& operator=(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); return *this; }
176193
IPAddress& operator=(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); return *this; }
177194

195+
#if LWIP_IPV6
178196
uint16_t* raw6()
179197
{
180198
setV6();

docs/platformio.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,18 @@ default Pico SDK USB stack. To change it, add
222222
Note that the special "No USB" setting is also supported, through the
223223
shortcut-define ``PIO_FRAMEWORK_ARDUINO_NO_USB``.
224224

225+
IP Stack
226+
---------
227+
228+
The lwIP stack can be configured to support only IPv4 (default) or additionally IPv6. To activate IPv6 support, add
229+
230+
.. code:: ini
231+
232+
; IPv6
233+
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
234+
235+
to the ``platformio.ini``.
236+
225237

226238
Selecting a different core version
227239
----------------------------------

lib/libpico-ipv6.a

2.91 MB
Binary file not shown.

lib/libpico.a

-374 KB
Binary file not shown.

libraries/lwIP_Ethernet/src/LwipIntfDev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ int LwipIntfDev<RawDev>::hostByName(const char* aHostname, IPAddress& aResult, i
179179
#if LWIP_IPV4 && LWIP_IPV6
180180
err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &_dns_found_callback, &cb, LWIP_DNS_ADDRTYPE_DEFAULT);
181181
#else
182-
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &cb);
182+
err_t err = dns_gethostbyname(aHostname, &addr, &_dns_found_callback, &cb);
183183
#endif
184184
if (err == ERR_OK) {
185185
aResult = IPAddress(&addr);

platform.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,11 @@ compiler.warning_flags.default=-Werror=return-type
4141
compiler.warning_flags.more=-Wall -Werror=return-type -Wno-ignored-qualifiers
4242
compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualifiers
4343

44-
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
44+
compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 {build.lwipdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1
4545
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}
4646
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt" "-I{runtime.platform.path}/include"
4747
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect}
4848
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
49-
compiler.libpico="{runtime.platform.path}/lib/libpico.a"
5049
compiler.libbearssl="{runtime.platform.path}/lib/libbearssl.a"
5150

5251
compiler.c.cmd=arm-none-eabi-gcc
@@ -92,8 +91,9 @@ build.usbstack_flags=
9291
build.flags.libstdcpp=-lstdc++
9392
build.flags.exceptions=-fno-exceptions
9493
build.flags.stackprotect=
95-
94+
build.libpico=libpico.a
9695
build.boot2=boot2_generic_03h_4_padded_checksum
96+
build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1
9797

9898
# Allow Pico boards do be auto-discovered by the IDE
9999
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
123123
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"
124124

125125
## Combine gc-sections, archives, and objects
126-
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
126+
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
127127

128128
## Create output (UF2 file)
129129
recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2"

tools/libpico/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ target_compile_definitions(pico PUBLIC
2121
PICO_FLASH_SIZE_BYTES=16777216
2222
PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
2323
LWIP_IPV4=1
24-
LWIP_IPV6=1
24+
LWIP_IPV6=${IPV6}
2525
LWIP_UDP=1
2626
LWIP_IGMP=1
2727
LWIP_CHECKSUM_CTRL_PER_NETIF=1

tools/libpico/make-libpico.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export PATH="$(cd ../../system/arm-none-eabi/bin; pwd):$PATH"
88
rm -rf build
99
mkdir build
1010
cd build
11-
cmake ..
11+
cmake .. -DIPV6=0
1212
make -j
1313

1414
# Put everything in its place
@@ -17,6 +17,14 @@ mv generated/pico_base/pico/version.h ../../../include/pico_base/pico/.
1717
cp ../lwipopts.h ../../../include/.
1818
cp ../tusb_config.h ../../../include/.
1919

20+
cd ..
21+
rm -rf build
22+
mkdir build
23+
cd build
24+
cmake .. -DIPV6=1
25+
make -j
26+
mv libpico.a ../../../lib/libpico-ipv6.a
27+
2028
rm -rf boot
2129
mkdir boot
2230
cd boot

tools/makeboards.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ def BuildWithoutUSBStack(name):
8383
print("%s.menu.usbstack.nousb=No USB" % (name))
8484
print('%s.menu.usbstack.nousb.build.usbstack_flags="-DNO_USB -DDISABLE_USB_SERIAL -I{runtime.platform.path}/tools/libpico"' % (name))
8585

86+
def BuildIPStack(name):
87+
print("%s.menu.ipstack.ipv4only=IPv4 Only" % (name))
88+
print('%s.menu.ipstack.ipv4only.build.libpico=libpico.a' % (name))
89+
print('%s.menu.ipstack.ipv4only.build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1' % (name))
90+
print("%s.menu.ipstack.ipv4ipv6=IPv4 and IPv6" % (name))
91+
print('%s.menu.ipstack.ipv4ipv6.build.libpico=libpico-ipv6.a' % (name))
92+
print('%s.menu.ipstack.ipv4ipv6.build.lwipdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1' % (name))
93+
8694
def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, pwr, boarddefine, variant, uploadtool, flashsize, ramsize, boot2):
8795
prettyname = vendor_name + " " + product_name
8896
print()
@@ -133,7 +141,7 @@ def BuildGlobalMenuList():
133141
print("menu.dbglvl=Debug Level")
134142
print("menu.boot2=Boot Stage 2")
135143
print("menu.usbstack=USB Stack")
136-
144+
print("menu.ipstack=IP Stack")
137145

138146
def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2):
139147
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
171179
BuildWithoutUSBStack(n)
172180
else:
173181
BuildUSBStack(n)
182+
BuildIPStack(n)
174183
if name == "generic":
175184
BuildBoot(n)
176185
MakeBoardJSON(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2)

tools/platformio-build.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ def is_pio_build():
7979
SIZEPROGREGEXP=r"^(?:\.boot2|\.text|\.data|\.rodata|\.text.align|\.ARM.exidx)\s+(\d+).*"
8080
)
8181

82+
# pico support library depends on ipv6 enable/disable
83+
if "PIO_FRAMEWORK_ARDUINO_ENABLE_IPV6" in flatten_cppdefines:
84+
libpico = File(os.path.join(FRAMEWORK_DIR, "lib", "libpico-ipv6.a"))
85+
else:
86+
libpico = File(os.path.join(FRAMEWORK_DIR, "lib", "libpico.a"))
87+
8288
env.Append(
8389
ASFLAGS=env.get("CCFLAGS", [])[:],
8490

@@ -106,13 +112,6 @@ def is_pio_build():
106112
"ARDUINO_ARCH_RP2040",
107113
("F_CPU", "$BOARD_F_CPU"),
108114
("BOARD_NAME", '\\"%s\\"' % env.subst("$BOARD")),
109-
# LWIP-related
110-
("PICO_CYW43_ARCH_THREADSAFE_BACKGROUND", 1),
111-
("CYW43_LWIP", 0),
112-
("LWIP_IPV6", 1),
113-
("LWIP_IPV4", 1),
114-
("LWIP_IGMP", 1),
115-
("LWIP_LWIP_CHECKSUM_CTRL_PER_NETIF", 1),
116115
],
117116

118117
CPPPATH=[
@@ -147,7 +146,7 @@ def is_pio_build():
147146

148147
# link lib/libpico.a by full path, ignore libstdc++
149148
LIBS=[
150-
File(os.path.join(FRAMEWORK_DIR, "lib", "libpico.a")),
149+
libpico,
151150
File(os.path.join(FRAMEWORK_DIR, "lib", "libbearssl.a")),
152151
"m", "c", stdcpp_lib, "c"]
153152
)
@@ -228,15 +227,19 @@ def configure_usb_flags(cpp_defines):
228227
board.update("build.hwids", hw_ids)
229228
board.update("upload.maximum_ram_size", ram_size)
230229

231-
def configure_network_flags():
230+
def configure_network_flags(cpp_defines):
232231
env.Append(CPPDEFINES=[
233232
("PICO_CYW43_ARCH_THREADSAFE_BACKGROUND", 1),
234233
("CYW43_LWIP", 0),
235-
("LWIP_IPV6", 1),
236234
("LWIP_IPV4", 1),
237235
("LWIP_IGMP", 1),
238236
("LWIP_CHECKSUM_CTRL_PER_NETIF", 1)
239237
])
238+
if "PIO_FRAMEWORK_ARDUINO_ENABLE_IPV6" in cpp_defines:
239+
env.Append(CPPDEFINES=[("LWIP_IPV6", 1)])
240+
else:
241+
env.Append(CPPDEFINES=[("LWIP_IPV6", 0)])
242+
240243
#
241244
# Process configuration flags
242245
#
@@ -255,7 +258,7 @@ def configure_network_flags():
255258
)
256259
# configure USB stuff
257260
configure_usb_flags(cpp_defines)
258-
configure_network_flags()
261+
configure_network_flags(cpp_defines)
259262

260263
# ensure LWIP headers are in path after any TINYUSB distributed versions, also PicoSDK USB path headers
261264
env.Append(CPPPATH=[os.path.join(FRAMEWORK_DIR, "include")])

0 commit comments

Comments
 (0)
0