Skip to content

Commit 01001fa

Browse files
committed
Add an example of extract and enumerate partition table information
1 parent d2346dd commit 01001fa

File tree

5 files changed

+214
-1
lines changed

5 files changed

+214
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ App|Description
102102
[xip_stream](flash/xip_stream) | Stream data using the XIP stream hardware, which allows data to be DMA'd in the background whilst executing code from flash.
103103
[ssi_dma](flash/ssi_dma) | DMA directly from the flash interface (continuous SCK clocking) for maximum bulk read performance.
104104
[runtime_flash_permissions](flash/runtime_flash_permissions) | Demonstrates adding partitions at runtime to change the flash permissions
105+
[partition_info](flash/partition_info) | Extract and enumerate partition information (address ranges, permissions, IDs, and names) from the partition table.
105106

106107
### FreeRTOS
107108

flash/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ if (TARGET hardware_flash)
55
add_subdirectory_exclude_platforms(ssi_dma "rp2350.*")
66
add_subdirectory_exclude_platforms(xip_stream)
77
add_subdirectory_exclude_platforms(runtime_flash_permissions rp2040)
8+
add_subdirectory_exclude_platforms(partition_info rp2040)
89
else()
910
message("Skipping flash examples as hardware_flash is unavailable on this platform")
10-
endif()
11+
endif()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_executable(partition_info partition_info.c)
2+
target_link_libraries(partition_info PRIVATE
3+
pico_stdlib
4+
pico_bootrom
5+
)
6+
7+
pico_embed_pt_in_binary(partition_info ${CMAKE_CURRENT_LIST_DIR}/pt.json)
8+
pico_enable_stdio_usb(partition_info 1)
9+
pico_add_extra_outputs(partition_info)
10+
example_auto_set_url(partition_info)
11+
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/**
2+
*
3+
* SPDX-License-Identifier: BSD-3-Clause
4+
*/
5+
#include <stdio.h>
6+
#include <pico/stdlib.h>
7+
#include <pico/bootrom.h>
8+
#include "boot/picobin.h"
9+
10+
11+
#define PART_LOC_FIRST(x) ( ((x) & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB )
12+
#define PART_LOC_LAST(x) ( ((x) & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB )
13+
14+
/*
15+
* Stores partition table information and data read status
16+
*/
17+
typedef struct {
18+
int flags;
19+
uint32_t *table;
20+
size_t table_size;
21+
int partition_count;
22+
uint32_t unpartitioned_space_first_sector;
23+
uint32_t unpartitioned_space_last_sector;
24+
uint32_t permission;
25+
int current_partition;
26+
size_t idx;
27+
} pico_partition_t;
28+
29+
/*
30+
* Stores information on each partition
31+
*/
32+
typedef struct {
33+
uint32_t first_sector;
34+
uint32_t last_sector;
35+
uint32_t permission;
36+
uint64_t partition_id;
37+
char name[127 + 1];
38+
} pico_partition_entry_t;
39+
40+
41+
/*
42+
* Read the partition table information.
43+
* See the RP2350 datasheet 5.1.2, 5.4.8.16 for flags and structures that can be specified.
44+
*/
45+
int pico_partitions_open(pico_partition_t *pt, int flags) {
46+
pt->flags = flags;
47+
static __attribute__((aligned(4))) uint32_t workarea[816] = {0};
48+
int rc = rom_get_partition_table_info(workarea, sizeof(workarea), flags);
49+
if (rc < 0) {
50+
return rc;
51+
}
52+
pt->table = workarea;
53+
pt->table_size = rc * 4; // word to bytes
54+
pt->partition_count = ((uint8_t*)workarea)[4];
55+
uint32_t location = workarea[2];
56+
pt->unpartitioned_space_first_sector = PART_LOC_FIRST(location);
57+
pt->unpartitioned_space_last_sector = PART_LOC_LAST(location);
58+
pt->permission = workarea[3];
59+
pt->idx = 4;
60+
pt->current_partition = 0;
61+
62+
return 0;
63+
}
64+
65+
/*
66+
* Parse a partition table and extract information
67+
*/
68+
size_t pico_partitions_parse(pico_partition_t *pt, pico_partition_entry_t *p) {
69+
size_t idx = pt->idx;
70+
if (pt->flags & PT_INFO_PARTITION_LOCATION_AND_FLAGS) {
71+
uint32_t location = pt->table[idx++];
72+
p->first_sector = PART_LOC_FIRST(location);
73+
p->last_sector = PART_LOC_LAST(location);
74+
p->permission = pt->table[idx++];
75+
} else {
76+
p->first_sector = 0;
77+
p->last_sector = 0;
78+
p->permission = 0;
79+
}
80+
81+
if (pt->flags & PT_INFO_PARTITION_ID) {
82+
uint32_t id_low = pt->table[idx++];
83+
uint32_t id_high = pt->table[idx++];
84+
p->partition_id = ((uint64_t)id_high << 32) | id_low;
85+
} else {
86+
p->partition_id = 0;
87+
}
88+
89+
if (pt->flags & PT_INFO_PARTITION_NAME) {
90+
uint8_t *name_field = (uint8_t *)&pt->table[idx];
91+
uint8_t name_length = name_field[0];
92+
uint8_t *name_src = name_field + 1;
93+
memcpy(p->name, name_src, name_length);
94+
p->name[name_length] = '\0';
95+
size_t total_name_bytes = 1 + name_length;
96+
size_t padded_bytes = (total_name_bytes + 3) & ~((size_t)3);
97+
idx += padded_bytes / 4;
98+
} else {
99+
p->name[0] = '\0';
100+
}
101+
return idx;
102+
}
103+
104+
/*
105+
* Extract one partition information
106+
*/
107+
bool pico_partitions_next(pico_partition_t *pt, pico_partition_entry_t *p) {
108+
if (pt->current_partition >= pt->partition_count) {
109+
return false;
110+
}
111+
pt->idx = pico_partitions_parse(pt, p);
112+
pt->current_partition++;
113+
return true;
114+
}
115+
116+
int main() {
117+
stdio_init_all();
118+
119+
pico_partition_t pt;
120+
pico_partitions_open(&pt, PT_INFO_PT_INFO | PT_INFO_PARTITION_LOCATION_AND_FLAGS |
121+
PT_INFO_PARTITION_ID | PT_INFO_PARTITION_NAME);
122+
printf("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s)\n",
123+
(pt.permission & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : ""),
124+
(pt.permission & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : ""),
125+
(pt.permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : ""),
126+
(pt.permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : ""),
127+
(pt.permission & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : ""),
128+
(pt.permission & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : ""));
129+
printf("patitions:\n");
130+
pico_partition_entry_t p;
131+
while (pico_partitions_next(&pt, &p)) {
132+
printf("%3d:", pt.current_partition - 1);
133+
if (pt.flags & PT_INFO_PARTITION_LOCATION_AND_FLAGS) {
134+
printf(" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)",
135+
p.first_sector * 4096, p.last_sector * 4096,
136+
(p.permission & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : ""),
137+
(p.permission & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : ""),
138+
(p.permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : ""),
139+
(p.permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : ""),
140+
(p.permission & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : ""),
141+
(p.permission & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : ""));
142+
143+
}
144+
if (pt.flags & PT_INFO_PARTITION_ID) {
145+
printf(", id=%016llx", p.partition_id);
146+
}
147+
if (pt.flags & PT_INFO_PARTITION_NAME) {
148+
printf(", \"%s\"", p.name);
149+
}
150+
printf("\n");
151+
}
152+
153+
return 0;
154+
}

flash/partition_info/pt.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"version": [1, 0],
3+
"unpartitioned": {
4+
"families": ["absolute"],
5+
"permissions": {
6+
"secure": "rw",
7+
"nonsecure": "rw",
8+
"bootloader": "rw"
9+
}
10+
},
11+
"partitions": [
12+
{
13+
"name": "Firmware",
14+
"id": 1,
15+
"size": "512K",
16+
"families": ["rp2350-arm-s", "rp2350-riscv"],
17+
"permissions": {
18+
"secure": "rw",
19+
"nonsecure": "rw",
20+
"bootloader": "rw"
21+
}
22+
},
23+
{
24+
"name": "Data",
25+
"id": 2,
26+
"size": "512K",
27+
"families": ["rp2350-arm-s", "rp2350-riscv"],
28+
"permissions": {
29+
"secure": "rw",
30+
"nonsecure": "rw",
31+
"bootloader": "rw"
32+
}
33+
},
34+
{
35+
"name": "Read only Data",
36+
"id": 3,
37+
"size": "512K",
38+
"families": ["rp2350-arm-s", "rp2350-riscv"],
39+
"permissions": {
40+
"secure": "r",
41+
"nonsecure": "r",
42+
"bootloader": "r"
43+
}
44+
}
45+
]
46+
}

0 commit comments

Comments
 (0)