Skip to content

Add pico_low_power library#2852

Draft
will-v-pi wants to merge 96 commits intoraspberrypi:developfrom
will-v-pi:low-power-new
Draft

Add pico_low_power library#2852
will-v-pi wants to merge 96 commits intoraspberrypi:developfrom
will-v-pi:low-power-new

Conversation

@will-v-pi
Copy link
Copy Markdown
Contributor

@will-v-pi will-v-pi commented Mar 6, 2026

This adds a pico_low_power library, which allows going to sleep, dormant, and powman pstates.

Also adds bitsets and hardware_rosc, to support the low power stuff.

Includes a possible fix for #2420 to get the bazel rp2040 clang build working

Requires the include linker scripts in #2841, so will need rebasing once those are merged

Also requires raspberrypi/picotool#298 when putting persistent data in XIP SRAM

See low_power.h for documentation

will-v-pi added 15 commits March 6, 2026 15:29
Allows for much simpler custom linker scripts
…ript_var variables

Means that CMake doesn't need to know the default memory addresses for different platforms
…l files easier

Restructured so that it includes the platform-specific files before common ones, so common ones can be overridden
Use new include_linker_script_dir and use_linker_script_file functions to add the linker arguments
Breaking change for Bazel builds using different binary types, instead of setting PICO_DEFAULT_LINKER_SCRIPT to eg `//src/rp2_common/pico_crt0:no_flash_linker_script` it is now `//src/rp2_common/pico_standard_link:no_flash_linker_script`
Treat rp2040 layout (boot2 instead of embedded blocks) as the outlier

static inline generic_bitset_t *bitset_write_word(generic_bitset_t *bitset, uint word_num, uint32_t value) {
check_bitset(bitset);
if (word_num < bitset_word_size(bitset)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this raise an error if word_num >= bitset_word_size(bitset) ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a question for @kilograham, but given that the other functions don't throw any errors when you attempt to pass a value that is outside the range and just return 0/do nothing, I think this one should also not throw an error?

uint rosc_find_freq_mhz(uint32_t low_mhz, uint32_t high_mhz) {
// TODO: This could be a lot better
rosc_set_div(1);
for (uint32_t code = 0; code <= 0x77777777u; code = next_rosc_code(code)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goodness that's a large search space 😂

Add PICO_LINKER_SCRIPT_INCLUDE_DIRS and PICO_LINKER_DEFAULT_LOCATIONS_PATH, instead of hardcoded paths under PICO_LINKER_SCRIPT_PATH

Also improve pico_set_linker_script_var and pico_add_linker_script_override_path to better utilise generator expressions
Required changes to the way bazel views these files
…d sections_... which contain multiple

Only exceptions are section_..._data and section_bss, as these contain data/bss and tdata/tbss - these are kept together as they are treated as a single section
Comment on lines +215 to +230
typedef uint32_t tiny_encoded_bitset_t;
typedef uint64_t encoded_bitset_t;

#define encoded_bitset_empty() 0
#define encoded_bitset_of1(v) (1u | ((v) << 8))
#define encoded_bitset_of2(v1, v2) (2u | ((v1) << 8) | ((v2) << 16))
#define encoded_bitset_of3(v1, v2, v3) (3u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)))
#define encoded_bitset_of4(v1, v2, v3, v4) (4u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)(v4)) << 32))
#define encoded_bitset_of5(v1, v2, v3, v4, v5) (5u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)((v4) | ((v5)<<8u))) << 32))

#define encoded_bitset_foreach(bitset, x) ({ \
for(uint _i=0;_i<((bitset)&0xffu);_i++) { \
uint bit = (uint8_t)((bitset) >> (8 * _i)); \
x; \
} \
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT it looks like this encoded_bitset stuff is only used in kitchen_sink.c, so maybe it's not actually needed? 🤷

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’ll be a question for @kilograham

will-v-pi and others added 16 commits March 19, 2026 14:44
…ink_libraries, as it uses generator expressions

Also add more checks to kitchen_sink
Intended for platform specific overrides, whereas post_end is for cross-platform overrides, similar to section_end vs section_platform_end
Existing method of just setting the linker script didn't work, because the PICO_NO_FLASH/PICO_COPY_TO_RAM define was only available in pico_platform, but needed to be propogated to things that only use pico_base_headers
…e for individual binaries

Can remove full no_flash etc test builds, as there can now be kitchen_sink_no_flash etc builds like in CMake
Now uses single linker_scripts function to allow both including and linking scripts

Returns DefaultInfo with all necessary files

Prepends ctx.label.workspace_root to link_include_dir

Gets link_include_dir directly from the include_scripts passed in
… bazel

Also adds pico_set_linker_script transition to set linker script for individual binaries
Remove whitespace, and rename memory_aliases_default to memory_aliases_flash, as it applies to copy_to_ram too
Commits on this branch are very messy due to being on top of changing linker scripts, so definitely need squashing before final merge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants