Skip to content

Commit

Permalink
addition: added more docs in an unordered manner
Browse files Browse the repository at this point in the history
  • Loading branch information
kiarie404 committed Mar 21, 2024
1 parent 185291f commit 3b07623
Show file tree
Hide file tree
Showing 72 changed files with 1,968 additions and 3,694 deletions.
2 changes: 1 addition & 1 deletion driver_book/book/404.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions driver_book/book/bare_metal/linking/linking.html

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions driver_book/book/bare_metal/linking/rusty_linkers.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/bare_metal/no_std/pracs_1.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/bare_metal/no_std/pracs_2.html

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions driver_book/book/bare_metal/no_std/removing_std_lib.html

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions driver_book/book/bare_metal/no_std/the_no_std_intro.html

Large diffs are not rendered by default.

261 changes: 0 additions & 261 deletions driver_book/book/bare_metal/probing/flashing.html

This file was deleted.

This file was deleted.

This file was deleted.

265 changes: 0 additions & 265 deletions driver_book/book/bare_metal/probing/pracs.html

This file was deleted.

273 changes: 0 additions & 273 deletions driver_book/book/bare_metal/probing/probing_preface.html

This file was deleted.

340 changes: 0 additions & 340 deletions driver_book/book/bare_metal/probing/probing_theory_1.html

This file was deleted.

362 changes: 0 additions & 362 deletions driver_book/book/bare_metal/probing/udev.html

This file was deleted.

14 changes: 8 additions & 6 deletions driver_book/book/bare_metal/the_no_std_preface.html

Large diffs are not rendered by default.

25 changes: 21 additions & 4 deletions driver_book/book/index.html

Large diffs are not rendered by default.

25 changes: 21 additions & 4 deletions driver_book/book/intro/intro.html

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions driver_book/book/intro/prerequisites.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/misc/API.html

Large diffs are not rendered by default.

56 changes: 55 additions & 1 deletion driver_book/book/misc/abi.html

Large diffs are not rendered by default.

287 changes: 287 additions & 0 deletions driver_book/book/misc/building_runtime_crates.html

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion driver_book/book/misc/different_std_libs.html

Large diffs are not rendered by default.

266 changes: 266 additions & 0 deletions driver_book/book/misc/notable_core_crates.html

Large diffs are not rendered by default.

276 changes: 276 additions & 0 deletions driver_book/book/misc/panicking.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/misc/the_C_runtime.html

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions driver_book/book/notable_crates.html

Large diffs are not rendered by default.

898 changes: 279 additions & 619 deletions driver_book/book/print.html

Large diffs are not rendered by default.

319 changes: 0 additions & 319 deletions driver_book/book/registers_and_mmio_programming.html

This file was deleted.

2 changes: 1 addition & 1 deletion driver_book/book/searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/searchindex.json

Large diffs are not rendered by default.

370 changes: 0 additions & 370 deletions driver_book/book/svd2rust.html

This file was deleted.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion driver_book/book/uart_implementations/on_qemu/intro.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions driver_book/book/uart_theory/draft_1.html

Large diffs are not rendered by default.

29 changes: 25 additions & 4 deletions driver_book/book/uart_theory/draft_2.html

Large diffs are not rendered by default.

267 changes: 267 additions & 0 deletions driver_book/book/uart_theory/intro.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

60 changes: 39 additions & 21 deletions driver_book/book/understanding_drivers/providing_an_interface.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions driver_book/book/why_embedded_rust.html

Large diffs are not rendered by default.

26 changes: 15 additions & 11 deletions driver_book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- [Role 1: Controlling the device below](./understanding_drivers/controlling_the_device_below.md)
- [Role 2: Providing an interface](./understanding_drivers/providing_an_interface.md)
- [Types of Drivers](./understanding_drivers/types_of_drivers.md)
- [Kernel and Driver Interaction mechanisms]()


# BARE METAL PROGRAMMING
Expand All @@ -22,7 +21,7 @@
- [Cross-Compilation](./bare_metal/cross_compilation/cross_compilation.md)
- [Linking](./bare_metal/linking/linking.md)
- [Rusty Linkers](./bare_metal/linking/rusty_linkers.md)
- [Probing](./bare_metal/probing/probing_preface.md)
<!-- - [Probing](./bare_metal/probing/probing_preface.md)
- [Probing Theory](./bare_metal/probing/probing_theory_1.md)
- [Probing Pracs](./bare_metal/probing/pracs.md)
- [udev](./bare_metal/probing/udev.md)
Expand All @@ -31,28 +30,29 @@
- [draft_1](./bare_metal/probing/logging_and_monitoring/monitoring_2.md)
- [Debugging]()
- [No-std testing]()
- [Performance testing]()
- [Performance testing]() -->


# ABSTRACTIONS
<!-- # ABSTRACTIONS
- [MMIO programming]()
- [Registers and MMIO programming](./registers_and_mmio_programming.md)
- [The datasheet](./knowing_your_hardware.md)
- [Abstraction]()
- [Abstracting a peripheral](./abstractions/abstracting_a_peripheral.md)
- [svd2rust](./svd2rust.md)
- [vcell](./abstractions/vcell.md)
- [representations](./abstractions/representations.md)
- [random](./abstractions/random.md)
- [random](./abstractions/random.md) -->


# THE UART THEORY
- [Understanding UART Theory]()
- [draft_1](./uart_theory/draft_1.md)
- [draft_2](./uart_theory/draft_2.md)
# THE UART
- [Intro](./uart_theory/intro.md)
- [general overview](./uart_theory/draft_1.md)
- [uart registers](./uart_theory/draft_2.md)
- [Understanding UART physical Implemetation in the esp32]()


# THE UART IMPLEMENTATION (Qemu)
# THE UART IMPLEMENTATION (on Qemu and single-threaded)
- [Intro](./uart_implementations/on_qemu/intro.md)
## Set Ups
- [Setting Things Up](./uart_implementations/on_qemu/setting_things_up.md)
Expand All @@ -67,7 +67,10 @@
- [tutorial over a naive UART implementation on a Esp32 device]()


# THE UART IMPLEMENTATION (less naive, with async)
# THE UART IMPLEMENTATION (less naive, with concurrency in mind)
- [Concurrency]()
- [critical-sections in single-threaded cores]()
- [critical-secions above multi-cores]()
- [tutorial over a naive UART implementation on a Qemu device]()
- [tutorial over a naive UART implementation on a Esp32 device]()

Expand All @@ -85,6 +88,7 @@
# APPENDIX
- [Notable Crates](./notable_crates.md)
- [Notable Learning Resources]()
- [Notable core-crates](./misc/notable_core_crates.md)
- [why use Rust?](./why_embedded_rust.md)
- [Out of topic]()
- [different_std_libs](./misc/different_std_libs.md)
Expand Down
10 changes: 10 additions & 0 deletions driver_book/src/abstractions/abstracting_a_peripheral.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
How does one safely abstract a register?
- well, read this [chapter][rust-embedded-book-peripherals-chapter].







[rust-embedded-book-peripherals-chapter]: undone_add_link
34 changes: 33 additions & 1 deletion driver_book/src/abstractions/random.md
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
- exception attribute with re-entrancy guarantees
- exception attribute with re-entrancy guarantees
- zero-cost abstractions?


### What should our rules be when dealing with peripherl registers?

How can we reliably interact with these peripherals?

- Always use volatile methods to read or write to peripheral memory, as it can change at any time
- In software, we should be able to share any number of read-only accesses to these peripherals
- If some software should have read-write access to a peripheral, it should hold the only reference to that peripheral

We cannot use global mutable variables because they expose our peripheral to every software. We just want one software to have the mutable reference to a single peripheral. Every other software should have read_references.

There should ONLY BE ONE mutable instance of a peripheral.

That is why we use the Singleton.

### Pointer manipulations
Be afraid of implicit copies. Just use ONE value assignation and multiple references when dealing with pointers that point to ONE physical memory address.

As you can see below, x and y have different addresses.
```rust
let x = 10;
let y = x;

println!("Address of x = {}", (&x as *const i32) as usize); // Address of x = 140735333354256
println!("Address of y = {}", (&y as *const i32) as usize); // Address of y = 140735333354260
```


ONE ASSIGNATION, the rest should be references.
TWO ASIGNATIONS result in two different raw addresse....
31 changes: 27 additions & 4 deletions driver_book/src/abstractions/representations.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
## Representation

reference : https://doc.rust-lang.org/nomicon/other-reprs.html

- discuss
- why memory representation is immportant in driver development
- The types of memory representation
- #[repr(rust)]
- #[repr(C)]
- #[repr(transparent)]
- #[repr(u8)], #[repr(u16)], #[repr(u32)]
- #[repr(align)]
- #[repr(u8)], #[repr(u16)], #[repr(u32)] // applied to an enum
- #[repr(align(2))]
- When one should use certain memory representations
- defining accurate register alignments/sizes
- FFI-ing
Expand Down Expand Up @@ -38,8 +40,29 @@ For example:
If the minimum alignment of a type is 8 bytes, it means that any object of that type must be located at a memory address that is divisible by 8.


#### Alignments and how they affect space occupied by data-types
Alignment is not directly related to the space occupied by the data type, but rather to the requirements imposed by the hardware or ABI. However, the alignment can influence the amount of space occupied by data in memory, as padding may be inserted between fields of a struct or at the end of an array to ensure that each element meets the required alignment.
### Alignments and how they affect space occupied by data-types
Alignment is not directly related to the space occupied by the data type. However, the alignment can influence the amount of space occupied by data in memory, as padding may be inserted between fields of a struct or at the end of an array to ensure that each element meets the required alignment.

for example :
```rust

// These two structs occupy different sizes even though they have the same field types.
// This is because struct::s1 has added paddings to help align field_1 to the alignment of 6 ie (2^6 = u64)
// s1 is 16 bytes long
// s2 is 12 bytes long

#[repr(Rust)]
struct s1{
field_1: u32,
field_2: u64
}

#[repr(packed)]
struct s1{
field_1: u32,
field_2: u64
}
```


### repr(transparent)
Expand Down
31 changes: 31 additions & 0 deletions driver_book/src/abstractions/vcell.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,34 @@ Vcell is one of the crates that PAC depends on. In order to understand the PAC,
- Understand how vcell fits into the PAC crate


### What is a cell? Why are we using them?

To wholly understand what a cell is, read up on [core::cell][core_cell_documentation].
I'll try my best to explain a watered-down version of it.

In Rust, core::cell is a module that provides a set of types for interior mutability. **Interior mutability** allows you to mutate data even when you only have an immutable reference to it. This is useful in situations where you need mutability but also need to adhere to Rust's ownership and borrowing rules.

So temporary unrustmanhip.

The types provided are :
- `Cell<T>`
- `RefCell<T>`
- `OneCell<T>`
- Other helper structs/types

These celll enclose types and allow that type to ...
- have multiple `&mut T` and `&T` at the same time
- be mutated through both `&mut T` and `&T` references

But it is not all chaos... there are rules... some rules on how all these mutiple references work together.
1. These types are not multi-thread-safe. They are guaranteed to work ONLY in a single-threaded program. (If you need to do aliasing and mutation among multiple threads, `Mutex<T>`, `RwLock<T>`, `OnceLock<T>` or atomic types are the correct data structures to do so).
2. Under Cell<T>
- a `&mut T` reference to the inner value can NEVER be obtained.
- The inner value `T` cannot just be obtained like that. You have to replace it with another value.
-
3. Under RefCell<T>




[core_cell_documentation]: undone_link
11 changes: 4 additions & 7 deletions driver_book/src/bare_metal/linking/linking.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
# Linking


**SOLID CHOICES** :

Linking is a VERY fundamental topic.

It is best to learn it **slowly** and **in full** from the [docs](#note-worthy-docs). It will be worth it; You will save yourself hundreds of hours in the future if you make the first read intentional. Be patient with yourself, restrain from skimming through the docs if it's your first time.

It is best to learn it **slowly** and **in full** from the [docs](#note-worthy-docs).
For this reason, this book will not spoil or water-down the purity of the [linking docs](#note-worthy-docs).

This book will however :
- assume that you have read [the docs](#note-worthy-docs).
- Briefly explain LLD linker usage in Rust targets
- Briefly explain LLD linker usage in Rust targets.
- Demonstrate how to fix the no-std linking error encountered in the previous chapter
- Demonstrate how to build a full linker script for the Esp32c3 board. (found in a much ater chapter)
- Demonstrate how to build a full linker script for the Esp32c3 board. (found in a much later chapter)
<!-- undone: specify the exact chapter -->



Expand Down
13 changes: 7 additions & 6 deletions driver_book/src/bare_metal/linking/rusty_linkers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ There are many linkers in existence. However the two dominant linkers are :
1. The [LD linker][ld-linker-page] (also called the GNU linker)
2. The [LLD linker][lld-linker-page] (also called the LLVM linker)

The Rust toolchain is a modification of the LLVM toolchain, so it uses the LLVM linker by default. You can however configure it to use ld with the help of Cargo.
The Rust toolchain is a modification of the LLVM toolchain, so it uses the LLVM linker by default. You can however configure it to use the GNU linker with the help of Cargo.

## Subtle but important differences.
## Subtle but important differences between LD and LLD.

### 1. Automatic linker-script generation.
The ld linker ALWAYS requires a manually-defined linker script to function. The LLD (the LLD linker) doesn't always use a manually-defined linker script like LD (the GNU linker).

In many cases, LD.LLD can automatically generate linker scripts internally based on the target architecture, format, and other parameters specified during the linking process. This means that LD.LLD can handle the linking process without requiring an explicit linker script provided by the user.
In many cases, LLD can automatically generate linker scripts internally based on the target architecture, format, and other parameters specified during the linking process. This means that LLD can handle the linking process without requiring an explicit linker script provided by the user.

However, LD.LLD does provide options to allow users to specify custom linker scripts if needed. Users can pass a custom linker script to LD.LLD using command-line options or configuration files, similar to how it's done with LD. This gives users flexibility in defining the linking behavior and organizing the output binary according to their specific requirements.
However, LLD does provide options to allow users to specify custom linker scripts if needed. Users can pass a custom linker script to LLD using command-line options or configuration files, similar to how it's done with LD. This gives users flexibility in defining the linking behavior and organizing the output binary according to their specific requirements.

### 2. Cross linking and the existence of flavours
The ld linker is a monolith. There is only one ld linker. If you want to compile something into an elf, you supply the linker with an elf-generating linker script. If you need a wasm binary file, you supply it with a corresponding linker script.
Expand All @@ -32,9 +32,10 @@ There are currently 4 lld flavours :

## Implications of those subtle differences

Adding a target using the `rustup target add` literally adds a LLVM back-end that includes an LLD-flavour configured for the subject target. Declaring linker scripts is optional.
1. Declaring linker scripts is optional.
2. Adding a target using the `rustup target add` literally adds a LLVM back-end that includes an LLD-flavour configured for the subject target. Declaring linker scripts is optional.

To view the defult lld flavour of a supproted target, run the following command :
To view the defult lld flavour of a supported target, run the following command :
```bash
# Replace `riscv32i-unknown-none-elf` with a target of your liking
rustc -Z unstable-options --target riscv32i-unknown-none-elf --print target-spec-json
Expand Down
5 changes: 4 additions & 1 deletion driver_book/src/bare_metal/no_std/removing_std_lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ So each OS needs to provide implementations for all those common functions.

For example, the standard library declares the thread_spawn function. Linux OS provides an implementation of that function that is different from the Windows implementation... provided they all do the same thing.

So when you write drivers, you cannot use the standard library. But you can use the core-library.
So when you write drivers, you cannot use the standard library. But you can use the [core-library][lib-core-documentation].

How's that possible? How are we able to use the core library on bare metal?
well...Lib-core functions can be **directly** compiled to assembly and machine code without having to depend on OS-system files. Lib-core is dependency-free.


Losing the std library means you forget about threads, files, heap memory, the network, random numbers, standard output, or any other features requiring OS abstractions or specific hardware. If you need them, you have to implement them yourself. The table below summarizes what you lose...
Expand Down
4 changes: 3 additions & 1 deletion driver_book/src/bare_metal/no_std/the_no_std_intro.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# No Std

Most rust programs depend on the standard library by default, including that simple 'hello world' you once wrote. The standard library on the other hand is dependent on the underlying operaring system or execution environment.
For example, the body of `std::println!` contains lines that call OS-defined functions.

Drivers provide an interface for the OS to use, meaning that the OS depends on drivers... as a result, you have to write the driver code without the help of the OS-dependent Standard Library. This paragraph sounds like a riddle ha ha... but you get the point... to write a driver, you have to forget about help from the typical std library. That std library depends on your driver code... that std library depends on you.

Drivers provide an interface for the OS to use, meaning that the OS depends on drivers... as a result, you have to write the driver code without the help of the OS-dependent Standard Library. This paragraph sounds like a riddle ha ha... but you get the point... to write a driver, you have to forget about help from the typical std library. That std library depends on your driver code... **that std library depends on you**.

When software does not depend on the standard library, it is said to be a bare-metal program. It can just be loaded to memory and the physical CPU will execute it as it is.

Expand Down
22 changes: 11 additions & 11 deletions driver_book/src/bare_metal/probing/probing_preface.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Probing

Probing is the act of interacting with the microcotroller via a debug adapter with the aim of doing at least one of the following...
1. Flashing a compiled program onto the RAM or ROM of the microcontroller.
2. Performing some In-system programming
3. Debugging the running program
Probing is the act of interacting with the microcotroller with the aim of doing at least one of the following...
1. Flashing a compiled program onto the RAM or ROM of the microcontroller. ie. writing your code into the RAM or ROM... breathing life into the machine.

2. Performing some In-system programming ie. literally manipulating the values found in the processor's registers and occasionaly reading and writing to memory.

3. Debugging the running program : Observing the how the program state changes in a step by step fashion.

4. Testing the functionality of the microcrontroller

This chapter walks through the first 3 tasks while assuming that...
- Your host machine is a linux box
This chapter walks through the theory behind first 3 tasks while assuming that...
- Your host machine is a linux box
- Your target machine is an esp32c3 SoC.

This chapter has also been divided into two :
- The theory behind probing
- The practicals

You choose how you'd like to read through it.
The practicals will be covered in a later chapter.
<!-- undone: Specify the actua chapter -->
Loading

0 comments on commit 3b07623

Please sign in to comment.