-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Guoping Wang
committed
Mar 29, 2025
1 parent
3aadfe8
commit 2de912c
Showing
1 changed file
with
33 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,52 @@ | ||
# TivaCCriticalRegion | ||
# TivaC Mutex Counter Example | ||
|
||
This repository demonstrates how to use `cortex_m::interrupt::free` to safely access shared data in a critical section on the TI TM4C123GXL LaunchPad using Rust. It is a minimal embedded example that toggles an onboard LED based on a shared flag, set inside a timer interrupt and cleared in the main loop. | ||
This repository contains an example demonstrating how to use a `Mutex` to safely share and update a `u32` counter variable between interrupt context and the main loop on the Tiva C Series microcontroller using the Rust Embedded ecosystem. | ||
|
||
Unlike platforms with native atomic support, this example uses `Mutex<Cell<bool>>` instead of `AtomicBool` to maintain compatibility with microcontrollers that do not fully support atomic operations in `no_std` environments. | ||
## Overview | ||
|
||
## Features | ||
|
||
- Runs on TI TM4C123GXL LaunchPad (Cortex-M4F) | ||
- Written in safe `no_std` Rust | ||
- Demonstrates safe shared-state access using `cortex_m::interrupt::free` | ||
- Uses a `Mutex<Cell<bool>>` flag shared between main and interrupt context | ||
- Blinks onboard LED when a timer-based flag is set | ||
Concurrency is a common challenge in embedded systems, especially when sharing data between the main application and interrupt service routines (ISRs). Rust’s ownership model helps enforce safe concurrency, and the `Mutex` abstraction from the `cortex_m::interrupt` module enables safe shared access to data. | ||
|
||
## Requirements | ||
In this example, a `u32` counter is protected by a `Mutex`, allowing both the main loop and an interrupt handler (e.g., triggered by a button press or timer event) to safely access and modify the shared variable. | ||
|
||
- Rust nightly toolchain with support for `thumbv7em-none-eabihf` | ||
- `cortex-m` and `cortex-m-rt` crates | ||
- Flashing tools like OpenOCD, probe-rs, or LM Flash Programmer | ||
- TivaWare and [TivaCRustWare](https://github.itap.purdue.edu/wang32/TivaCRustWare) HAL | ||
This is a departure from simpler examples that only toggle or read a `bool` flag. Using a `u32` demonstrates how to work with more complex shared data and atomic-style updates in an embedded Rust environment. | ||
|
||
## Setup | ||
|
||
1. Add the target: | ||
```bash | ||
rustup target add thumbv7em-none-eabihf | ||
``` | ||
## Features | ||
|
||
2. Clone the repository: | ||
```bash | ||
git clone https://github.itap.purdue.edu/wang32/TivaCCriticalRegion.git | ||
cd TivaCCriticalRegion | ||
``` | ||
- Safe sharing of a `u32` counter between main and interrupt contexts. | ||
- Uses `Mutex` from `cortex_m::interrupt` to guarantee data race freedom. | ||
- Runs on the Tiva C Series TM4C123G microcontroller. | ||
- Illustrates best practices for writing concurrent embedded Rust code. | ||
|
||
3. Build the project: | ||
```bash | ||
cargo build --release | ||
``` | ||
## Requirements | ||
|
||
4. Flash to the TM4C123GXL board using your preferred method. | ||
- Tiva C Series LaunchPad (TM4C123GXL) | ||
- Rust toolchain with target support for `thumbv7em-none-eabi` | ||
- [TivaCRustWare](https://github.itap.purdue.edu/wang32/TivaCRustWare) as the base project template | ||
- `probe-rs` or `openocd` for flashing the firmware | ||
|
||
## Code Structure | ||
## Building and Flashing | ||
|
||
- `SECONDS_FLAG` is a `Mutex<Cell<bool>>` shared between main and an interrupt handler. | ||
- The interrupt handler sets `SECONDS_FLAG` to true. | ||
- The main loop checks and clears `SECONDS_FLAG`; if set, it toggles the LED. | ||
```bash | ||
# Add target if you haven't already | ||
rustup target add thumbv7em-none-eabi | ||
|
||
## Example Logic Snippet | ||
# Build the project | ||
cargo build --release | ||
|
||
```rust | ||
interrupt::free(|cs| { | ||
let flag = SECONDS_FLAG.borrow(cs); | ||
if flag.get() { | ||
flag.set(false); | ||
GREEN_LED.toggle(); | ||
} | ||
}); | ||
# Flash to device (example using probe-rs) | ||
cargo run --release | ||
``` | ||
|
||
## License | ||
## How It Works | ||
|
||
This project is intended for educational and instructional use. | ||
- A global static `Mutex<RefCell<Option<u32>>>` wraps the counter variable. | ||
- The main loop and an interrupt handler both enter critical sections to access and update the counter. | ||
- This ensures the shared `u32` is never accessed concurrently from multiple contexts. | ||
|
||
## Acknowledgments | ||
## Educational Value | ||
|
||
Inspired by the Rust embedded community and based on the `cortex-m` crate's safe interrupt handling patterns. | ||
This example is designed for students and embedded systems developers looking to understand how to safely share data between threads of execution in Rust, specifically in environments where standard threading libraries are unavailable and concurrency is managed through interrupts. | ||
|
||
## License | ||
|
||
MIT License |