Skip to content

fix bug # add AT32-F435 sram config - #11774

Open
sunyanmeng963 wants to merge 1 commit into
iNavFlight:masterfrom
sunyanmeng963:AT32F435_SRAM_CONFIG
Open

fix bug # add AT32-F435 sram config#11774
sunyanmeng963 wants to merge 1 commit into
iNavFlight:masterfrom
sunyanmeng963:AT32F435_SRAM_CONFIG

Conversation

@sunyanmeng963

Copy link
Copy Markdown
Contributor

No description provided.

@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@github-actions

Copy link
Copy Markdown

Branch Targeting Suggestion

You've targeted the master branch with this PR. Please consider if a version branch might be more appropriate:

  • maintenance-9.x - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.

  • maintenance-10.x - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x

If master is the correct target for this change, no action is needed.


This is an automated suggestion to help route contributions to the appropriate branch.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Fix AT32F435 SRAM sizing by initializing flash USD EOPB0 config

🐞 Bug fix ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add runtime SRAM configuration selection based on linker-provided SRAM size.
• Ensure USD EOPB0 SRAM config matches target, reprogram and reset if mismatched.
• Set BLUEBERRYF435WING flash size and define default SRAM size in F43x linker scripts.
Diagram

graph TD
  L["Linker: _SRAM_SIZE"] --> S["get_sram_config()"] --> I["init_sram_config()"] --> D{"USD EOPB0 matches?"}
  D -->|"yes"| B["systemInit() continue"]
  D -->|"no"| F["flash unlock/erase/config"] --> U[("USD EOPB0")] --> R["systemReset()"]
  T["target.h: TARGET_FLASH_SIZE"] --> S

  subgraph Legend
    direction LR
    _p["Process"] ~~~ _d{"Decision"} ~~~ _r[("Register/Nonvolatile")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Compile-time only SRAM config (no USD rewrite)
  • ➕ Avoids flash USD erase/write during boot, reducing risk of boot loops and flash wear
  • ➕ Simpler runtime behavior; fewer failure modes
  • ➖ Does not correct boards already shipped/misconfigured in USD
  • ➖ Requires manual flashing/programming steps to fix SRAM config
2. One-time migration with marker/versioning in USD
  • ➕ Still self-heals misconfigured devices while avoiding repeated erase/write attempts
  • ➕ Can guard against reset loops if config write fails
  • ➖ Requires allocating/defining a persistent marker and handling upgrade logic
  • ➖ Slightly more code and validation effort
3. Fail-safe: attempt config once, then continue with warning
  • ➕ Prevents hard reset loops if USD cannot be updated (locked, brown-out, etc.)
  • ➕ Improves field robustness
  • ➖ System may run with incorrect SRAM layout leading to subtle memory corruption
  • ➖ Requires reliable logging/telemetry channel early in boot

Recommendation: Current self-healing approach is reasonable for ensuring SRAM layout correctness, but consider adding a fail-safe to prevent indefinite reset loops if USD programming fails (e.g., only attempt once per power cycle or add a migration marker). Also ensure the USD mask/mapping is validated against all supported TARGET_FLASH_SIZE variants so the comparison cannot false-trigger.

Files changed (6) +79 / -5

Bug fix (1) +74 / -0
system_at32f43x.cInitialize AT32F43x SRAM config via USD EOPB0 at boot +74/-0

Initialize AT32F43x SRAM config via USD EOPB0 at boot

• Adds logic to derive the correct SRAM configuration from the linker-provided _SRAM_SIZE symbol and TARGET_FLASH_SIZE-dependent mappings. On boot, compares the desired setting with USD->eopb0 and, if mismatched, unlocks flash, erases user system data, programs EOPB0, and resets to apply the change.

src/main/drivers/system_at32f43x.c

Other (5) +5 / -5
target.hSet BLUEBERRYF435WING flash size to 1024 KB +1/-1

Set BLUEBERRYF435WING flash size to 1024 KB

• Defines TARGET_FLASH_SIZE as 1024 for the BLUEBERRYF435WING target so SRAM configuration selection uses the correct flash-size branch.

src/main/target/BLUEBERRYF435WING/target.h

at32_flash_f43xG.ldDefine default SRAM size symbol for F43xG linker script +1/-1

Define default SRAM size symbol for F43xG linker script

• Adds _SRAM_SIZE = 192 to the linker script so firmware can infer intended SRAM configuration at runtime.

src/main/target/link/at32_flash_f43xG.ld

at32_flash_f43xM.ldDefine default SRAM size symbol for F43xM linker script +1/-1

Define default SRAM size symbol for F43xM linker script

• Adds _SRAM_SIZE = 192 to the linker script to support runtime SRAM configuration selection.

src/main/target/link/at32_flash_f43xM.ld

at32_flash_f43xM_bl.ldDefine default SRAM size symbol for F43xM bootloader linker script +1/-1

Define default SRAM size symbol for F43xM bootloader linker script

• Adds _SRAM_SIZE = 192 for bootloader builds so the SRAM configuration logic can resolve the expected size consistently.

src/main/target/link/at32_flash_f43xM_bl.ld

at32_flash_f43xM_for_bl.ldDefine default SRAM size symbol for F43xM-for-bootloader linker script +1/-1

Define default SRAM size symbol for F43xM-for-bootloader linker script

• Adds _SRAM_SIZE = 192 to keep SRAM sizing consistent across the for-bootloader linker variant.

src/main/target/link/at32_flash_f43xM_for_bl.ld

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Flash size macro missing 🐞 Bug ≡ Correctness
Description
system_at32f43x.c now branches on TARGET_FLASH_SIZE, but AT32 builds define MCU_FLASH_SIZE in CMake
and other AT32 targets do not define TARGET_FLASH_SIZE; when undefined it evaluates as 0 in #if
expressions, leaving get_sram_config() with no return path and causing undefined behavior (or
-Werror build failure).
Code

src/main/drivers/system_at32f43x.c[R32-36]

+#if 256 < TARGET_FLASH_SIZE
+#define USD_EOPB0_SRAM_CONFIG_MASK 0x7
+#else
+#define USD_EOPB0_SRAM_CONFIG_MASK 0x3
+#endif
Evidence
The driver’s new preprocessor logic depends on TARGET_FLASH_SIZE, but the AT32 build system defines
MCU_FLASH_SIZE and the sampled AT32 target headers do not define TARGET_FLASH_SIZE (only BLUEBERRY
does), so builds can end up compiling the new function with no valid branch/return.

src/main/drivers/system_at32f43x.c[31-80]
cmake/at32f4.cmake[80-101]
src/main/target/BLUEBERRYF435WING/target.h[18-46]
src/main/target/IFLIGHT_BLITZ_ATF435/target.h[25-40]
src/main/target/NEUTRONRCF435MINI/target.h[18-36]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`system_at32f43x.c` uses `TARGET_FLASH_SIZE` in preprocessor conditionals, but the AT32 build system provides `MCU_FLASH_SIZE` (CMake) and most AT32 targets do not define `TARGET_FLASH_SIZE`. When undefined, `TARGET_FLASH_SIZE` is treated as `0` in `#if`, so the `get_sram_config()` switch compiles with no cases and no return, leading to undefined behavior (and often failing the build under `-Werror=return-type`).

### Issue Context
- AT32 CMake toolchain defines `MCU_FLASH_SIZE`, not `TARGET_FLASH_SIZE`.
- Only one AT32 target header was updated to define `TARGET_FLASH_SIZE`, leaving other AT32 targets inconsistent.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[31-80]
- cmake/at32f4.cmake[80-101]
- src/main/target/BLUEBERRYF435WING/target.h[18-46]

### Suggested fix
- Replace `TARGET_FLASH_SIZE` usage with `MCU_FLASH_SIZE` (preferred), or add a single global fallback in a common header:
 - `#ifndef TARGET_FLASH_SIZE` / `#define TARGET_FLASH_SIZE MCU_FLASH_SIZE`.
- Remove the per-target `#define TARGET_FLASH_SIZE ...` if it becomes redundant, to avoid divergence.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Flash ops unchecked 🐞 Bug ☼ Reliability
Description
init_sram_config() erases/programs USD and immediately resets without checking
flash_user_system_data_erase()/flash_eopb0_config() return values; if the operations fail, the board
can reboot into the same mismatch and get stuck in a persistent reset loop.
Code

src/main/drivers/system_at32f43x.c[R88-93]

+    if (((USD->eopb0) & USD_EOPB0_SRAM_CONFIG_MASK) != sram_cfg) {
+        flash_unlock();
+        flash_user_system_data_erase();
+        flash_eopb0_config(sram_cfg);
+        systemReset();
+    }
Evidence
The new code calls erase/config/reset without using the flash_status_type results, even though these
APIs are defined to return success/failure and the erase routine is documented to change eopb0 to
0xFF, which can impact SRAM sizing if reset occurs before successful reprogramming.

src/main/drivers/system_at32f43x.c[84-94]
lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[671-690]
lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-558]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`init_sram_config()` ignores the return statuses of `flash_user_system_data_erase()` and `flash_eopb0_config()`, then calls `systemReset()` unconditionally. If erase/program fails, the SRAM-config mismatch will still be present on next boot and the device can repeatedly erase/reset.

### Issue Context
The vendor flash driver APIs return `flash_status_type` specifically to allow callers to detect failures/timeouts. Additionally, the vendor driver documents that USD erase changes `eopb0` to `0xFF` (which can affect SRAM sizing), so resetting without confirming successful re-programming is risky.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[84-94]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[671-690]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-599]

### Suggested fix
- Capture and validate return values:
 - If erase fails: abort the update and avoid reset (enter a safe failure mode, or keep running with current config).
 - If programming fails after a successful erase: avoid reset-loop; signal failure and stop.
- Only call `systemReset()` after confirming successful programming.
- Consider re-locking flash (and/or USD) if execution continues after failure.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. USD erase wipes settings 🐞 Bug ≡ Correctness
Description
init_sram_config() uses flash_user_system_data_erase() (documented to erase all USD except FAP) but
then only restores eopb0, so any existing USD fields (SSB/DATA/EPP/QSPIKEY/etc.) are lost whenever
SRAM config differs.
Code

src/main/drivers/system_at32f43x.c[R89-92]

+        flash_unlock();
+        flash_user_system_data_erase();
+        flash_eopb0_config(sram_cfg);
+        systemReset();
Evidence
The vendor driver explicitly states that USD erase clears all user system data except FAP and
changes eopb0 to 0xFF, while the USD layout includes many fields besides eopb0; the new init
sequence erases USD and only reprograms eopb0.

src/main/drivers/system_at32f43x.c[84-94]
lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-558]
lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[631-652]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The new SRAM configuration path erases the entire User System Data (USD) area but reprograms only `eopb0`. Per the vendor driver, this erase clears all USD fields except the FAP byte, so board-specific/provisioned values in other USD fields can be destroyed.

### Issue Context
`usd_type` contains multiple fields beyond `eopb0` (`ssb`, `data0/1`, `epp*`, `qspikey[]`, etc.). If any of these are set (factory provisioning, security settings, boot behavior), erasing USD during firmware boot can cause permanent behavior changes.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[84-94]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-558]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[631-652]

### Suggested fix
- Avoid a full USD erase if the platform supports updating `eopb0` without erasing the whole USD block.
- If erase is required, first snapshot all USD fields that must be preserved (read `USD->...`), perform the erase, then reprogram **all** preserved fields plus the desired `eopb0` value.
- At minimum, explicitly set any required USD fields to known-safe defaults after erase, rather than leaving them erased.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +32 to +36
#if 256 < TARGET_FLASH_SIZE
#define USD_EOPB0_SRAM_CONFIG_MASK 0x7
#else
#define USD_EOPB0_SRAM_CONFIG_MASK 0x3
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Flash size macro missing 🐞 Bug ≡ Correctness

system_at32f43x.c now branches on TARGET_FLASH_SIZE, but AT32 builds define MCU_FLASH_SIZE in CMake
and other AT32 targets do not define TARGET_FLASH_SIZE; when undefined it evaluates as 0 in #if
expressions, leaving get_sram_config() with no return path and causing undefined behavior (or
-Werror build failure).
Agent Prompt
### Issue description
`system_at32f43x.c` uses `TARGET_FLASH_SIZE` in preprocessor conditionals, but the AT32 build system provides `MCU_FLASH_SIZE` (CMake) and most AT32 targets do not define `TARGET_FLASH_SIZE`. When undefined, `TARGET_FLASH_SIZE` is treated as `0` in `#if`, so the `get_sram_config()` switch compiles with no cases and no return, leading to undefined behavior (and often failing the build under `-Werror=return-type`).

### Issue Context
- AT32 CMake toolchain defines `MCU_FLASH_SIZE`, not `TARGET_FLASH_SIZE`.
- Only one AT32 target header was updated to define `TARGET_FLASH_SIZE`, leaving other AT32 targets inconsistent.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[31-80]
- cmake/at32f4.cmake[80-101]
- src/main/target/BLUEBERRYF435WING/target.h[18-46]

### Suggested fix
- Replace `TARGET_FLASH_SIZE` usage with `MCU_FLASH_SIZE` (preferred), or add a single global fallback in a common header:
  - `#ifndef TARGET_FLASH_SIZE` / `#define TARGET_FLASH_SIZE MCU_FLASH_SIZE`.
- Remove the per-target `#define TARGET_FLASH_SIZE ...` if it becomes redundant, to avoid divergence.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +88 to +93
if (((USD->eopb0) & USD_EOPB0_SRAM_CONFIG_MASK) != sram_cfg) {
flash_unlock();
flash_user_system_data_erase();
flash_eopb0_config(sram_cfg);
systemReset();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Flash ops unchecked 🐞 Bug ☼ Reliability

init_sram_config() erases/programs USD and immediately resets without checking
flash_user_system_data_erase()/flash_eopb0_config() return values; if the operations fail, the board
can reboot into the same mismatch and get stuck in a persistent reset loop.
Agent Prompt
### Issue description
`init_sram_config()` ignores the return statuses of `flash_user_system_data_erase()` and `flash_eopb0_config()`, then calls `systemReset()` unconditionally. If erase/program fails, the SRAM-config mismatch will still be present on next boot and the device can repeatedly erase/reset.

### Issue Context
The vendor flash driver APIs return `flash_status_type` specifically to allow callers to detect failures/timeouts. Additionally, the vendor driver documents that USD erase changes `eopb0` to `0xFF` (which can affect SRAM sizing), so resetting without confirming successful re-programming is risky.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[84-94]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[671-690]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-599]

### Suggested fix
- Capture and validate return values:
  - If erase fails: abort the update and avoid reset (enter a safe failure mode, or keep running with current config).
  - If programming fails after a successful erase: avoid reset-loop; signal failure and stop.
- Only call `systemReset()` after confirming successful programming.
- Consider re-locking flash (and/or USD) if execution continues after failure.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +89 to +92
flash_unlock();
flash_user_system_data_erase();
flash_eopb0_config(sram_cfg);
systemReset();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Usd erase wipes settings 🐞 Bug ≡ Correctness

init_sram_config() uses flash_user_system_data_erase() (documented to erase all USD except FAP) but
then only restores eopb0, so any existing USD fields (SSB/DATA/EPP/QSPIKEY/etc.) are lost whenever
SRAM config differs.
Agent Prompt
### Issue description
The new SRAM configuration path erases the entire User System Data (USD) area but reprograms only `eopb0`. Per the vendor driver, this erase clears all USD fields except the FAP byte, so board-specific/provisioned values in other USD fields can be destroyed.

### Issue Context
`usd_type` contains multiple fields beyond `eopb0` (`ssb`, `data0/1`, `epp*`, `qspikey[]`, etc.). If any of these are set (factory provisioning, security settings, boot behavior), erasing USD during firmware boot can cause permanent behavior changes.

### Fix Focus Areas
- src/main/drivers/system_at32f43x.c[84-94]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/src/at32f435_437_flash.c[508-558]
- lib/main/AT32F43x/Drivers/AT32F43x_StdPeriph_Driver/inc/at32f435_437_flash.h[631-652]

### Suggested fix
- Avoid a full USD erase if the platform supports updating `eopb0` without erasing the whole USD block.
- If erase is required, first snapshot all USD fields that must be preserved (read `USD->...`), perform the erase, then reprogram **all** preserved fields plus the desired `eopb0` value.
- At minimum, explicitly set any required USD fields to known-safe defaults after erase, rather than leaving them erased.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant