Skip to content

Commit 52853c4

Browse files
committed
Enable building RP2350 bare-metal and PicoSDK firmwares in RISC-V mode, correct RISC-V CMSIS-DAP uploading
1 parent 85097c0 commit 52853c4

File tree

6 files changed

+75
-25
lines changed

6 files changed

+75
-25
lines changed

builder/frameworks/_bare.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
env.Append(
2424
ASFLAGS=[
25-
"-mthumb",
2625
],
2726
ASPPFLAGS=[
2827
"-x", "assembler-with-cpp",
@@ -33,7 +32,6 @@
3332
"-ffunction-sections", # place each function in its own section
3433
"-fdata-sections",
3534
"-Wall",
36-
"-mthumb",
3735
"-nostdlib"
3836
],
3937

@@ -49,7 +47,6 @@
4947
LINKFLAGS=[
5048
"-Os",
5149
"-Wl,--gc-sections,--relax",
52-
"-mthumb",
5350
"--specs=nano.specs",
5451
"--specs=nosys.specs"
5552
],
@@ -62,23 +59,28 @@
6259
mcu = env.BoardConfig().get("build.mcu", "")
6360
if mcu == "rp2350":
6461
more_flags = [
62+
"-mcpu=%s" % env.BoardConfig().get("build.cpu"),
6563
"-march=armv8-m.main+fp+dsp",
64+
"-mthumb",
6665
"-mfloat-abi=hard",
6766
"-mcmse",
6867
]
69-
if mcu == "rp2350-riscv":
68+
elif mcu == "rp2040":
69+
more_flags = [
70+
"-mcpu=%s" % env.BoardConfig().get("build.cpu"),
71+
"-mthumb",
72+
]
73+
elif mcu == "rp2350-riscv":
7074
more_flags = [
75+
# special value as supported by our RISC-V toolchain. No -mcpu.
7176
"-march=rv32imac_zicsr_zifencei_zba_zbb_zbs_zbkb",
7277
"-mabi=ilp32"
7378
]
7479
env.Append(
75-
ASFLAGS=[
76-
"-mcpu=%s" % env.BoardConfig().get("build.cpu")
77-
] + more_flags,
78-
CCFLAGS=[
79-
"-mcpu=%s" % env.BoardConfig().get("build.cpu")
80-
] + more_flags,
81-
LINKFLAGS=[
82-
"-mcpu=%s" % env.BoardConfig().get("build.cpu")
83-
] + more_flags
80+
ASFLAGS=more_flags,
81+
CCFLAGS=more_flags,
82+
LINKFLAGS=more_flags
8483
)
84+
85+
if mcu == "rp2350-riscv":
86+
env.Append(LINKFLAGS=["-Wl,--no-warn-rwx-segments"])

builder/frameworks/picosdk.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
FRAMEWORK_DIR = platform.get_package_dir("framework-picosdk")
1212
assert isdir(FRAMEWORK_DIR)
1313

14-
mcu = "rp2350" if board.get('build.mcu') == "rp2350" else "rp2040"
15-
is_rp2350 = mcu == "rp2350"
14+
mcu = "rp2350" if "rp2350" in board.get('build.mcu') else "rp2040"
15+
is_rp2350 = mcu == "rp2350" # could be ARM or RISC-V
16+
is_riscv = board.get('build.mcu') == "rp2350-riscv"
1617
rp2_variant_dir = join(FRAMEWORK_DIR, "src", mcu)
1718
header = "%s.h" % board.get("build.variant")
1819
# try to find the board header in the common directory
@@ -58,11 +59,9 @@ def gen_config_autogen(target_base_dir, board_hdr):
5859
#CFLAGS=sorted(list(cflags - ccflags)),
5960
#CCFLAGS=sorted(list(ccflags)),
6061
CPPDEFINES=[
61-
# BUG: defining PICO_RP2040 in any way will force compilation for 2040 only.
62-
# FIX: add RP2350 only if board requested was 2350
63-
("PICO_RP2350" if board.get('build.mcu') == "rp2350" else "PICO_RP2040", 1),
64-
("PICO_RISCV", 0),
65-
("PICO_ARM", 1),
62+
("PICO_RP2350" if is_rp2350 else "PICO_RP2040", 1),
63+
("PICO_RISCV", int(is_riscv)),
64+
("PICO_ARM", int(not is_riscv)),
6665
("PICO_CMSIS_DEVICE", "\"%s\"" % mcu.upper()),
6766
("PICO_DEFAULT_FLASH_SIZE_BYTES", 2 * 1024 * 1024),
6867
# default SDK defines for on-hardware build
@@ -112,6 +111,7 @@ def gen_config_autogen(target_base_dir, board_hdr):
112111
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_exception", "include"),
113112
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_flash", "include"),
114113
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_gpio", "include"),
114+
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_hazard3", "include"),
115115
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_i2c", "include"),
116116
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_interp", "include"),
117117
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_irq", "include"),
@@ -120,6 +120,8 @@ def gen_config_autogen(target_base_dir, board_hdr):
120120
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_pwm", "include"),
121121
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_resets", "include"),
122122
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_rcp", "include"),
123+
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_riscv", "include"),
124+
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_riscv_platform_timer", "include"),
123125
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_rtc", "include"),
124126
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_spi", "include"),
125127
join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_sync_spin_lock", "include"),
@@ -335,6 +337,11 @@ def configure_printf_impl():
335337
# join("$BUILD_DIR", "PicoSDK"),
336338
# join(FRAMEWORK_DIR, "src", "rp2_common", "cmsis", "stub", "CMSIS", "Device", "RP2040", "Source")
337339
# )
340+
if is_rp2350:
341+
pad_checksum_arch = "-a riscv" if is_riscv else "-a arm"
342+
else:
343+
# when calling into the RP2040 version of that script, it actually doesn't take a "-a" argument at all.
344+
pad_checksum_arch = ""
338345

339346
gen_boot2_cmd = env.Command(
340347
join("$BUILD_DIR", "boot2.S"), # $TARGET
@@ -354,6 +361,7 @@ def configure_printf_impl():
354361
"-I", "$PROJECT_BUILD_DIR/$PIOENV/generated",
355362
"-I\"%s\"" % join(rp2_variant_dir, "pico_platform", "include"),
356363
"-I\"%s\"" % join(FRAMEWORK_DIR, "src", "rp2_common", "pico_platform_compiler", "include"),
364+
"-I\"%s\"" % join(FRAMEWORK_DIR, "src", "rp2_common", "hardware_hazard3", "include"),
357365
"-I\"%s\"" % join(rp2_variant_dir, "hardware_regs", "include"),
358366
"-I\"%s\"" % join(FRAMEWORK_DIR, "src", "rp2_common", "pico_platform_common", "include"),
359367
"-I\"%s\"" % join(FRAMEWORK_DIR, "src", "rp2_common", "pico_platform_sections", "include"),
@@ -374,6 +382,7 @@ def configure_printf_impl():
374382
"$PYTHONEXE",
375383
join(FRAMEWORK_DIR, "src", mcu, "boot_stage2", "pad_checksum"),
376384
"-s 0xffffffff",
385+
pad_checksum_arch,
377386
join("$BUILD_DIR", "boot2.bin"),
378387
join("$BUILD_DIR", "boot2.S"),
379388
]), "Generating boot2 $BUILD_DIR/boot2.S")
@@ -468,11 +477,11 @@ def configure_printf_impl():
468477
src_filter
469478
)
470479

471-
# Will be crt0_riscv.S for RISC-V builds..
480+
pico_crt0 = "crt0_riscv.S" if is_riscv else "crt0.S"
472481
env.BuildSources(
473482
join("$BUILD_DIR", "PicoSDKCRT0"),
474483
join(FRAMEWORK_DIR, "src", "rp2_common", "pico_crt0"),
475-
"-<*> +<crt0.S>"
484+
"-<*> +<%s>" % pico_crt0
476485
)
477486

478487
default_common_components = [

builder/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621
166166
env.TouchSerialPort("$UPLOAD_PORT", 1200)
167167
# delay a tiny bit in any case
168168
time.sleep(0.2)
169-
max_wait_s = 3.0
169+
max_wait_s = 5.0
170170
while max_wait_s > 0:
171171
if get_num_rpxxxx_devs(picotool_path) > num_before:
172172
print("Device rebooted into BOOTSEL mode successfully.")

examples/picosdk-blink/platformio.ini

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ board = pico
2121
board = rpipico2
2222
; explicitly set the board header for all pin definitions if not automatically detected
2323
; see <home folder>/.platformio/packages/framework-arduinopico/pico-sdk/src/boards/include/boards
24-
board_build.picosdk.board_header = pimoroni_tiny2350.h
24+
board_build.picosdk.board_header = pimoroni_plasma2350.h
25+
26+
[env:pico2-riscv]
27+
board = rpipico2
28+
board_build.mcu = rp2350-riscv
29+
board_build.picosdk.board_header = pimoroni_plasma2350.h

platform.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
"owner": "earlephilhower",
4242
"version": "https://github.com/maxgerhardt/toolchain-dummy/archive/refs/heads/main.zip"
4343
},
44+
"toolchain-riscv-rp2350": {
45+
"type": "toolchain",
46+
"optional": true,
47+
"owner": "platformio",
48+
"version": "https://github.com/maxgerhardt/toolchain-dummy/archive/refs/heads/main-riscv.zip"
49+
},
4450
"framework-arduino-mbed": {
4551
"type": "framework",
4652
"optional": true,

platform.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ class RaspberrypiPlatform(PlatformBase):
2323
def is_embedded(self):
2424
return True
2525

26+
picosdk_toolchain_riscv = {
27+
# Windows
28+
"windows_amd64": "https://github.com/maxgerhardt/toolchain-riscv-rp2350/releases/download/15.1.0/pio-riscv-toolchain-15-x64-win.zip",
29+
#"windows_x86": ""
30+
# No Windows x86, ARM64 or ARM32 builds.
31+
# Linux
32+
"linux_x86_64": "https://github.com/maxgerhardt/toolchain-riscv-rp2350/releases/download/15.1.0/toolchain-riscv-rp2350-linux_x86_64-1.150100.250822.tar.gz",
33+
#"linux_i686": "",
34+
"linux_aarch64": "https://github.com/maxgerhardt/toolchain-riscv-rp2350/releases/download/15.1.0/toolchain-riscv-rp2350-linux_aarch64-1.150100.250822.tar.gz",
35+
#"linux_armv7l": "",
36+
#"linux_armv6l": "",
37+
# Mac (Intel and ARM are the separate)
38+
"darwin_x86_64": "https://github.com/maxgerhardt/toolchain-riscv-rp2350/releases/download/15.1.0/toolchain-riscv-rp2350-darwin_x86_64-1.150100.250822.tar.gz",
39+
"darwin_arm64": "https://github.com/maxgerhardt/toolchain-riscv-rp2350/releases/download/15.1.0/toolchain-riscv-rp2350-darwin_arm64-1.150100.250822.tar.gz"
40+
}
41+
2642
earle_toolchain_arm = {
2743
# Windows
2844
"windows_amd64": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/4.1.0/x86_64-w64-mingw32.arm-none-eabi-1aec55e.250530.zip",
@@ -87,11 +103,15 @@ def is_embedded(self):
87103
"darwin_arm64": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/4.1.0/aarch64-apple-darwin20.4.picotool-c56c005.250530.tar.gz"
88104
}
89105

106+
last_board_is_riscv = False
107+
90108
def configure_default_packages(self, variables, targets):
91109
#print("System type: %s" % (util.get_systype()))
92110
# configure arduino core package.
93111
# select the right one based on the build.core, disable other one.
94112
board = variables.get("board")
113+
# workaround: remember this for upload logic
114+
self.last_board_is_riscv = variables.get("board_build.mcu", "").endswith("-riscv")
95115
board_config = self.board_config(board)
96116
chip = variables.get("board_build.mcu", board_config.get("build.mcu"))
97117
build_core = variables.get(
@@ -128,7 +148,13 @@ def configure_default_packages(self, variables, targets):
128148
sys.stderr.write(
129149
"Error! Unknown build.core value '%s'. Don't know which Arduino core package to use." % build_core)
130150
env.Exit(1)
131-
151+
else:
152+
# this is a pico-sdk or baremetal project. if it's for a rp2350-riscv, we need the RISC-V toolchain.
153+
if chip == "rp2350-riscv":
154+
self.packages["toolchain-riscv-rp2350"]["optional"] = False
155+
self.packages["toolchain-riscv-rp2350"]["version"] = RaspberrypiPlatform.picosdk_toolchain_riscv[sys_type]
156+
self.packages.pop("toolchain-gccarmnoneeabi", None)
157+
# rest is okay for ARM-based RP2040/RP2350.
132158
# if we want to build a filesystem, we need the tools.
133159
if "buildfs" in targets:
134160
self.packages["tool-mklittlefs-rp2040-earlephilhower"]["optional"] = False
@@ -208,6 +234,8 @@ def _add_default_debug_tools(self, board):
208234
}
209235
else:
210236
openocd_target = debug.get("openocd_target")
237+
if self.last_board_is_riscv:
238+
openocd_target = "rp2350-riscv.cfg"
211239
assert openocd_target, ("Missing target configuration for %s" %
212240
board.id)
213241
debug["tools"][link] = {

0 commit comments

Comments
 (0)