Skip to content

Commit 14ab71d

Browse files
authored
Minimal interrupt (#7)
1 parent 732c1e6 commit 14ab71d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+83044
-1
lines changed

.github/workflows/rust_all.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,10 @@ jobs:
6868
cargo make ci_debug
6969
cargo make ci_release
7070
cargo doc
71+
72+
- name: Minimal Interrupt
73+
working-directory: ${{github.workspace}}/minimal_interrupt
74+
run: |
75+
cargo make ci_debug
76+
cargo make ci_release
77+
cargo doc

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,29 @@ Rust on microcontrollers
99
- Minimal buildsystem
1010
- Initial [cargo-make](https://github.com/sagiegurari/cargo-make) framework to have configurable build options i.e extending `cargo`
1111
- Minimal controller peripheral
12+
- Use bindgen to transform `.c` architecture and chip files to `.rs`
1213
- Create `l0` and `l5` workspace layers
1314
- Add **architecture**, **controller** and **startup** files in `l0`
15+
- Minimal Drivers
16+
- Write GPIO and USART drivers for high level application usage
17+
- Added `l2`, `l3` and `l4` workspace layers
18+
- Added **bitflags** utility library in `l2` via crates.io
19+
- Added **driver interfaces**, **gpio**, **usart** drivers in `l3`
20+
- Added **led** and **button** modules in `l4`
21+
- Minimal Interrupt
22+
- Configure interrupts from high level application code
23+
- Updated `l0` `l2`, `l3` and `l4` workspace layers
24+
- Updated `l0` with user interrupt considerations
25+
- Added **heapless** library to `l2`
26+
- Added USART buffered traits to `l3`
1427

1528
# Roadmap
1629

30+
## Libraries
31+
32+
- [Bitflags](https://crates.io/crates/bitflags): Rust macros to generate bitflags
33+
- [Heapless](https://crates.io/crates/heapless): Stack allocated data structures
34+
1735
## RTOS
1836

1937
## Debugging

minimal_drivers/l5/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn main() -> ! {
3939
gpiob_peripheral.configure_for_usart(GPIOAlternate::AF7, 6);
4040
gpiob_peripheral.configure_for_usart(GPIOAlternate::AF7, 7);
4141

42-
let usart1_rx_tx: &mut dyn UsartInOut = &mut USART1_PORT.take().configure_default_rx_tx();
42+
let mut usart1_rx_tx = USART1_PORT.take().configure_default_rx_tx();
4343

4444
let gpioc_peripheral = GPIOC_PORT.take();
4545
// Configure GPIOC port and Pin 13 as input

minimal_interrupt/.cargo/config.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[target.thumbv7em-none-eabihf]
2+
# uncomment this to make `cargo run` execute programs on QEMU
3+
# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
4+
5+
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
6+
# uncomment ONE of these three option to make `cargo run` start a GDB session
7+
# which option to pick depends on your system
8+
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
9+
# runner = "gdb-multiarch -q -x openocd.gdb"
10+
# runner = "gdb -q -x openocd.gdb"
11+
rustflags = [
12+
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
13+
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
14+
# "-C", "link-arg=--nmagic",
15+
16+
# LLD (shipped with the Rust toolchain) is used as the default linker
17+
# "-C", "link-arg=-Tgcc_arm.ld",
18+
19+
# Generate a .map file
20+
# "-C", "link-args=-Map=application.map",
21+
22+
# if you run into problems with LLD switch to the GNU linker by commenting out
23+
# this line
24+
"-C", "linker=arm-none-eabi-ld",
25+
26+
# if you need to link to pre-compiled C libraries provided by a C toolchain
27+
# use GCC as the linker by commenting out both lines above and then
28+
# uncommenting the three lines below
29+
"-C", "linker=arm-none-eabi-gcc",
30+
"-C", "link-arg=-Wl,-Tgcc_arm.ld",
31+
"-C", "link-arg=-Wl,-Map,application.map",
32+
"-C", "link-arg=-nostartfiles",
33+
]
34+
35+
[build]
36+
# Pick ONE of these compilation targets
37+
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
38+
# target = "thumbv7m-none-eabi" # Cortex-M3
39+
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
40+
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
41+
# target = "thumbv8m.base-none-eabi" # Cortex-M23
42+
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
43+
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)

minimal_interrupt/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Files
2+
*.map
3+
.vscode/.cortex-debug.*
4+
5+
# Folders
6+
target

minimal_interrupt/.vscode/launch.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"configurations": [
3+
{
4+
"cwd": "${workspaceFolder}",
5+
"executable": "target/thumbv7em-none-eabihf/debug/application",
6+
"configFiles": [
7+
"stm32l4discovery.cfg"
8+
],
9+
"postLaunchCommands": [
10+
"load",
11+
"monitor arm semihosting enable",
12+
],
13+
"name": "Rust Debug",
14+
"request": "launch",
15+
"type": "cortex-debug",
16+
"servertype": "openocd",
17+
"svdFile": "l0/svd/STM32L4x5.svd",
18+
"svdPath": "l0/svd/STM32L4x5.svd"
19+
},
20+
{
21+
"cwd": "${workspaceFolder}",
22+
"executable": "target/thumbv7em-none-eabihf/release/application",
23+
"configFiles": [
24+
"stm32l4discovery.cfg"
25+
],
26+
"postLaunchCommands": [
27+
"load",
28+
"monitor arm semihosting enable",
29+
],
30+
"name": "Rust Release",
31+
"request": "launch",
32+
"type": "cortex-debug",
33+
"servertype": "openocd"
34+
}
35+
]
36+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"rust-analyzer.cargo.target": "thumbv7em-none-eabihf",
3+
"rust-analyzer.check.allTargets": false,
4+
"rust-analyzer.imports.prefer.no.std": true,
5+
"rust-analyzer.cargo.unsetTest": [
6+
"core",
7+
"l0",
8+
"l3",
9+
"l5",
10+
"application",
11+
],
12+
}

minimal_interrupt/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[workspace]
2+
members = [
3+
"l0",
4+
"l3",
5+
"l4",
6+
"l5"
7+
]

minimal_interrupt/Makefile.toml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
[config]
2+
default_to_workspace = false
3+
4+
# Duckscript is used here to convert \ to / for binary output path
5+
[tasks.build_debug]
6+
script_runner = "@duckscript"
7+
script = '''
8+
output = set ${CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY}/debug/application
9+
echo OUTPUT: ${output}
10+
output = replace ${output} \\ /
11+
set_env OUTPUT ${output}
12+
exec cargo build
13+
'''
14+
15+
# Duckscript is used here to convert \ to / for binary output path
16+
[tasks.build_release]
17+
script_runner = "@duckscript"
18+
script = '''
19+
output = set ${CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY}/release/application
20+
output = replace ${output} \\ /
21+
set_env OUTPUT ${output}
22+
exec cargo build --release
23+
'''
24+
25+
[tasks.test]
26+
command = "cargo"
27+
args = ["test", "--target", "${CARGO_MAKE_RUST_TARGET_TRIPLE}"]
28+
29+
[tasks.flash_debug]
30+
script_runner = "@shell"
31+
script = '''
32+
openocd -f board/stm32l4discovery.cfg -c "program ${OUTPUT} verify reset exit"
33+
'''
34+
dependencies = ["build_debug"]
35+
36+
[tasks.ci_debug]
37+
dependencies = [
38+
"build_debug",
39+
"test",
40+
"objcopy_to_binary",
41+
"objcopy_to_hex",
42+
"objdump",
43+
"size",
44+
]
45+
46+
[tasks.ci_release]
47+
dependencies = [
48+
"build_release",
49+
"test",
50+
"objcopy_to_binary",
51+
"objcopy_to_hex",
52+
"objdump",
53+
"size",
54+
]
55+
56+
# Private Tasks
57+
58+
# Requires
59+
# arm-none-eabi-size executable (ARM GCC toolchain)
60+
# OUTPUT env variable (Set by build_*)
61+
[tasks.size]
62+
private = true
63+
command = "arm-none-eabi-size"
64+
args = ["${OUTPUT}"]
65+
66+
# arm-none-eabi-objcopy executable (ARM GCC toolchain)
67+
# OUTPUT env variable (Set by build_*)
68+
[tasks.objcopy_to_binary]
69+
private = true
70+
command = "arm-none-eabi-objcopy"
71+
args = ["-O", "binary", "${OUTPUT}", "${OUTPUT}.bin"]
72+
73+
# arm-none-eabi-objcopy executable (ARM GCC toolchain)
74+
# OUTPUT env variable (Set by build_*)
75+
[tasks.objcopy_to_hex]
76+
private = true
77+
command = "arm-none-eabi-objcopy"
78+
args = ["-O", "ihex", "${OUTPUT}", "${OUTPUT}.hex"]
79+
80+
# arm-none-eabi-objdump executable (ARM GCC toolchain)
81+
# OUTPUT env variable (Set by build_*)
82+
[tasks.objdump]
83+
private = true
84+
script_runner = "@shell"
85+
script = '''
86+
arm-none-eabi-objdump --source --all-headers --demangle --line-numbers --wide ${OUTPUT} > ${OUTPUT}.lst
87+
'''

minimal_interrupt/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
- [Minimal Interrupt](#minimal-interrupt)
2+
- [Links](#links)
3+
- [Microcontrollers layers](#microcontrollers-layers)
4+
- [Pre-requisites](#pre-requisites)
5+
- [Changelog](#changelog)
6+
- [L0 - Entry](#l0---entry)
7+
- [L0 - Utility](#l0---utility)
8+
- [L0 - Chip](#l0---chip)
9+
- [L0 - Architecture](#l0---architecture)
10+
- [L2 - Utility](#l2---utility)
11+
- [L3 Improvements](#l3-improvements)
12+
- [Hardware](#hardware)
13+
- [Software](#software)
14+
- [L3 - Interface](#l3---interface)
15+
- [L3 - Driver](#l3---driver)
16+
- [L5 - Application](#l5---application)
17+
18+
# Minimal Interrupt
19+
20+
This code has been tested on
21+
22+
- B-L475-IOT01A board (STM32L475VGT6 ARM Cortex M4 CPU with FPU)
23+
24+
## Links
25+
26+
- [Cargo binutils](https://github.com/rust-embedded/cargo-binutils)
27+
- [Embedded Rust book](https://doc.rust-lang.org/stable/embedded-book/)
28+
- [Lowlevel Embedded Rust book](https://docs.rust-embedded.org/embedonomicon/)
29+
30+
## Microcontrollers layers
31+
32+
- L0 Lowlevel
33+
- Chip Interrupts
34+
- L1 RTOS
35+
- L2 Utility
36+
- Heapless library
37+
- L3 Driver
38+
- Interrupt support for GPIO and USART
39+
- L4 Sensor
40+
- L5 Application
41+
- Interrupt usage
42+
43+
---
44+
45+
## Pre-requisites
46+
47+
- Pre-requisites from `minimal_driver`
48+
49+
# Changelog
50+
51+
## L0 - Entry
52+
53+
- Updated linker script to remove PROVIDE attributes
54+
- Updated entry point with a better EXCEPTIONS usage
55+
56+
## L0 - Utility
57+
58+
- Added `write_assign_register` macro
59+
60+
## L0 - Chip
61+
62+
- Updated `controller_init` with `SCB->VTOR = FLASH_BASE`
63+
- Added `attach_interrupt_handler` for STM32L475xx chip
64+
65+
## L0 - Architecture
66+
67+
- Added `nvic` module with `enable_irq` function
68+
- NOTE, This has only been added since bindgen cannot parse `static inline` C functions
69+
70+
71+
## L2 - Utility
72+
73+
- Added [heapless](https://crates.io/crates/heapless) library for stack based datastructures
74+
75+
## L3 Improvements
76+
77+
### Hardware
78+
79+
```mermaid
80+
graph BT;
81+
subgraph Port
82+
USART1-3
83+
subgraph Peripheral
84+
USART
85+
subgraph Register
86+
CR1
87+
CR2
88+
RDR
89+
TDR
90+
end
91+
end
92+
end
93+
```
94+
95+
### Software
96+
97+
```mermaid
98+
graph BT;
99+
subgraph Port
100+
USART1-3
101+
subgraph Peripheral
102+
PolledUSART
103+
BufferedUSART
104+
end
105+
end
106+
```
107+
108+
## L3 - Interface
109+
110+
- Removed `PeripheralConfiguration` trait
111+
- Added `UsartBufferedIn` and `UsartBufferedInOut` trait
112+
113+
## L3 - Driver
114+
115+
- Added `USARTBufferedFunction` functionality
116+
- Renamed to `USARTPolledFunction`
117+
- Renamed to `GPIOFunction`
118+
119+
## L5 - Application
120+
121+
- Updated example with GPIO Input using interrupt and Atomics
122+
- Updated example with USART Buffered RX and TX using interrupts and static stack allocated lock free queues

0 commit comments

Comments
 (0)