Skip to content
Snippets Groups Projects
Commit a32bd930 authored by Per Lindgren's avatar Per Lindgren
Browse files

Initial commit

parents
Branches
No related tags found
No related merge requests found
[target.thumbv6m-none-eabi]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=true",
"-Z", "linker-flavor=ld",
]
[target.thumbv7m-none-eabi]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[target.thumbv7em-none-eabi]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[target.thumbv7em-none-eabihf]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[build]
target = "thumbv7em-none-eabihf"
\ No newline at end of file
[Dolphin]
Timestamp=2017,12,27,22,4,55
Version=4
ViewMode=1
[Settings]
HiddenFilesShown=true
**/*.rs.bk
*.org
.gdb_history
Cargo.lock
target/
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "gdb",
"request": "attach",
"name": "Debug",
"gdbpath": "/usr/bin/arm-none-eabi-gdb",
"executable": "./target/thumbv7em-none-eabihf/debug/app",
"target": ":3333",
"remote": true,
"autorun": [
"monitor reset init",
"monitor arm semihosting enable",
"monitor tpiu config internal /tmp/itm.log uart off 64000000",
"monitor itm port 0 on",
"load",
"monitor reset init"
],
"cwd": "${workspaceRoot}"
},
{
"type": "gdb",
"request": "attach",
"name": "Release",
"gdbpath": "/usr/bin/arm-none-eabi-gdb",
"executable": "./target/thumbv7em-none-eabihf/release/app",
"target": ":3333",
"remote": true,
"autorun": [
"monitor reset init",
"monitor arm semihosting enable",
"monitor tpiu config internal /tmp/itm.log uart off 64000000",
"monitor itm port 0 on",
"load",
"monitor reset init"
],
"cwd": "${workspaceRoot}"
},
]
}
\ No newline at end of file
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "xargo build",
"command": "xargo",
"args": [
"build"
],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "xargo build --release",
"command": "xargo",
"args": [
"build --release"
],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
\ No newline at end of file
[package]
authors = [
"Per Lindgren <per.lindgren@ltu.se>",
]
categories = ["concurrency", "embedded", "no-std"]
description = "Real Time For the Masses (RTFM) framework for ARM Cortex-M microcontrollers"
documentation = "https://docs.rs/cortex-m-rtfm"
keywords = ["arm", "cortex-m"]
license = "MIT OR Apache-2.0"
name = "app"
repository = "https://github.com/japaric/cortex-m-rtfm"
version = "0.1.0"
[dependencies]
cortex-m-rtfm = "0.2.2"
cortex-m = "0.3.1"
rtfm-core = "0.1.0"
cortex-m-semihosting = "0.2.0"
[dependencies.cortex-m-debug]
version = "0.1.0"
path = "../cortex-m-debug"
[dependencies.cortex-m-rt]
features = ["abort-on-panic"]
version = "0.3.3"
[dependencies.stm32f413]
path = "../stm32f413"
features = ["rt"]
version = "0.1.0"
[features]
wcet_bkpt = []
wcet_nop = []
[profile.release]
lto = true
debug = true
README.md 0 → 100644
[![crates.io](https://img.shields.io/crates/v/cortex-m-rtfm.svg)](https://crates.io/crates/cortex-m-rtfm)
[![crates.io](https://img.shields.io/crates/d/cortex-m-rtfm.svg)](https://crates.io/crates/cortex-m-rtfm)
# `rtfm-app`
> Real Time For the Masses (RTFM) framework for ARM Cortex-M microcontrollers
# [Documentation](https://docs.rs/cortex-m-rtfm)
# Features
This is a minimalistic crate useful as a template for your own projects.
It comprises:
- an `app!` system configuration with three task with two shared resources.
- the use of the `cortex-m-debug` crate for simple tracing over `itm` and `semihosting`
- `vscode` integration:
- Task configurations: `ctrl-shift-b` for building (Debug/Release)
- Launch configurations: `ctrl-shift-d` for entering Debug. Select (Debug/Release) and press arrow to start.
- a file `r` demonstrating `gdb` automation.
# Requirements
- The `Native Debug` extension.
- A running `gdb` server (e.g., `openocd`), connecting on port 3333.
- `ITM` tracing truogh the file `/tmp/itm.log`.
- Access to `arm-none-eabi-gdb`.
# Openocd
Start `openocd` in a terminal window. (Status and semihosting output is visible here.)
> openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
The configuration broken down:
- `stlink.cfg` defines the specifics for the STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1 in-circuit debugger/programmerprogrammer interface.
``` txt
interface hla
hla_layout stlink
hla_device_desc "ST-LINK"
hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b
```
`hla` relates to the interface driver (low level *transport* in between `openocd` and the st-link programmer).
- `stm32f4x.cfg` is a script for the stm32f4x family, defining memory areas etc. It also defines the handling of `events`, e.g.,
- `trace-config` - enbling tracing.
- `reset-start` - requesting adapter speed to a (conservative) 2000khz (actual speed will be negotiated).
- `reset-init` - setting the CPU to 64Mhz (its 16Mhz by default), and requesting adapter speed to 8000khz (actual speed will be negotiated).
- `examine-end` - debug behavior:
- Enable debug during low power modes (uses more power).
- Stop watchdog counters during halt.
# Launch configuration
``` txt
{
"type": "gdb",
"request": "attach",
"name": "Debug",
"gdbpath": "/usr/bin/arm-none-eabi-gdb",
"executable": "./target/thumbv7em-none-eabihf/debug/app",
"target": ":3333",
"remote": true,
"autorun": [
"monitor reset init",
"monitor arm semihosting enable",
"monitor tpiu config internal /tmp/itm.log uart off 64000000",
"monitor itm port 0 on",
"load",
"monitor reset init"
],
"cwd": "${workspaceRoot}"
},
...
}
```
The autorun script broken down:
- `monitor reset init`
Halts the processor and applies the `reset-init` configuration.
- `monitor arm semihosting enable`
Enables `semihosting` (`breakpoint` handling for semihosting).
- `monitor tpiu config internal /tmp/itm.log uart off 64000000`
- `monitor itm port 0 on`
Enables `itm` debugging assuming a clock speed of 64Mhz.
- `load`
Loads the binary (set in "executable": "./target/thumbv7em-none-eabihf/debug/app") to the target. `load` performs a `reset-start` after finishing.
- `monitor reset init`
Set the MCU to 64Mhz (again).
# GDB
The `gdb` tool allows to program and debug the target, e.g., set breakpoints, inspect memory, etc. `gdb` can be highly automated through scripting. In the `DEBUG` console you can interact directly with `gdb`. The integration between the console and `vscode` is rudimentary. The `vscode` `Native Debug` view is in general not notified/updated (by stepping/continuing through `vscode` icons/shortcuts the view gets in synch). Even so, manual interaction with `gdb` can be very useful, an example is to restart the program without reloading it (there is no shortcut/icon for this functionality in the `Native Debug` extension). Enter in the `DEBUG` console:
> source() r
or simply:
> so r
`gdb` commands can typically be abbreviated, in this case `so` for `source`. Notice, you may run `gdb` (`arm-none-eabi-gdb`) directly in a terminal, in this case you get a both tabbing of commands and history (e.g., pressing enter repeats the last command).
The content of the file `r` is simply:
``` txt
monitor reset init
```
# License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
[dependencies.core]
stage = 0
[dependencies.compiler_builtins]
stage = 1
\ No newline at end of file
/* STM32F103C8V6 */
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}
r 0 → 100644
monitor reset init
\ No newline at end of file
[Dolphin]
Timestamp=2017,12,27,22,2,41
Version=4
ViewMode=1
//! Nesting claims and how the preemption threshold works
//!
//! If you run this program you'll hit the breakpoints as indicated by the
//! letters in the comments: A, then B, then C, etc.
#![deny(unsafe_code)]
#![feature(proc_macro)]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rtfm as rtfm;
extern crate stm32f413;
#[macro_use]
extern crate cortex_m_debug;
use stm32f413::Interrupt;
use rtfm::{app, Resource, Threshold};
app! {
device: stm32f413,
resources: {
static LOW: u64 = 0;
static HIGH: u64 = 0;
},
tasks: {
EXTI0: {
path: exti0,
priority: 1,
resources: [LOW, HIGH],
},
EXTI1: {
path: exti1,
priority: 2,
resources: [LOW],
},
EXTI2: {
path: exti2,
priority: 3,
resources: [HIGH],
},
},
}
fn init(p: init::Peripherals, _r: init::Resources) {
//iprintln!(&p.ITM.stim[0], "Hello ITM");
ipln!("Hello nasty");
ipln!();
ipln!("Well it's...");
ipln!("{} cups of coffee ...", 50);
sprintln!("Hello Semihosting");
rtfm::bkpt();
}
#[inline(never)]
fn idle() -> ! {
// A
let mut t = 0;
rtfm::bkpt();
t += 1;
// Sets task `exti0` as pending
//
// Because `exti0` has higher priority than `idle` it will be executed
// immediately
rtfm::set_pending(Interrupt::EXTI0); // ~> exti0
loop {
rtfm::wfi();
}
}
#[allow(non_snake_case)]
fn exti0(t: &mut Threshold, EXTI0::Resources { mut LOW, mut HIGH }: EXTI0::Resources) {
// Because this task has a priority of 1 the preemption threshold `t` also
// starts at 1
// B
rtfm::bkpt();
// Because `exti1` has higher priority than `exti0` it can preempt it
rtfm::set_pending(Interrupt::EXTI1); // ~> exti1
// A claim creates a critical section
LOW.claim_mut(t, |_low, t| {
// This claim increases the preemption threshold to 2
//
// 2 is just high enough to not race with task `exti1` for access to the
// `LOW` resource
// D
rtfm::bkpt();
// Now `exti1` can't preempt this task because its priority is equal to
// the current preemption threshold
rtfm::set_pending(Interrupt::EXTI1);
// But `exti2` can, because its priority is higher than the current
// preemption threshold
rtfm::set_pending(Interrupt::EXTI2); // ~> exti2
// F
rtfm::bkpt();
// Claims can be nested
HIGH.claim_mut(t, |_high, _| {
// This claim increases the preemption threshold to 3
// Now `exti2` can't preempt this task
rtfm::set_pending(Interrupt::EXTI2);
// G
rtfm::bkpt();
});
// Upon leaving the critical section the preemption threshold drops back
// to 2 and `exti2` immediately preempts this task
// ~> exti2
// I
// After excecution of exti2 we now return to the exti0 task
rtfm::bkpt();
});
// Once again the preemption threshold drops but this time to 1. Now the
// pending `exti1` task can preempt this task
// ~> exti1
// K
rtfm::bkpt();
}
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {
// C, J
rtfm::bkpt();
}
fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {
// E, H
rtfm::bkpt();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment