Closed japaric closed 5 years ago
I'm interested in having RTFM for RISC-V, however I need to understand possible RISC-V-related limitations and how to deal with them (if possible).
P.S. I'm not quite familiar with RTFM, so I need to study it first in detail.
I need to view @korken89's presentation on RTFM before I could meaningfully contribute a port, but I am very interested and supportive of this proposal.
This would also be a good opportunity to flesh out what features are feasible to support on archs more constrained than cortex-m
(e.g. msp430 has nowhere near the amount of priority levels NVIC does).
@Disasm I have a prototype implementation that targets the HiFive1 board here. The prototype implements the core API plus the schedule
and #[interrupt]
extensions.
IRQs are different and defined on device-level and even may not exists at all.
Even if you have zero IRQs, you can use the (machine) software (MSI) / timer (MTI) interrupt to implement (software) tasks.
We have priorities only for IRQs
But you can individually mask interrupts (MSIE, MTIE, etc.); it's possible to implement some form of prioritization (and critical sections) using interrupt masking.
SMP (not AMP) support on some chips.
(I have one of those K210 chips; too bad my "development" board has no on-board debugger (and I have no JTAG probe around) so I can't actually do any actual development on it ...)
Timers are accessed in a device-dependent way.
mtime
and mtimecmp
seem rather standard to me. They may be memory mapped registers and their address may be device-dependent but their binary interface and semantics are well specified. In any case, timers are not necessary to implement the core API.
Some "devices" are FPGA softcores that do not have Privileged Architecture parts at all.
We could state that some privileged parts are required to use RTFM on RISCV. If the softcore has zero support for interrupts / preemption then we can't run RTFM on it.
@japaric Thanks for making the prototype!
too bad my "development" board has no on-board debugger (and I have no JTAG probe around)
I use BusBlaster based on FTDI chip, but I think that any JTAG adapter for FPGA would work.
mtime
andmtimecmp
seem rather standard to me. They may be memory mapped registers and their address may be device-dependent but their binary interface and semantics are well specified. In any case, timers are not necessary to implement the core API.
They are standard, but due to their device-dependent addressing I have no idea how to pass them to the RTFM implementation. Of cause, we could tie riscv-rtfm
to the FE310 chip family, but this solution is far from perfect.
@Disasm
They are standard, but due to their device-dependent addressing I have no idea how to pass them to the RTFM implementation.
As part of the prototype I wrote a riscv
crate from scratch (to force me to read the RISC-V spec). That crate contains an API to access the mtime
and mtimecmp
registers. To get around the device specific address I used symbols. In the riscv
crate the address of the mtime
register is an external symbol; this symbol must be provided by a device crate (PAC) like the hifive1
crate in that repository.
With this approach any crate can use the mtime
register by depending only on riscv
and not on any particular device crate. When building an application where the mtime
API is used a device crate must appear in the dependency graph or you get a not really helpful error. The symbol, and the device crate, don't need to appear in the dependency graph when building libraries that use the mtime
API.
There are other ways to pass device specific information to the RTFM runtime though. The Cortex-M port uses a device
argument, which is a path to a module, in its #[app]
attribute. This module is expected to contain an enumeration of all interrupts (Interrupt
), the number of priority bits (const NVIC_PRIO_BITS: u8
), etc. It's also possible for ports to define other custom #[app]
arguments. One example is the monotonic
argument proposed in RFC #200.
I think this is a great idea! The power that SRP gives through this framework should fit a lot more than Cortex-M, and this is indeed a great way to get there. I also hope that something like this would help with the readability of the code, as this is quite a challenge today.
This proposal has been well received so I'm going to FCP it with disposition to merge it.
We can start right away with the refactor and take our time to roll out the org. (One extra thing I'd like to do is create an rfcs repo and archive all these RFCs as proper markdown files).
OK for me
:tada: This RFC has been formally approved. The refactor part is in PR #205.
Done in PR #205
Current state
cortex-m-rtfm
is the main port of the RTFM framework. There are two outdated ports of RTFM for MSP430 and RISCV and two experimental Cortex-R and Linux ports. None of these ports shares code with one another so they have diverged or stalled since their inception.The
cortex-m-rtfm
port is under @japaric's GitHub account and currently has 3 people maintaining it.Proposal
This RFC proposes refactoring out the RTFM syntax (meta-language) and analysis pass that currently live in
cortex-m-rtfm
into a crate that can be used to easily implement ports for different architectures.Rationale
We want to make RTFM available on as many architectures as possible with minimal maintenance effort and with as similar APIs / syntax as possible.
Detailed design
This RFC proposes the following crate hierarchy:
rtfm-core
This crate will only contain the
Mutex
trait and theExclusive
newtype and it's meant to be used to implement generic library code.rtfm-syntax
This crate will contain the parser of the
#[app]
and the analysis pass (e.g. priority ceiling analysis) of the RTFM specification.The main function in this crate is the
parse
function which parse the input of the#[app]
attribute.To accommodate the different capabilities of the many RTFM ports this function takes a
Settings
struct that indicates which extensions the port implements.$ARCH-rtfm
These are the actual ports. These crates will use the
rtfm-syntax
crate to implement the#[app]
attribute and they'll re-export thertfm-core
API.All ports must implement the following API:
lock
API#[task]
s andspawn
APIAnd they may implement any of these extensions:
#[exception]
API#[interrupt]
APIschedule
APImulti-core support
GitHub org
All these crates will be owned by the
rtfm-rs
GitHub organization and maintained by the members of the organization. The idea is to grow the membership of the organization to include people with expertise on architectures other than ARM Cortex-M.I have already done the refactor and have tested the portability of the
rtfm-syntax
crate by implementing a Linux port (base features +schedule
+ multi-core support) and the single-core and multi-core variants ofcortex-m-rtfm
(see PR #205).cc'ing people that may be interested in other ports:
@disasm (rust-embedded/riscv) @cr1901 @pftbest (rust-embedded/msp430)