This repository has been archived by the owner on Jul 6, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 100
Platform Tree parser documentation
Vladimir Pouzanov edited this page Jul 15, 2014
·
3 revisions
Here's how PT generation for platformtree!()
macro works.
-
Parser converts the token stream to node::PlatformTree object.
node::PlatformTree
contains all the nodes for the PT and an additional name-based index. -
node::PlatformTree
is passed to Builder::build(). - Builder verifies that top-level nodes are
mcu
,os
anddrivers
. - Builder calls attach for
mcu
node first. -
attach
function finds the actualattach
implementation for mcu based on the node name and forwards the call, or sets the materializer to one that generates error. - Builder calls attach for
os
anddrivers
. - Builder walks over all the nodes in the order of appearance and calls mutators if they are present.
- Builder walks over all the dependencies of
mcu::clock
and calls materializers.
Now, the process specifically for lpc17xx mcu. What happens in materializers.
For each child node in mcu, attach sets the dependency (so that mcu
node depends on child nodes) and calls the corresponding materializer.
-
attach
for clock just binds the materializer.mcu::clock
is the primary node that always must be present in PT, everything else depends on it. - When called, materializer for clock verifies node arguments, and resolves all the required values.
- It must verify that the clock config is reasonable (this code is missing).
- It modifies the node by providing
system_frequency
attribute. Other nodes can use it to figure out the system clock. - Next it generates the code item that will be part of the main function.
quote_expr!() helps a lot in here
. Note that you should use simple data structures here and make sure that they get inlined. Use common rust pattern ofnew
functions. Try to do all validations in here and skip them in runtime part of the code. Runtime code must be marked asunsafe
then. - Back from clock, we're moving on to timer. It has a trivial materializer that just verifies the correctness of root
timer
node, actual work is node in subnodes. -
Timer
node emits an usable item — the instance of a timer. To do that it first sets the item type name, which must be full-qualified. - It uses a
let
statement to create a local variable. Using node name for variable name is always safe. - Next, UART node. UART depends on rx and tx pins but also needs to set those pins up before they are materialized. It uses a mutator for that. Note that it still resolves all other dependencies.
- When mutator is called, it sets up pin
direction
andfunction
attributes. That's why there's no need to configure those pins in PT source.
TODO: write about how os
node is materialized.