Skip to content

Commit 8f8d0cd

Browse files
committed
soc: arm: rpi_pico: Add support RaspberryPi Pico binary info feature
Binary Info embeds program meta information in flash, which can be viewed with RaspberryPi Pico's `picotool`. Meta information is automatically collected from pinctrl. It can override by the Kconfig configurations, such as ``` CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME="my program name" ``` When this feature is enabled, pinctrl groups are restricted to consisting of pins with a single rpi_pico function. In other words, SPI's MISO and MOSI can be in the same group, but I2C's SDA cannot be included in this group. This is rarely an issue in normal use, and can be resolved by dividing them into separate groups. Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 861bdfd commit 8f8d0cd

File tree

9 files changed

+1528
-0
lines changed

9 files changed

+1528
-0
lines changed

soc/raspberrypi/rpi_pico/common/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,17 @@ zephyr_sources(
88
)
99

1010
zephyr_sources_ifdef(CONFIG_RPI_PICO_ROM_BOOTLOADER rom_bootloader.c)
11+
12+
zephyr_library_sources_ifdef(CONFIG_RPI_PICO_BINARY_INFO
13+
binary_info.c
14+
binary_info_pins.c
15+
binary_info_header.S
16+
)
17+
18+
zephyr_linker_sources_ifdef(CONFIG_RPI_PICO_BINARY_INFO
19+
ROM_START SORT_KEY 0x0binary_info_header binary_info_header.ld
20+
)
21+
22+
zephyr_linker_sources_ifdef(CONFIG_RPI_PICO_BINARY_INFO
23+
RODATA binary_info.ld
24+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2025 TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "soc/raspberrypi/rpi_pico/common/Kconfig.*"
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Copyright (c) 2024 TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config RPI_PICO_BINARY_INFO
5+
bool "Generate RaspberryPi Pico binary info"
6+
default y
7+
help
8+
Binary info is able to embed machine readable information with the binary in flash.
9+
It can read with picotool(https://github.com/raspberrypi/picotool).
10+
Binary info is generated automatically when this option is enabled,
11+
12+
When this feature is enabled, pinctrl groups are restricted to consisting
13+
of pins with a single rpi_pico function.
14+
In other words, SPI's MISO and MOSI can be in the same group, but I2C's
15+
SDA cannot be included in this group. This is rarely an issue in normal use,
16+
and can be resolved by dividing them into separate groups.
17+
18+
if RPI_PICO_BINARY_INFO
19+
20+
config RPI_PICO_BINARY_INFO_PROGRAM_NAME
21+
bool "Generate program_name in binary info"
22+
default y
23+
24+
if RPI_PICO_BINARY_INFO_PROGRAM_NAME
25+
26+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME
27+
string "Override program_name in binary info"
28+
depends on RPI_PICO_BINARY_INFO_PROGRAM_NAME
29+
30+
config RPI_PICO_BINARY_INFO_PROGRAM_NAME_OVERRIDDEN
31+
bool
32+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME != ""
33+
depends on RPI_PICO_BINARY_INFO_PROGRAM_NAME
34+
35+
endif
36+
37+
config RPI_PICO_BINARY_INFO_PROGRAM_URL
38+
bool "Generate program_url in binary info"
39+
default y
40+
41+
if RPI_PICO_BINARY_INFO_PROGRAM_URL
42+
43+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_URL
44+
string "Override program_url in binary info"
45+
depends on RPI_PICO_BINARY_INFO_PROGRAM_URL
46+
47+
config RPI_PICO_BINARY_INFO_PROGRAM_URL_OVERRIDDEN
48+
bool
49+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_URL != ""
50+
depends on RPI_PICO_BINARY_INFO_PROGRAM_URL
51+
52+
endif
53+
54+
config RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
55+
bool "Generate program_description in binary info"
56+
default y
57+
58+
if RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
59+
60+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_DESCRIPTION
61+
string "Override program_description in binary info"
62+
depends on RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
63+
64+
config RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION_OVERRIDDEN
65+
bool
66+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_DESCRIPTION != ""
67+
depends on RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
68+
69+
endif
70+
71+
config RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
72+
bool "Generate program_build_date in binary info"
73+
default y
74+
75+
if RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
76+
77+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_BUILD_DATE
78+
string "Override program_build_date in binary info"
79+
depends on RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
80+
81+
config RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE_OVERRIDDEN
82+
bool
83+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_BUILD_DATE != ""
84+
depends on RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
85+
86+
endif
87+
88+
config RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
89+
bool "Generate program_version_string in binary info"
90+
default y
91+
92+
if RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
93+
94+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_VERSION_STRING
95+
string "Override program_version_string in binary info"
96+
depends on RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
97+
98+
config RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING_OVERRIDDEN
99+
bool
100+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_VERSION_STRING != ""
101+
depends on RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
102+
103+
endif
104+
105+
config RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
106+
bool "Generate sdk_version_string in binary info"
107+
default y
108+
109+
if RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
110+
111+
config RPI_PICO_BINARY_INFO_OVERRIDE_SDK_VERSION_STRING
112+
string "Override sdk_version_string in binary info"
113+
depends on RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
114+
115+
config RPI_PICO_BINARY_INFO_SDK_VERSION_STRING_OVERRIDDEN
116+
bool
117+
default RPI_PICO_BINARY_INFO_OVERRIDE_SDK_VERSION_STRING != ""
118+
depends on RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
119+
120+
endif
121+
122+
config RPI_PICO_BINARY_INFO_PICO_BOARD
123+
bool "Generate pico_board in binary info"
124+
default y
125+
126+
if RPI_PICO_BINARY_INFO_PICO_BOARD
127+
128+
config RPI_PICO_BINARY_INFO_OVERRIDE_PICO_BOARD
129+
string "Override pico_board in binary info"
130+
depends on RPI_PICO_BINARY_INFO_PICO_BOARD
131+
132+
config RPI_PICO_BINARY_INFO_PICO_BOARD_OVERRIDDEN
133+
bool
134+
default RPI_PICO_BINARY_INFO_OVERRIDE_PICO_BOARD != ""
135+
depends on RPI_PICO_BINARY_INFO_PICO_BOARD
136+
137+
endif
138+
139+
config RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
140+
bool "Generate attribute_build_type in binary info"
141+
default y
142+
143+
if RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
144+
145+
config RPI_PICO_BINARY_INFO_OVERRIDE_ATTRIBUTE_BUILD_TYPE
146+
string "Override attribute_build_type in binary info"
147+
depends on RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
148+
149+
config RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE_OVERRIDDEN
150+
bool
151+
default RPI_PICO_BINARY_INFO_OVERRIDE_ATTRIBUTE_BUILD_TYPE != ""
152+
depends on RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
153+
154+
endif
155+
156+
config RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
157+
bool "Generate boot_stage2_name in binary info"
158+
default y
159+
160+
if RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
161+
162+
config RPI_PICO_BINARY_INFO_OVERRIDE_BOOT_STAGE2_NAME
163+
string "Override boot_stage2_name in binary info"
164+
depends on RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
165+
166+
config RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME_OVERRIDDEN
167+
bool
168+
default RPI_PICO_BINARY_INFO_OVERRIDE_BOOT_STAGE2_NAME != ""
169+
depends on RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
170+
171+
endif
172+
173+
config RPI_PICO_BINARY_INFO_PIN_CONFIGURATIONS
174+
bool "Generate pin configuration info in binary info"
175+
default y
176+
177+
endif
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2023 TOKITA Hiroshi <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "binary_info.h"
8+
9+
extern uint32_t __rom_region_end;
10+
bi_decl(bi_binary_end((intptr_t)&__rom_region_end));
11+
12+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_NAME
13+
bi_decl(bi_program_name((uint32_t)BI_PROGRAM_NAME));
14+
#endif
15+
16+
#if defined(CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING)
17+
bi_decl(bi_program_version_string((uint32_t)BI_PROGRAM_VERSION_STRING));
18+
#endif
19+
20+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
21+
bi_decl(bi_program_description((uint32_t)BI_PROGRAM_DESCRIPTION));
22+
#endif
23+
24+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_URL
25+
bi_decl(bi_program_url((uint32_t)BI_PROGRAM_URL));
26+
#endif
27+
28+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
29+
bi_decl(bi_program_build_date_string((uint32_t)BI_PROGRAM_BUILD_DATE));
30+
#endif
31+
32+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PICO_BOARD
33+
bi_decl(bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PICO_BOARD,
34+
(uint32_t)BI_PICO_BOARD));
35+
#endif
36+
37+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
38+
bi_decl(bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_SDK_VERSION,
39+
(uint32_t)BI_SDK_VERSION_STRING));
40+
#endif
41+
42+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
43+
bi_decl(bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_BOOT2_NAME,
44+
(uint32_t)BI_BOOT_STAGE2_NAME));
45+
#endif
46+
47+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
48+
#ifdef CONFIG_DEBUG
49+
bi_decl(bi_program_build_attribute((uint32_t)"Debug"));
50+
#else
51+
bi_decl(bi_program_build_attribute((uint32_t)"Release"));
52+
#endif
53+
#endif
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2025 TOKITA Hiroshi <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_SOC_RASPBERRYPI_RPI_PICO_COMMON_BINARY_INFO_H_
8+
#define ZEPHYR_SOC_RASPBERRYPI_RPI_PICO_COMMON_BINARY_INFO_H_
9+
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/devicetree.h>
12+
#include <zephyr/sys/util_macro.h>
13+
14+
#include <zephyr/dt-bindings/pinctrl/rpi-pico-pinctrl-common.h>
15+
16+
#include <soc.h>
17+
18+
#include <boot_stage2/config.h>
19+
#include <pico/binary_info.h>
20+
21+
#include <version.h>
22+
23+
#define BI_PROGRAM_NAME CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME
24+
#define BI_PROGRAM_DESCRIPTION CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_DESCRIPTION
25+
#define BI_PROGRAM_URL CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_URL
26+
#define BI_PROGRAM_VERSION_STRING CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_VERSION_STRING
27+
28+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PICO_BOARD
29+
#define BI_PICO_BOARD CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PICO_BOARD
30+
#else
31+
#define BI_PICO_BOARD CONFIG_BOARD
32+
#endif
33+
34+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_SDK_VERSION_STRING_OVERRIDDEN
35+
#define BI_SDK_VERSION_STRING CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_SDK_VERSION_STRING
36+
#else
37+
#define BI_SDK_VERSION_STRING "zephyr-" STRINGIFY(BUILD_VERSION)
38+
#endif
39+
40+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE_OVERRIDDEN
41+
#define BI_PROGRAM_BUILD_DATE CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_BUILD_DATE
42+
#else
43+
#define BI_PROGRAM_BUILD_DATE __DATE__
44+
#endif
45+
46+
#ifdef CONFIG_RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
47+
#define BI_BOOT_STAGE2_NAME CONFIG_RPI_PICO_BINARY_INFO_OVERRIDE_BOOT_STAGE2_NAME
48+
#else
49+
#define BI_BOOT_STAGE2_NAME PICO_BOOT_STAGE2_NAME
50+
#endif
51+
52+
/* Utilities for pin encoding calcluation */
53+
54+
#ifdef CONFIG_SOC_RP2040
55+
#define MAX_PIN_ENTRIES 4
56+
#define ENCODE_BASE_IDX 1
57+
#define ENCODE_BYTES 5
58+
#define ENCODE_PADDING 2
59+
#define ENCODE_PINS_WITH_FUNC __bi_encoded_pins_with_func
60+
#else
61+
#define MAX_PIN_ENTRIES 6
62+
#define ENCODE_BASE_IDX 1
63+
#define ENCODE_BYTES 8
64+
#define ENCODE_PADDING 0
65+
#define ENCODE_PINS_WITH_FUNC __bi_encoded_pins_64_with_func
66+
#endif
67+
68+
/* Get group-wide pin functions */
69+
70+
#define PIN_FUNC_OFFSET 3
71+
#define PIN_FUNC(n, _, idx) ((DT_PROP_BY_IDX(n, pinmux, idx)) & RP2_ALT_FUNC_MASK)
72+
#define PIN_GROUP_FUNC(n) (DT_FOREACH_PROP_ELEM_SEP(n, pinmux, PIN_FUNC, (|)))
73+
#define PIN_GROUP_HEADER(n) (BI_PINS_ENCODING_MULTI | (PIN_GROUP_FUNC(n) << PIN_FUNC_OFFSET))
74+
75+
/* Encode the pins in a group */
76+
77+
#define PINMUX_COUNT(n) COND_CODE_1(DT_NODE_HAS_PROP(n, pinmux), (DT_PROP_LEN(n, pinmux)), (0))
78+
#define PIN_NUM(n, idx) (((DT_PROP_BY_IDX(n, pinmux, idx)) >> RP2_PIN_NUM_POS) & RP2_PIN_NUM_MASK)
79+
80+
#define ENCODE_OFFSET(idx) (((idx + ENCODE_BASE_IDX) * ENCODE_BYTES) + ENCODE_PADDING)
81+
#define ENCODE_PIN(n, idx) ((uint64_t)PIN_NUM(n, idx) << ENCODE_OFFSET(idx))
82+
#define ENCODE_TERMINATE(n, i, end) ((((i) + 1) == (end)) ? ENCODE_PIN(n, i + 1) : 0)
83+
#define ENCODE_EACH_PIN(n, p, i, end) \
84+
(DT_PROP_HAS_IDX(n, p, i) ? ENCODE_PIN(n, i) : 0) | ENCODE_TERMINATE(n, i, end)
85+
#define ENCODE_PIN_GROUP(n) \
86+
DT_FOREACH_PROP_ELEM_SEP_VARGS(n, pinmux, ENCODE_EACH_PIN, (|), PINMUX_COUNT(n))
87+
88+
/*
89+
* Macro for checking pin settings
90+
* Checks that a group consists of a single pin-function.
91+
*/
92+
93+
#define PIN_FUNC_IS(n, p, i, func) (PIN_FUNC(n, p, i) == func)
94+
#define ALL_PINS_FUNC_IS_SAME(n) \
95+
(DT_FOREACH_PROP_ELEM_SEP_VARGS(n, pinmux, PIN_FUNC_IS, (&&), PIN_GROUP_FUNC(n)))
96+
97+
/*
98+
* Create binary info for pin-cfg group.
99+
*/
100+
101+
#define DECLARE_PINCFG_GROUP(n) \
102+
BUILD_ASSERT(PINMUX_COUNT(n) > 0, "Group must contain at least one pin"); \
103+
BUILD_ASSERT(PINMUX_COUNT(n) <= MAX_PIN_ENTRIES, "Too many pins in group"); \
104+
BUILD_ASSERT(ALL_PINS_FUNC_IS_SAME(n), "Group pins must share identical function"); \
105+
bi_decl(ENCODE_PINS_WITH_FUNC(PIN_GROUP_HEADER(n) | ENCODE_PIN_GROUP(n)))
106+
107+
/*
108+
* Scan pin-cfg and the groups it contains.
109+
* Each enumerates its child elements, but since the same macro cannot be used within nesting,
110+
* DT_FOREACH_CHILD_VARGS and DT_FOREACH_CHILD_SEP_VARGS are used accordingly.
111+
*/
112+
113+
#define PINMUX_NUM_IF_MATCH_GROUP(node, g_idx) \
114+
COND_CODE_1(IS_EQ(DT_NODE_CHILD_IDX(node), g_idx), (DT_PROP_LEN(node, pinmux)), ())
115+
#define PINMUX_NUM_IF_MATCH_PINCFG(node, pcfg_idx, g_idx) \
116+
COND_CODE_1(IS_EQ(DT_NODE_CHILD_IDX(node), pcfg_idx), \
117+
(DT_FOREACH_CHILD_SEP_VARGS(node, PINMUX_NUM_IF_MATCH_GROUP, (), g_idx)), ())
118+
#define PINMUX_NUM_OF_PINCFG_GROUP(node, pcfg_idx, g_idx) \
119+
DT_FOREACH_CHILD_VARGS(node, PINMUX_NUM_IF_MATCH_PINCFG, pcfg_idx, g_idx)
120+
121+
#define BINARY_INFO_IF_MATCH_GROUP(node, g_idx) \
122+
COND_CODE_1(IS_EQ(DT_NODE_CHILD_IDX(node), g_idx), (DECLARE_PINCFG_GROUP(node)), ())
123+
#define BINARY_INFO_IF_MATCH_PINCFG(node, pcfg_idx, g_idx) \
124+
COND_CODE_1(IS_EQ(DT_NODE_CHILD_IDX(node), pcfg_idx), \
125+
(DT_FOREACH_CHILD_SEP_VARGS(node, BINARY_INFO_IF_MATCH_GROUP, (), g_idx)), ())
126+
#define BINARY_INFO_FROM_PINCFG_GROUP(node, pcfg_idx, g_idx) \
127+
COND_CODE_1(IS_EMPTY(PINMUX_NUM_OF_PINCFG_GROUP(node, pcfg_idx, g_idx)), (), \
128+
(DT_FOREACH_CHILD_VARGS(node, BINARY_INFO_IF_MATCH_PINCFG, pcfg_idx, g_idx)))
129+
130+
#endif /* ZEPHYR_SOC_RASPBERRYPI_RPI_PICO_COMMON_BINARY_INFO_H_ */
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright (c) 2023 TOKITA Hiroshi <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
. = ALIGN(4);
8+
__binary_info_start = .;
9+
KEEP(*(.binary_info.keep.*))
10+
*(.binary_info.*)
11+
__binary_info_end = .;

0 commit comments

Comments
 (0)