Skip to content

feat(params): add board-level read-only parameter support#26522

Open
julianoes wants to merge 1 commit intomainfrom
pr-readonly-params
Open

feat(params): add board-level read-only parameter support#26522
julianoes wants to merge 1 commit intomainfrom
pr-readonly-params

Conversation

@julianoes
Copy link
Copy Markdown
Contributor

Integrators can declare read-only parameters in a per-board YAML file: readonly_params.yaml.

There are two ways to define the read-only params:

  • "block": default writable, explicitly list params to be locked
  • "allow": default readonly, explicitly list params to be writable

Enforcement is activated by param lock in rcS after all startup scripts have run, so board defaults and airframe scripts can still set params during init.

The feedback via MAVLink uses the new
MAV_PARAM_ERROR_READ_ONLY as part of the PARAM_ERROR message.

This also includes an extension to param show:

nsh> param show -l
Symbols: x = used, + = saved, * = unsaved, l = locked
x + l BAT1_N_CELLS [6,37] : 2

Closes #12429.
Closes #14493.

@github-actions
Copy link
Copy Markdown

No broken links found in changed files.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 18, 2026

🔎 FLASH Analysis

px4_fmu-v5x [Total VM Diff: 416 byte (0.02 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.0%    +416  +0.0%    +416    .text
  +0.1%    +152  +0.1%    +152    [section .text]
  +4.9%     +92  +4.9%     +92    param_main
  [NEW]     +60  [NEW]     +60    CSWTCH.1971
  [NEW]     +44  [NEW]     +44    CSWTCH.2766
  +3.4%     +44  +3.4%     +44    MavlinkParametersManager::handle_message()
  [NEW]     +28  [NEW]     +28    do_show_print_locked()
  +5.7%     +20  +5.7%     +20    do_set()
  +9.6%     +20  +9.6%     +20    do_set_custom_default()
  +7.6%     +20  +7.6%     +20    do_show_index()
  +6.5%     +20  +6.5%     +20    do_show_print()
  [NEW]     +14  [NEW]     +14    CSWTCH.3534
  +0.0%     +12  +0.0%     +12    g_cromfs_image
  +4.8%      +4  +4.8%      +4    FlightTask
  [NEW]      +4  [NEW]      +4    param_is_readonly
  [NEW]      +4  [NEW]      +4    param_lock_readonly
  -2.0%      -4  -2.0%      -4    MavlinkReceiver::handle_message_att_pos_mocap()
  [DEL]     -14  [DEL]     -14    CSWTCH.3532
  [DEL]     -44  [DEL]     -44    CSWTCH.2765
  [DEL]     -60  [DEL]     -60    CSWTCH.1970
+0.1% +2.26Ki  [ = ]       0    .debug_abbrev
+0.0%     +24  [ = ]       0    .debug_aranges
+0.0%     +76  [ = ]       0    .debug_frame
+0.0% +9.55Ki  [ = ]       0    .debug_info
+0.0%    +115  [ = ]       0    .debug_line
  +400%      +4  [ = ]       0    [Unmapped]
  +0.0%    +111  [ = ]       0    [section .debug_line]
+0.0%    +133  [ = ]       0    .debug_loclists
+0.0%     +18  [ = ]       0    .debug_rnglists
   +50%      +1  [ = ]       0    [Unmapped]
  +0.0%     +17  [ = ]       0    [section .debug_rnglists]
+0.0%    +109  [ = ]       0    .debug_str
+0.4%      +1  [ = ]       0    .shstrtab
+0.0%     +67  [ = ]       0    .strtab
  [DEL]     -12  [ = ]       0    CSWTCH.1970
  [NEW]     +12  [ = ]       0    CSWTCH.1971
  [DEL]     -12  [ = ]       0    CSWTCH.2765
  [NEW]     +12  [ = ]       0    CSWTCH.2766
  [DEL]     -24  [ = ]       0    CSWTCH.3532
  [NEW]     +24  [ = ]       0    CSWTCH.3534
 -44.4%     -16  [ = ]       0    __nxsem_wait_veneer
   +67%     +16  [ = ]       0    __stm32_dmastart_veneer
  [NEW]     +29  [ = ]       0    do_show_print_locked()
  [NEW]     +18  [ = ]       0    param_is_readonly
  [NEW]     +20  [ = ]       0    param_lock_readonly
+0.0%     +96  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.1970
  [NEW]     +32  [ = ]       0    CSWTCH.1971
  [DEL]     -32  [ = ]       0    CSWTCH.2765
  [NEW]     +32  [ = ]       0    CSWTCH.2766
  [DEL]     -48  [ = ]       0    CSWTCH.3532
  [NEW]     +48  [ = ]       0    CSWTCH.3534
  +0.3%     +32  [ = ]       0    [section .symtab]
 -25.0%     -16  [ = ]       0    __arp_ipin_veneer
 -40.0%     -32  [ = ]       0    __nxsem_wait_veneer
   +67%     +32  [ = ]       0    __stm32_dmastart_veneer
   +33%     +16  [ = ]       0    __stm32_i2c_set_bytes_to_transfer_veneer
  [NEW]     +32  [ = ]       0    do_show_print_locked()
 -25.0%     -16  [ = ]       0    param_get_system_default_value
  [NEW]     +48  [ = ]       0    param_is_readonly
  [NEW]     +16  [ = ]       0    param_lock_readonly
 -33.3%     -16  [ = ]       0    px4::parameters_volatile
-3.5%    -416  [ = ]       0    [Unmapped]
+0.0% +12.4Ki  +0.0%    +416    TOTAL

px4_fmu-v6x [Total VM Diff: 416 byte (0.02 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.0%    +416  +0.0%    +416    .text
  +0.1%    +152  +0.1%    +152    [section .text]
  +4.9%     +92  +4.9%     +92    param_main
  [NEW]     +60  [NEW]     +60    CSWTCH.1971
  [NEW]     +44  [NEW]     +44    CSWTCH.2766
  +3.4%     +44  +3.4%     +44    MavlinkParametersManager::handle_message()
  [NEW]     +28  [NEW]     +28    do_show_print_locked()
  +5.7%     +20  +5.7%     +20    do_set()
  +9.6%     +20  +9.6%     +20    do_set_custom_default()
  +7.6%     +20  +7.6%     +20    do_show_index()
  +6.5%     +20  +6.5%     +20    do_show_print()
  [NEW]     +14  [NEW]     +14    CSWTCH.3534
  +0.0%     +12  +0.0%     +12    g_cromfs_image
  +4.8%      +4  +4.8%      +4    FlightTask
  [NEW]      +4  [NEW]      +4    param_is_readonly
  [NEW]      +4  [NEW]      +4    param_lock_readonly
  -2.0%      -4  -2.0%      -4    MavlinkReceiver::handle_message_att_pos_mocap()
  [DEL]     -14  [DEL]     -14    CSWTCH.3532
  [DEL]     -44  [DEL]     -44    CSWTCH.2765
  [DEL]     -60  [DEL]     -60    CSWTCH.1970
+0.1% +2.17Ki  [ = ]       0    .debug_abbrev
+0.0%     +24  [ = ]       0    .debug_aranges
+0.0%     +76  [ = ]       0    .debug_frame
+0.0% +9.19Ki  [ = ]       0    .debug_info
+0.0%    +105  [ = ]       0    .debug_line
  [DEL]      -4  [ = ]       0    [Unmapped]
  +0.0%    +109  [ = ]       0    [section .debug_line]
+0.0%    +165  [ = ]       0    .debug_loclists
+0.0%     +18  [ = ]       0    .debug_rnglists
   +50%      +1  [ = ]       0    [Unmapped]
  +0.0%     +17  [ = ]       0    [section .debug_rnglists]
+0.0%    +109  [ = ]       0    .debug_str
+0.4%      +1  [ = ]       0    .shstrtab
+0.0%     +67  [ = ]       0    .strtab
  [DEL]     -12  [ = ]       0    CSWTCH.1970
  [NEW]     +12  [ = ]       0    CSWTCH.1971
  [DEL]     -12  [ = ]       0    CSWTCH.2765
  [NEW]     +12  [ = ]       0    CSWTCH.2766
  [DEL]     -24  [ = ]       0    CSWTCH.3532
  [NEW]     +24  [ = ]       0    CSWTCH.3534
  [NEW]     +29  [ = ]       0    do_show_print_locked()
  [NEW]     +18  [ = ]       0    param_is_readonly
  [NEW]     +20  [ = ]       0    param_lock_readonly
+0.0%     +96  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.1970
  [NEW]     +32  [ = ]       0    CSWTCH.1971
  [DEL]     -32  [ = ]       0    CSWTCH.2765
  [NEW]     +32  [ = ]       0    CSWTCH.2766
  [DEL]     -48  [ = ]       0    CSWTCH.3532
  [NEW]     +48  [ = ]       0    CSWTCH.3534
  [NEW]     +32  [ = ]       0    do_show_print_locked()
  [NEW]     +48  [ = ]       0    param_is_readonly
  [NEW]     +16  [ = ]       0    param_lock_readonly
-6.1%    -416  [ = ]       0    [Unmapped]
+0.0% +12.0Ki  +0.0%    +416    TOTAL

Updated: 2026-04-08T18:51:26

Copy link
Copy Markdown
Contributor

@hamishwillee hamishwillee left a comment

Choose a reason for hiding this comment

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

Docs are great, but we really need the read-only field to be injected into parameter metadata so that a GCS doesn't have to try to read it, and doesn't offer the option. Once it is in the metadata I can also read it.

You'd have to update src/lib/parameters/px_generate_params.py‎ to add a new property like the following to generated parameters.

 * @read-only True

We can then update the src parser and markdown out exc to generate appropriate XML and markdown.

@julianoes
Copy link
Copy Markdown
Contributor Author

Ah yes, we can add that.

@hamishwillee
Copy link
Copy Markdown
Contributor

Ah yes, we can add that.

If you can add to the generated params stuff I can fix up the markdown output.

dakejahl
dakejahl previously approved these changes Feb 19, 2026
Copy link
Copy Markdown
Contributor

@dakejahl dakejahl left a comment

Choose a reason for hiding this comment

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

Amazing!

@julianoes
Copy link
Copy Markdown
Contributor Author

@hamishwillee is this ok?

image

QGC PR: mavlink/qgroundcontrol#14007

If you can add to the generated params stuff I can fix up the markdown output.

What do you mean exactly?

@hamishwillee
Copy link
Copy Markdown
Contributor

@hamishwillee is this ok?

To my mind the QGC change would be that the read only parameters

  • would be shown with some visual difference in lists - i.e. different than ones that can be edited and ones that have been edited (shown in red). Usually you'd do something like this with a little icon - you can't use grey because that means disabled.
  • In popup would have something very clear to indicate that they are read only. Again, I'd tend to use a lock icon or similar.

I can't see what you have done in the background list, and to me an icon or colour change would be much more visually obvious than this text.

So yes, this is OK, but would prefer optimal.

What do you mean exactly?

I mean for the parameter metadata rendering in docs the readonly information needs to be captured in the parameter source parser. You must have done this though or you wouldn't be able to generate parameters.xml.

So what I am saying is that once this merges, I can take on the update to generate the updates to the documentation. Unless you want to do that.

@ryanjAA
Copy link
Copy Markdown
Contributor

ryanjAA commented Feb 19, 2026

This is so good!

@julianoes
Copy link
Copy Markdown
Contributor Author

would be shown with some visual difference in lists

Yeah, I can try that.

I mean for the parameter metadata rendering in docs the readonly information needs to be captured in the parameter source parser.

I think it's just ignored. There are no locked parameters for the upstream version, so this really only applies to integrator forks that would use it.

@julianoes
Copy link
Copy Markdown
Contributor Author

julianoes commented Feb 20, 2026

@hamishwillee something like this?

image

@hamishwillee
Copy link
Copy Markdown
Contributor

@julianoes Yes - that's what I was thinking. Lovely.

@mrpollo
Copy link
Copy Markdown
Contributor

mrpollo commented Feb 22, 2026

Whats missing here? it would be nice to get this merged, cool feature

@julianoes
Copy link
Copy Markdown
Contributor Author

The one thing I should check is how/if this conflicts with ArduPilot, mostly concerning the QGC side. I wasn't aware of the fact that they already have it, or something like it.

@dakejahl
Copy link
Copy Markdown
Contributor

dakejahl commented Apr 2, 2026

Did we get the QGC side figured out? I think this is a great feature and would love to get it in.

@julianoes
Copy link
Copy Markdown
Contributor Author

Looking into what is going on now.

@julianoes julianoes force-pushed the pr-readonly-params branch from ff4699c to 50d2442 Compare April 8, 2026 18:43
@julianoes julianoes changed the title params: add board-level read-only parameter support feat(params): add board-level read-only parameter support Apr 8, 2026
Integrators can declare read-only parameters in a per-board YAML file:
readonly_params.yaml.

There are two ways to define the read-only params:
- "block": default writable, explicitly list params to be locked
- "allow": default readonly, explicitly list params to be writable

Enforcement is activated by `param lock` in rcS after all startup
scripts have run, so board defaults and airframe scripts can still set
params during init.

The feedback via MAVLink uses the new
MAV_PARAM_ERROR_READ_ONLY as part of the PARAM_ERROR message.
@julianoes julianoes force-pushed the pr-readonly-params branch from 50d2442 to ccb86d1 Compare April 14, 2026 22:18
@github-actions
Copy link
Copy Markdown

🔎 FLASH Analysis

px4_fmu-v5x [Total VM Diff: 416 byte (0.02 %)]
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +416  +0.0%    +416    .text
    +0.1%    +160  +0.1%    +160    [section .text]
    +4.9%     +92  +4.9%     +92    param_main
    [NEW]     +60  [NEW]     +60    CSWTCH.1971
    [NEW]     +44  [NEW]     +44    CSWTCH.2768
    +3.4%     +44  +3.4%     +44    MavlinkParametersManager::handle_message()
    [NEW]     +28  [NEW]     +28    do_show_print_locked()
    +5.7%     +20  +5.7%     +20    do_set()
    +9.6%     +20  +9.6%     +20    do_set_custom_default()
    +7.6%     +20  +7.6%     +20    do_show_index()
    +6.5%     +20  +6.5%     +20    do_show_print()
    [NEW]     +14  [NEW]     +14    CSWTCH.3532
    +0.0%      +8  +0.0%      +8    g_cromfs_image
    [NEW]      +4  [NEW]      +4    param_is_readonly
    [NEW]      +4  [NEW]      +4    param_lock_readonly
    -2.0%      -4  -2.0%      -4    MavlinkReceiver::handle_message_att_pos_mocap()
    [DEL]     -14  [DEL]     -14    CSWTCH.3530
    [DEL]     -44  [DEL]     -44    CSWTCH.2767
    [DEL]     -60  [DEL]     -60    CSWTCH.1970
  +0.1% +2.25Ki  [ = ]       0    .debug_abbrev
  +0.0%     +24  [ = ]       0    .debug_aranges
  +0.0%     +76  [ = ]       0    .debug_frame
  +0.0% +9.51Ki  [ = ]       0    .debug_info
  +0.0%    +106  [ = ]       0    .debug_line
   -83.3%      -5  [ = ]       0    [Unmapped]
    +0.0%    +111  [ = ]       0    [section .debug_line]
  +0.0%    +200  [ = ]       0    .debug_loclists
  +0.0%     +15  [ = ]       0    .debug_rnglists
    [DEL]      -2  [ = ]       0    [Unmapped]
    +0.0%     +17  [ = ]       0    [section .debug_rnglists]
  +0.0%    +109  [ = ]       0    .debug_str
  +0.4%      +1  [ = ]       0    .shstrtab
  +0.0%     +67  [ = ]       0    .strtab
    [DEL]     -12  [ = ]       0    CSWTCH.1970
    [NEW]     +12  [ = ]       0    CSWTCH.1971
    [DEL]     -12  [ = ]       0    CSWTCH.2767
    [NEW]     +12  [ = ]       0    CSWTCH.2768
    [DEL]     -24  [ = ]       0    CSWTCH.3530
    [NEW]     +24  [ = ]       0    CSWTCH.3532
     +36%     +16  [ = ]       0    ___ZL19param_get_cplusplustPf.isra.0_veneer
   -18.0%     -16  [ = ]       0    ___ZN7sensors22VehicleAngularVelocity21FilterAngularVelocityEiPfi_veneer
    [NEW]     +29  [ = ]       0    do_show_print_locked()
    [NEW]     +18  [ = ]       0    param_is_readonly
    [NEW]     +20  [ = ]       0    param_lock_readonly
  +0.0%     +96  [ = ]       0    .symtab
    [DEL]     -32  [ = ]       0    CSWTCH.1970
    [NEW]     +32  [ = ]       0    CSWTCH.1971
    [DEL]     -32  [ = ]       0    CSWTCH.2767
    [NEW]     +32  [ = ]       0    CSWTCH.2768
    [DEL]     -48  [ = ]       0    CSWTCH.3530
    [NEW]     +48  [ = ]       0    CSWTCH.3532
    +0.3%     +32  [ = ]       0    [section .symtab]
     +17%     +32  [ = ]       0    ___ZL19param_get_cplusplustPf.isra.0_veneer
   -40.0%     -32  [ = ]       0    ___ZN7sensors22VehicleAngularVelocity21FilterAngularVelocityEiPfi_veneer
    [NEW]     +32  [ = ]       0    do_show_print_locked()
   -25.0%     -16  [ = ]       0    param_get_system_default_value
    [NEW]     +48  [ = ]       0    param_is_readonly
    [NEW]     +16  [ = ]       0    param_lock_readonly
   -33.3%     -16  [ = ]       0    px4::parameters_volatile
  -3.5%    -416  [ = ]       0    [Unmapped]
  +0.0% +12.4Ki  +0.0%    +416    TOTAL

px4_fmu-v6x [Total VM Diff: 416 byte (0.02 %)]
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +416  +0.0%    +416    .text
    +0.1%    +160  +0.1%    +160    [section .text]
    +4.9%     +92  +4.9%     +92    param_main
    [NEW]     +60  [NEW]     +60    CSWTCH.1971
    [NEW]     +44  [NEW]     +44    CSWTCH.2768
    +3.4%     +44  +3.4%     +44    MavlinkParametersManager::handle_message()
    [NEW]     +28  [NEW]     +28    do_show_print_locked()
    +5.7%     +20  +5.7%     +20    do_set()
    +9.6%     +20  +9.6%     +20    do_set_custom_default()
    +7.6%     +20  +7.6%     +20    do_show_index()
    +6.5%     +20  +6.5%     +20    do_show_print()
    [NEW]     +14  [NEW]     +14    CSWTCH.3532
    +0.0%     +12  +0.0%     +12    g_cromfs_image
    [NEW]      +4  [NEW]      +4    param_is_readonly
    [NEW]      +4  [NEW]      +4    param_lock_readonly
    -4.5%      -4  -4.5%      -4    FlightTask
    -2.0%      -4  -2.0%      -4    MavlinkReceiver::handle_message_att_pos_mocap()
    [DEL]     -14  [DEL]     -14    CSWTCH.3530
    [DEL]     -44  [DEL]     -44    CSWTCH.2767
    [DEL]     -60  [DEL]     -60    CSWTCH.1970
  +0.1% +2.16Ki  [ = ]       0    .debug_abbrev
  +0.0%     +24  [ = ]       0    .debug_aranges
  +0.0%     +76  [ = ]       0    .debug_frame
  +0.0% +9.15Ki  [ = ]       0    .debug_info
  +0.0%    +113  [ = ]       0    .debug_line
    +100%      +3  [ = ]       0    [Unmapped]
    +0.0%    +110  [ = ]       0    [section .debug_line]
  +0.0%    +214  [ = ]       0    .debug_loclists
  +0.0%     +17  [ = ]       0    .debug_rnglists
  +0.0%    +109  [ = ]       0    .debug_str
  -1.3%      -3  [ = ]       0    .shstrtab
  +0.0%     +67  [ = ]       0    .strtab
    [DEL]     -12  [ = ]       0    CSWTCH.1970
    [NEW]     +12  [ = ]       0    CSWTCH.1971
    [DEL]     -12  [ = ]       0    CSWTCH.2767
    [NEW]     +12  [ = ]       0    CSWTCH.2768
    [DEL]     -24  [ = ]       0    CSWTCH.3530
    [NEW]     +24  [ = ]       0    CSWTCH.3532
    [NEW]     +29  [ = ]       0    do_show_print_locked()
    [NEW]     +18  [ = ]       0    param_is_readonly
    [NEW]     +20  [ = ]       0    param_lock_readonly
  +0.0%     +96  [ = ]       0    .symtab
    [DEL]     -32  [ = ]       0    CSWTCH.1970
    [NEW]     +32  [ = ]       0    CSWTCH.1971
    [DEL]     -32  [ = ]       0    CSWTCH.2767
    [NEW]     +32  [ = ]       0    CSWTCH.2768
    [DEL]     -48  [ = ]       0    CSWTCH.3530
    [NEW]     +48  [ = ]       0    CSWTCH.3532
    [NEW]     +32  [ = ]       0    do_show_print_locked()
    [NEW]     +48  [ = ]       0    param_is_readonly
    [NEW]     +16  [ = ]       0    param_lock_readonly
   +92% +3.59Ki  [ = ]       0    [Unmapped]
  +0.0% +16.0Ki  +0.0%    +416    TOTAL

Updated: 2026-04-14T22:24:55

@github-actions
Copy link
Copy Markdown

No broken links found in changed files.

Copy link
Copy Markdown
Contributor

@hamishwillee hamishwillee left a comment

Choose a reason for hiding this comment

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

Approving for the docs part. The mavlink bits look good too, but I haven't tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parameter Protection Parameter locking / classifiication to prevent accidental reset

5 participants