diff options
| author | Felipe Balbi <[email protected]> | 2025-11-13 09:58:21 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-11-13 09:58:21 -0800 |
| commit | f4b8ae36bec40a15bedd3c0493e4822f9c5238dd (patch) | |
| tree | 2b989f04f7bd2778e4763116181b6571a3a6efea | |
| parent | f53d4975774dd0c6009ad72692f394dca1083c0b (diff) | |
Remove a lot of text from README.md (#15)
New text will be added as necessary.
Co-authored-by: Felipe Balbi <[email protected]>
| -rw-r--r-- | README.md | 357 |
1 files changed, 2 insertions, 355 deletions
| @@ -1,366 +1,13 @@ | |||
| 1 | # Embassy MCXA276 HAL | 1 | # Embassy MCXA256 HAL |
| 2 | 2 | ||
| 3 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/check.yml) | 3 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/check.yml) |
| 4 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/nostd.yml) | 4 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/nostd.yml) |
| 5 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/rolling.yml) | 5 | [](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/rolling.yml) |
| 6 | 6 | ||
| 7 | A Hardware Abstraction Layer (HAL) for the NXP MCXA276 microcontroller | 7 | A Hardware Abstraction Layer (HAL) for the NXP MCXA256 microcontroller |
| 8 | using the Embassy async framework. This HAL provides safe, idiomatic | 8 | using the Embassy async framework. This HAL provides safe, idiomatic |
| 9 | Rust interfaces for GPIO, UART, and OSTIMER peripherals. | 9 | Rust interfaces for GPIO, UART, and OSTIMER peripherals. |
| 10 | 10 | ||
| 11 | ## Prerequisites | ||
| 12 | |||
| 13 | ### Ubuntu/Debian Setup | ||
| 14 | |||
| 15 | ```bash | ||
| 16 | # Install Rust toolchain | ||
| 17 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh | ||
| 18 | source ~/.cargo/env | ||
| 19 | |||
| 20 | # Add target for MCXA276 (ARM Cortex-M33) | ||
| 21 | rustup target add thumbv8m.main-none-eabihf | ||
| 22 | |||
| 23 | # Install required tools | ||
| 24 | sudo apt update | ||
| 25 | sudo apt install -y gdb-multiarch curl wget | ||
| 26 | |||
| 27 | # Install probe-rs for running and debugging | ||
| 28 | cargo install probe-rs --features cli | ||
| 29 | ``` | ||
| 30 | |||
| 31 | ### Windows Setup | ||
| 32 | |||
| 33 | - Install Rust via https://rustup.rs (default options are fine) | ||
| 34 | - Add the MCXA276 target: | ||
| 35 | ```powershell | ||
| 36 | rustup target add thumbv8m.main-none-eabihf | ||
| 37 | ``` | ||
| 38 | - Install probe-rs CLI (we will use it directly; no GDB required): | ||
| 39 | ```powershell | ||
| 40 | cargo install probe-rs --features cli | ||
| 41 | ``` | ||
| 42 | - Install a serial terminal (e.g., Tera Term): https://ttssh2.osdn.jp/ | ||
| 43 | - USB drivers: Windows 10/11 usually picks up the board as a USB CDC device automatically (COM port) | ||
| 44 | |||
| 45 | ### Hardware Requirements | ||
| 46 | |||
| 47 | - NXP FRDM-MCXA276 development board | ||
| 48 | - Debug probe (CMSIS-DAP compatible) | ||
| 49 | - USB cable for power and programming | ||
| 50 | |||
| 51 | ## Examples | ||
| 52 | |||
| 53 | This HAL includes several examples demonstrating different peripherals: | ||
| 54 | |||
| 55 | ### GPIO Examples | ||
| 56 | |||
| 57 | #### `blink` | ||
| 58 | Blinks an LED connected to GPIO pin. Demonstrates basic GPIO output operations. | ||
| 59 | |||
| 60 | ### UART Examples | ||
| 61 | |||
| 62 | #### `hello` | ||
| 63 | Interactive UART2 demo: prints a banner and supports `help`, `echo <text>`, `hex <byte>`. | ||
| 64 | |||
| 65 | ### OSTIMER Examples | ||
| 66 | |||
| 67 | #### `ostimer_alarm` | ||
| 68 | |||
| 69 | Demonstrates setting and waiting for OSTIMER alarms. | ||
| 70 | |||
| 71 | #### `ostimer_async` | ||
| 72 | Shows asynchronous OSTIMER operations with Embassy's async runtime. | ||
| 73 | |||
| 74 | #### `ostimer_counter` | ||
| 75 | Demonstrates OSTIMER counter functionality. | ||
| 76 | |||
| 77 | #### `ostimer_race_test` | ||
| 78 | Advanced example testing OSTIMER race conditions and synchronization. | ||
| 79 | |||
| 80 | ### RTC Example | ||
| 81 | |||
| 82 | #### `rtc_alarm` | ||
| 83 | Demonstrates how to enable and use the RTC to generate an interrupt after 10seconds. | ||
| 84 | |||
| 85 | ## Build and Run | ||
| 86 | |||
| 87 | ### Using probe-rs | ||
| 88 | |||
| 89 | All examples require specifying your debug probe. First, find your probe ID: | ||
| 90 | |||
| 91 | ```bash | ||
| 92 | probe-rs list | ||
| 93 | ``` | ||
| 94 | |||
| 95 | Then run examples with your probe ID (replace `1fc9:0143:H3AYDQVQMTROB` with your actual probe): | ||
| 96 | |||
| 97 | ```bash | ||
| 98 | # GPIO blink example | ||
| 99 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "gpio ostimer0" --example blink | ||
| 100 | |||
| 101 | |||
| 102 | |||
| 103 | # UART hello example | ||
| 104 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example hello | ||
| 105 | |||
| 106 | # OSTIMER examples | ||
| 107 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm | ||
| 108 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_async | ||
| 109 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_counter | ||
| 110 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_race_test | ||
| 111 | |||
| 112 | # RTC example | ||
| 113 | PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 rtc0" --example rtc_alarm | ||
| 114 | ``` | ||
| 115 | |||
| 116 | **Note:** All examples run from RAM, not flash memory. They are loaded directly into RAM for faster development iteration. | ||
| 117 | |||
| 118 | **Important:** After pressing the RESET button on the board, the first `cargo run` attempt may fail with a connection error. This is expected - simply run the command again and it will work. The run.sh script now properly sets the Vector Table Offset Register (VTOR) to point to the RAM-based vector table, ensuring the correct stack pointer and reset vector are used. | ||
| 119 | |||
| 120 | ```console | ||
| 121 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --release --features "gpio ostimer0" --example blink | ||
| 122 | Finished `release` profile [optimized + debuginfo] target(s) in 0.07s | ||
| 123 | Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/release/examples/blink` | ||
| 124 | probe-rs gdb server failed to connect to target. Log: | ||
| 125 | ----- probe-rs gdb log ----- | ||
| 126 | Error: Connecting to the chip was unsuccessful. | ||
| 127 | |||
| 128 | Caused by: | ||
| 129 | 0: An ARM specific error occurred. | ||
| 130 | 1: Error using access port FullyQualifiedApAddress { dp: Default, ap: V1(0) }. | ||
| 131 | 2: Failed to read register DRW at address 0xd0c | ||
| 132 | 3: An error occurred in the communication with an access port or debug port. | ||
| 133 | 4: Target device responded with a FAULT response to the request. | ||
| 134 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --release --features "gpio ostimer0" --example blink | ||
| 135 | Finished `release` profile [optimized + debuginfo] target(s) in 0.02s | ||
| 136 | Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/release/examples/blink` | ||
| 137 | ``` | ||
| 138 | |||
| 139 | ### Additional UART Examples | ||
| 140 | |||
| 141 | #### `uart_interrupt` | ||
| 142 | Interrupt-driven UART2 echo. Type in the serial terminal; each byte is echoed back from the IRQ handler path. | ||
| 143 | |||
| 144 | #### `lpuart_polling` | ||
| 145 | Blocking TX/RX echo over UART2 using the simple polling driver. | ||
| 146 | |||
| 147 | #### `lpuart_buffered` | ||
| 148 | Async buffered driver with separate TX/RX tasks; echoes typed characters in chunks. | ||
| 149 | |||
| 150 | Pins: UART2 TX=P2_2, RX=P2_3 (ALT3), 115200 8N1. | ||
| 151 | |||
| 152 | ### ADC Examples | ||
| 153 | |||
| 154 | #### `adc_polling` | ||
| 155 | Configures ADC1 channel A8 (pin P1_10) and prints conversion values to UART2 periodically. | ||
| 156 | |||
| 157 | #### `adc_interrupt` | ||
| 158 | Triggers a conversion and signals completion via ADC1 interrupt, printing a notification on UART2. | ||
| 159 | |||
| 160 | ```console | ||
| 161 | 0x20002040 in ?? () | ||
| 162 | Supported Commands: | ||
| 163 | |||
| 164 | info - print session information | ||
| 165 | reset - reset target | ||
| 166 | reset halt - reset target and halt afterwards | ||
| 167 | |||
| 168 | Loading section .vector_table, size 0x224 lma 0x20000000 | ||
| 169 | Loading section .text, size 0x97e lma 0x20000224 | ||
| 170 | Loading section .Reset, size 0x58 lma 0x20000ba4 | ||
| 171 | Loading section .rodata, size 0x28 lma 0x20000bfc | ||
| 172 | Start address 0x20000ba4, load size 3106 | ||
| 173 | Transfer rate: 13 KB/sec, 776 bytes/write. | ||
| 174 | ``` | ||
| 175 | |||
| 176 | then I see the LED blinking. I press CTRL+C to exit. It will show me ^C | ||
| 177 | |||
| 178 | ```console | ||
| 179 | Program received signal SIGINT, Interrupt. | ||
| 180 | 0x20000880 in embassy_executor::arch::thread::Executor::run<blink::__cortex_m_rt_main::{closure_env#0}> (self=0x200027e8, init=...) at /home/smw016108/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embassy-executor-0.9.1/src/arch/cortex_m.rs:106 | ||
| 181 | 106 asm!("wfe"); | ||
| 182 | [Inferior 1 (process 1) detached] | ||
| 183 | Program loaded and started (no reset) | ||
| 184 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ \ | ||
| 185 | |||
| 186 | Then I press RESET again and I want to run another example, like ostimer_alarm. I open the console using sudo picocom -b 115200 /dev/ttyACM0 and I start running the example: | ||
| 187 | |||
| 188 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm | ||
| 189 | Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s | ||
| 190 | Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm` | ||
| 191 | probe-rs gdb server failed to connect to target. Log: | ||
| 192 | ----- probe-rs gdb log ----- | ||
| 193 | Error: Connecting to the chip was unsuccessful. | ||
| 194 | |||
| 195 | Caused by: | ||
| 196 | 0: An ARM specific error occurred. | ||
| 197 | 1: Error using access port FullyQualifiedApAddress { dp: Default, ap: V1(0) }. | ||
| 198 | 2: Failed to read register DRW at address 0xd0c | ||
| 199 | 3: An error occurred in the communication with an access port or debug port. | ||
| 200 | 4: Target device responded with a FAULT response to the request. | ||
| 201 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm | ||
| 202 | Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s | ||
| 203 | Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm` | ||
| 204 | 0x20002040 in core::panicking::panic_const::panic_const_mul_overflow () at library/core/src/panicking.rs:175 | ||
| 205 | warning: 175 library/core/src/panicking.rs: No such file or directory | ||
| 206 | Supported Commands: | ||
| 207 | |||
| 208 | info - print session information | ||
| 209 | reset - reset target | ||
| 210 | reset halt - reset target and halt afterwards | ||
| 211 | |||
| 212 | Loading section .vector_table, size 0x224 lma 0x20000000 | ||
| 213 | Loading section .text, size 0x2226 lma 0x20000224 | ||
| 214 | Loading section .Reset, size 0x58 lma 0x2000244c | ||
| 215 | Loading section .rodata, size 0x6dc lma 0x200024a4 | ||
| 216 | Start address 0x2000244c, load size 11134 | ||
| 217 | Transfer rate: 16 KB/sec, 1855 bytes/write. | ||
| 218 | ``` | ||
| 219 | |||
| 220 | I can see in the console | ||
| 221 | |||
| 222 | ```console | ||
| 223 | OSTIMER Alarm Example | ||
| 224 | Scheduling alarm for 2 seconds... | ||
| 225 | Alarm scheduled successfully | ||
| 226 | Alarm expired! Callback executed. | ||
| 227 | Scheduling another alarm for 3 seconds... | ||
| 228 | Alarm scheduled. Waiting 1 second then canceling... | ||
| 229 | Alarm canceled | ||
| 230 | Alarm was successfully canceled | ||
| 231 | Example complete | ||
| 232 | ``` | ||
| 233 | |||
| 234 | then I press CTRL+C to stop running | ||
| 235 | |||
| 236 | ```console | ||
| 237 | ^C | ||
| 238 | Program received signal SIGINT, Interrupt. | ||
| 239 | 0x20000e64 in embassy_executor::arch::thread::Executor::run<ostimer_alarm::__cortex_m_rt_main::{closure_env#0}> (self=0x200027e8, init=...) at /home/smw016108/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embassy-executor-0.9.1/src/arch/cortex_m.rs:106 | ||
| 240 | 106 asm!("wfe"); | ||
| 241 | [Inferior 1 (process 1) detached] | ||
| 242 | Program loaded and started (no reset) | ||
| 243 | smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ | ||
| 244 | ``` | ||
| 245 | |||
| 246 | ### Windows: Running examples (RAM, no RTT/defmt) | ||
| 247 | |||
| 248 | Important: On Windows, do not use `cargo run` because `.cargo/config.toml` sets a Linux-only runner (`./run.sh`). Instead, use `probe-rs run` directly. | ||
| 249 | |||
| 250 | 1) Find your probe and COM port | ||
| 251 | - List probes: | ||
| 252 | |||
| 253 | ```console | ||
| 254 | probe-rs list | ||
| 255 | ``` | ||
| 256 | - If multiple probes are attached, set the specific one (replace with your ID): | ||
| 257 | |||
| 258 | ```console | ||
| 259 | $env:PROBE_RS_PROBE = "1366:0101:000600110607" | ||
| 260 | ``` | ||
| 261 | |||
| 262 | - Check Windows Device Manager → Ports (COM & LPT) for the board’s COM port. | ||
| 263 | |||
| 264 | 2) Build the example | ||
| 265 | |||
| 266 | ```console | ||
| 267 | cargo build --example hello --features "lpuart2" | ||
| 268 | ``` | ||
| 269 | |||
| 270 | 3) Run from RAM with probe-rs | ||
| 271 | |||
| 272 | ```console | ||
| 273 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/hello | ||
| 274 | ``` | ||
| 275 | You will see a short probe-rs warning like "unknown variant, try to set watch point"; it’s harmless. | ||
| 276 | |||
| 277 | 4) View output in Tera Term | ||
| 278 | - Open Tera Term, select the board’s COMx port, 115200 8N1 | ||
| 279 | - Expected behavior per example: | ||
| 280 | - hello: prints a banner; simple UART output | ||
| 281 | - lpuart_polling / lpuart_buffered / uart_interrupt: echo typed characters | ||
| 282 | - adc_polling: prints ADC values periodically (ADC1 channel A8 on P1_10) | ||
| 283 | - adc_interrupt: prints "*** ADC interrupt TRIGGERED! ***" upon conversion completion | ||
| 284 | - blink: LED on PIO3_18 blinks "SOS" pattern | ||
| 285 | - rtc_alarm: schedules, cancels and reports alarm events on UART | ||
| 286 | |||
| 287 | Notes | ||
| 288 | - All examples run from RAM (not flashed). Reset clears the program. | ||
| 289 | - If the first attempt after a reset fails to connect, just run the command again. | ||
| 290 | - UART2 pins: TX=P2_2, RX=P2_3 (ALT3), 115200 8N1. | ||
| 291 | |||
| 292 | Quick commands for other examples: | ||
| 293 | |||
| 294 | ```console | ||
| 295 | # Build | ||
| 296 | cargo build --example blink --features "gpio ostimer0" | ||
| 297 | cargo build --example lpuart_polling --features "lpuart2 ostimer0" | ||
| 298 | cargo build --example lpuart_buffered --features "lpuart2 ostimer0" | ||
| 299 | cargo build --example uart_interrupt --features "lpuart2 ostimer0" | ||
| 300 | cargo build --example rtc_alarm --features "lpuart2 rtc0" | ||
| 301 | cargo build --example adc_polling --features "adc1 lpuart2" | ||
| 302 | cargo build --example adc_interrupt --features "adc1 lpuart2" | ||
| 303 | |||
| 304 | # Run (RAM) | ||
| 305 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/blink | ||
| 306 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/lpuart_polling | ||
| 307 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/lpuart_buffered | ||
| 308 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/uart_interrupt | ||
| 309 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/rtc_alarm | ||
| 310 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/adc_polling | ||
| 311 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/adc_interrupt | ||
| 312 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm | ||
| 313 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_async | ||
| 314 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_counter | ||
| 315 | probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_race_test | ||
| 316 | ``` | ||
| 317 | |||
| 318 | How I tested on Windows | ||
| 319 | - Windows 11; Rust stable; probe-rs 0.29.x | ||
| 320 | - Built each example as above; ran with `probe-rs run` (RAM execution) | ||
| 321 | - Observed UART output in Tera Term at 115200 8N1; all examples behaved as expected | ||
| 322 | - No RTT/defmt used; purely UART or LED observation | ||
| 323 | |||
| 324 | ### Build Only | ||
| 325 | |||
| 326 | To build without running: | ||
| 327 | |||
| 328 | ```console | ||
| 329 | cargo build --features "gpio ostimer0" --example blink | ||
| 330 | cargo build --features "lpuart2 ostimer0" --example hello | ||
| 331 | cargo build --features "lpuart2 ostimer0" --example ostimer_alarm | ||
| 332 | cargo build --features "lpuart2 rtc0" --example rtc_alarm | ||
| 333 | # etc. | ||
| 334 | ``` | ||
| 335 | |||
| 336 | ## Development Notes | ||
| 337 | |||
| 338 | ### Critical Fix: MCXA276 Interrupt Vector Table | ||
| 339 | |||
| 340 | |||
| 341 | Update (SVD 25.06.00, mcxa-pac a9dd33): No manual PAC edits are required anymore. OS_EVENT and WAKETIMER0 are present and the vector table is correct. The section below is kept for historical context. | ||
| 342 | **Problem:** The OSTIMER examples crashed during interrupt handling with a hardfault (SP=0x00000000). Investigation revealed the OS_EVENT interrupt vector was NULL in the vector table, causing the CPU to jump to address 0 when OSTIMER interrupts fired. | ||
| 343 | |||
| 344 | **Root Cause:** The `mcxa276-pac/src/lib.rs` file (generated from the SVD file) was missing the `WAKETIMER0` interrupt handler declaration. This caused the `__INTERRUPTS` array to have an off-by-one error, placing OS_EVENT at IRQ 58 instead of the correct IRQ 57 position. | ||
| 345 | |||
| 346 | **Solution:** Manually edited `mcxa276-pac/src/lib.rs` to add the missing WAKETIMER0 interrupt: | ||
| 347 | |||
| 348 | 1. Added `fn WAKETIMER0()` to the `extern "C"` block | ||
| 349 | 2. Fixed the `__INTERRUPTS: [Vector; 122]` array sequence: | ||
| 350 | - Changed from: `LPTMR0, _reserved, _reserved, OS_EVENT, _reserved, UTICK0, ...` | ||
| 351 | - Changed to: `LPTMR0, _reserved, OS_EVENT, WAKETIMER0, UTICK0, WWDT0, _reserved, ADC0, ...` | ||
| 352 | 3. Added `WAKETIMER0 = 58` to the `Interrupt` enum | ||
| 353 | |||
| 354 | **Verification:** Binary analysis confirmed OS_EVENT is now at the correct position: | ||
| 355 | - IRQ 57 = word 73 = offset 0x124 in vector table | ||
| 356 | - OS_EVENT handler: 0x20000BB1 (verified with `arm-none-eabi-objdump`) | ||
| 357 | |||
| 358 | **Note:** This is likely an issue with the NXP MCXA276.svd file or svd2rust generation. The WAKETIMER0 peripheral exists in the PAC but the interrupt handler was missing. Future regeneration of the PAC from SVD may require reapplying this fix. | ||
| 359 | |||
| 360 | ### Warning: Avoid `#[inline(always)]` in Performance-Critical Code | ||
| 361 | |||
| 362 | Using `#[inline(always)]` can cause the Rust compiler to generate incorrect assembly, leading to register corruption or unexpected behavior. For example, in tight polling loops like those in the OSTIMER driver, this attribute may result in invalid instructions that zero registers (e.g., `movs r1, r0` causing r1=0), triggering hardfaults. | ||
| 363 | |||
| 364 | ## License | 11 | ## License |
| 365 | 12 | ||
| 366 | This project is licensed under MIT OR Apache-2.0. | 13 | This project is licensed under MIT OR Apache-2.0. |
