Skip to content

Commit 51c15c5

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" ``` Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 861bdfd commit 51c15c5

File tree

9 files changed

+1522
-0
lines changed

9 files changed

+1522
-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: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
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+
if RPI_PICO_BINARY_INFO
13+
14+
config RPI_PICO_BINARY_INFO_PROGRAM_NAME
15+
bool "Generate program_name in binary info"
16+
default y
17+
18+
if RPI_PICO_BINARY_INFO_PROGRAM_NAME
19+
20+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME
21+
string "Override program_name in binary info"
22+
depends on RPI_PICO_BINARY_INFO_PROGRAM_NAME
23+
24+
config RPI_PICO_BINARY_INFO_PROGRAM_NAME_OVERRIDDEN
25+
bool
26+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_NAME != ""
27+
depends on RPI_PICO_BINARY_INFO_PROGRAM_NAME
28+
29+
endif
30+
31+
config RPI_PICO_BINARY_INFO_PROGRAM_URL
32+
bool "Generate program_url in binary info"
33+
default y
34+
35+
if RPI_PICO_BINARY_INFO_PROGRAM_URL
36+
37+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_URL
38+
string "Override program_url in binary info"
39+
depends on RPI_PICO_BINARY_INFO_PROGRAM_URL
40+
41+
config RPI_PICO_BINARY_INFO_PROGRAM_URL_OVERRIDDEN
42+
bool
43+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_URL != ""
44+
depends on RPI_PICO_BINARY_INFO_PROGRAM_URL
45+
46+
endif
47+
48+
config RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
49+
bool "Generate program_description in binary info"
50+
default y
51+
52+
if RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
53+
54+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_DESCRIPTION
55+
string "Override program_description in binary info"
56+
depends on RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
57+
58+
config RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION_OVERRIDDEN
59+
bool
60+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_DESCRIPTION != ""
61+
depends on RPI_PICO_BINARY_INFO_PROGRAM_DESCRIPTION
62+
63+
endif
64+
65+
config RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
66+
bool "Generate program_build_date in binary info"
67+
default y
68+
69+
if RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
70+
71+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_BUILD_DATE
72+
string "Override program_build_date in binary info"
73+
depends on RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
74+
75+
config RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE_OVERRIDDEN
76+
bool
77+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_BUILD_DATE != ""
78+
depends on RPI_PICO_BINARY_INFO_PROGRAM_BUILD_DATE
79+
80+
endif
81+
82+
config RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
83+
bool "Generate program_version_string in binary info"
84+
default y
85+
86+
if RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
87+
88+
config RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_VERSION_STRING
89+
string "Override program_version_string in binary info"
90+
depends on RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
91+
92+
config RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING_OVERRIDDEN
93+
bool
94+
default RPI_PICO_BINARY_INFO_OVERRIDE_PROGRAM_VERSION_STRING != ""
95+
depends on RPI_PICO_BINARY_INFO_PROGRAM_VERSION_STRING
96+
97+
endif
98+
99+
config RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
100+
bool "Generate sdk_version_string in binary info"
101+
default y
102+
103+
if RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
104+
105+
config RPI_PICO_BINARY_INFO_OVERRIDE_SDK_VERSION_STRING
106+
string "Override sdk_version_string in binary info"
107+
depends on RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
108+
109+
config RPI_PICO_BINARY_INFO_SDK_VERSION_STRING_OVERRIDDEN
110+
bool
111+
default RPI_PICO_BINARY_INFO_OVERRIDE_SDK_VERSION_STRING != ""
112+
depends on RPI_PICO_BINARY_INFO_SDK_VERSION_STRING
113+
114+
endif
115+
116+
config RPI_PICO_BINARY_INFO_PICO_BOARD
117+
bool "Generate pico_board in binary info"
118+
default y
119+
120+
if RPI_PICO_BINARY_INFO_PICO_BOARD
121+
122+
config RPI_PICO_BINARY_INFO_OVERRIDE_PICO_BOARD
123+
string "Override pico_board in binary info"
124+
depends on RPI_PICO_BINARY_INFO_PICO_BOARD
125+
126+
config RPI_PICO_BINARY_INFO_PICO_BOARD_OVERRIDDEN
127+
bool
128+
default RPI_PICO_BINARY_INFO_OVERRIDE_PICO_BOARD != ""
129+
depends on RPI_PICO_BINARY_INFO_PICO_BOARD
130+
131+
endif
132+
133+
config RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
134+
bool "Generate attribute_build_type in binary info"
135+
default y
136+
137+
if RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
138+
139+
config RPI_PICO_BINARY_INFO_OVERRIDE_ATTRIBUTE_BUILD_TYPE
140+
string "Override attribute_build_type in binary info"
141+
depends on RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
142+
143+
config RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE_OVERRIDDEN
144+
bool
145+
default RPI_PICO_BINARY_INFO_OVERRIDE_ATTRIBUTE_BUILD_TYPE != ""
146+
depends on RPI_PICO_BINARY_INFO_ATTRIBUTE_BUILD_TYPE
147+
148+
endif
149+
150+
config RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
151+
bool "Generate boot_stage2_name in binary info"
152+
default y
153+
154+
if RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
155+
156+
config RPI_PICO_BINARY_INFO_OVERRIDE_BOOT_STAGE2_NAME
157+
string "Override boot_stage2_name in binary info"
158+
depends on RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
159+
160+
config RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME_OVERRIDDEN
161+
bool
162+
default RPI_PICO_BINARY_INFO_OVERRIDE_BOOT_STAGE2_NAME != ""
163+
depends on RPI_PICO_BINARY_INFO_BOOT_STAGE2_NAME
164+
165+
endif
166+
167+
config RPI_PICO_BINARY_INFO_PIN_CONFIGURATIONS
168+
bool "Generate pin configuration info in binary info"
169+
default y
170+
171+
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)