-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import app docs from the arceos main repo
- Loading branch information
1 parent
8c86c36
commit a47dd3a
Showing
19 changed files
with
1,458 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# INTRODUCTION | ||
| App | Enabled features | Extra modules | Description | | ||
|-|-|-|-| | ||
| [display](../rust/display/) | display | axdriver, axdisplay | Graphic/GUI test | | ||
|
||
# RUN | ||
|
||
```bash | ||
make A=rust/display GRAPHIC=y LOG=debug run | ||
``` | ||
|
||
# RESULT | ||
|
||
```text | ||
... | ||
[ 0.408067 axdriver:59] Initialize device drivers... | ||
[ 0.410941 driver_virtio:50] Detected virtio MMIO device with vendor id: 0x554D4551, device type: GPU, version: Legacy | ||
[ 0.414473 virtio_drivers::device::gpu:47] Device features EDID | NOTIFY_ON_EMPTY | ANY_LAYOUT | RING_INDIRECT_DESC | RING_EVENT_IDX | ||
[ 0.418886 virtio_drivers::device::gpu:57] events_read: 0x0, num_scanouts: 0x1 | ||
[ 0.423408 virtio_drivers::device::gpu:102] => RespDisplayInfo { header: CtrlHeader { hdr_type: Command(4353), flags: 0, fence_id: 0, ctx_id: 0, _padding: 0 }, rect: Rect { x: 0, y: 0, width: 1280, height: 800 }, enabled: 1, flags: 0 } | ||
[ 0.452037 axdriver::virtio:88] created a new Display device: "virtio-gpu" | ||
[ 0.455473 axdisplay:17] Initialize Display subsystem... | ||
[ 0.458124 axdisplay:19] number of Displays: 1 | ||
... | ||
... | ||
... | ||
(never end) | ||
``` | ||
![display](figures/display.png) | ||
|
||
# STEPS | ||
|
||
## step1 | ||
|
||
``` rust | ||
let mut board = DrawingBoard::new(); | ||
board.disp.clear(Rgb888::BLACK).unwrap(); | ||
``` | ||
|
||
**flow chart** | ||
```mermaid | ||
graph TD; | ||
A["DrawingBoard::new()"] --> B["display::Display::new()"]; | ||
A --> C["embedded_graphics::prelude::Point::new(INIT_X, INIT_Y)"]; | ||
B --> D["libax::display::framebuffer_info"] | ||
B --> E["core::slice::from_raw_parts_mut"] | ||
B --> F["embedded_graphics::prelude::Size::new"] | ||
D --> G["axsync::Mutex(axdriver::DisplayDevices)::lock"] | ||
D --> H["axdriver::DisplayDevices::info"] | ||
``` | ||
|
||
## step2 | ||
``` rust | ||
for _ in 0..5 { | ||
board.latest_pos.x += RECT_SIZE as i32 + 20; | ||
board.paint(); | ||
framebuffer_flush(); | ||
} | ||
... | ||
impl DrawingBoard { | ||
... | ||
fn paint(&mut self) { | ||
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE)) | ||
.into_styled(PrimitiveStyle::with_stroke(Rgb888::RED, 10)) | ||
.draw(&mut self.disp) | ||
.ok(); | ||
Circle::new(self.latest_pos + Point::new(-70, -300), 150) | ||
.into_styled(PrimitiveStyle::with_fill(Rgb888::BLUE)) | ||
.draw(&mut self.disp) | ||
.ok(); | ||
Triangle::new( | ||
self.latest_pos + Point::new(0, 150), | ||
self.latest_pos + Point::new(80, 200), | ||
self.latest_pos + Point::new(-120, 300), | ||
) | ||
.into_styled(PrimitiveStyle::with_stroke(Rgb888::GREEN, 10)) | ||
.draw(&mut self.disp) | ||
.ok(); | ||
let text = "ArceOS"; | ||
Text::with_alignment( | ||
text, | ||
self.latest_pos + Point::new(0, 300), | ||
MonoTextStyle::new(&FONT_10X20, Rgb888::YELLOW), | ||
Alignment::Center, | ||
) | ||
.draw(&mut self.disp) | ||
.ok(); | ||
} | ||
} | ||
``` | ||
|
||
**flow chart** | ||
```mermaid | ||
graph TD; | ||
A["DrawingBoard::paint"] --> B["embedded_graphics::primitives::{Circle, PrimitiveStyle, Rectangle, Triangle}"]; | ||
A --> C["embedded_graphics::text::{Alignment, Text}"] | ||
B --> D["impl embedded_graphics::draw_target::DrawTarget, embedded_graphics::prelude::OriginDimensions for Display"] | ||
C --> D | ||
``` | ||
|
||
## step3 | ||
``` rust | ||
loop { | ||
core::hint::spin_loop(); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# INTRODUCTION | ||
|
||
| App | Enabled features | Extra modules | Description | | ||
|-|-|-|-| | ||
| [echoserver](../rust/net/echoserver/) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded TCP server that reverses messages sent by the client | | ||
|
||
# RUN | ||
|
||
```console | ||
$ make A=rust/net/echoserver NET=y run | ||
... | ||
Hello, echo server! | ||
listen on: 10.0.2.15:5555 | ||
``` | ||
|
||
In another shell, use `telnet` (or `nc`) to connect to localhost (`127.0.0.1`) to view the reversed echo message: | ||
|
||
```console | ||
$ telnet localhost 5555 | ||
Trying 127.0.0.1... | ||
Connected to localhost. | ||
Escape character is '^]'. | ||
hello | ||
olleh | ||
12345 | ||
54321 | ||
``` | ||
|
||
```console | ||
$ nc 127.0.0.1 5555 | ||
hello | ||
olleh | ||
12345 | ||
54321 | ||
``` | ||
|
||
# STEPS | ||
|
||
## step1 | ||
|
||
[init](./init.md) | ||
|
||
After executed all initial actions, then arceos calls `main` function in `echoserver` app. | ||
|
||
## step2 | ||
|
||
`main` calls `accept_loop()`, which will keep processing incoming tcp connection. | ||
|
||
```rust | ||
let (addr, port) = (IpAddr::from_str(LOCAL_IP).unwrap(), LOCAL_PORT); | ||
let mut listener = TcpListener::bind((addr, port).into())?; | ||
println!("listen on: {}", listener.local_addr().unwrap()); | ||
|
||
let mut i = 0; | ||
loop { | ||
match listener.accept() { | ||
... | ||
} | ||
Err(e) => return Err(e), | ||
} | ||
i += 1; | ||
} | ||
``` | ||
|
||
## step3 | ||
|
||
Once it receives a tcp connection. It will get a `(stream, addr)` pair from `libax::net`. | ||
`main` task will spawn a task to reverse every package it receives. | ||
|
||
```rust | ||
Ok((stream, addr)) => { | ||
info!("new client {}: {}", i, addr); | ||
task::spawn(move || match echo_server(stream) { | ||
Err(e) => error!("client connection error: {:?}", e), | ||
Ok(()) => info!("client {} closed successfully", i), | ||
}); | ||
} | ||
``` | ||
|
||
## step4 | ||
|
||
Reverse bytes in package it receives. | ||
|
||
```rust | ||
fn reverse(buf: &[u8]) -> Vec<u8> { | ||
let mut lines = buf | ||
.split(|&b| b == b'\n') | ||
.map(Vec::from) | ||
.collect::<Vec<_>>(); | ||
for line in lines.iter_mut() { | ||
line.reverse(); | ||
} | ||
lines.join(&b'\n') | ||
} | ||
|
||
fn echo_server(mut stream: TcpStream) -> io::Result { | ||
let mut buf = [0u8; 1024]; | ||
loop { | ||
let n = stream.read(&mut buf)?; | ||
if n == 0 { | ||
return Ok(()); | ||
} | ||
stream.write_all(reverse(&buf[..n]).as_slice())?; | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# INTRODUCTION | ||
|
||
| App | Enabled features | Extra modules | Description | | ||
|-|-|-|-| | ||
| [exception](../rust/exception/) | | | Exception handling test | | ||
|
||
# RUN | ||
|
||
```console | ||
$ make A=rust/exception LOG=debug run | ||
... | ||
Running exception tests... | ||
[ 0.249873 0 axhal::arch::riscv::trap:13] Exception(Breakpoint) @ 0xffffffc0802001e8 | ||
Exception tests run OK! | ||
[ 0.068358 0 axtask::api:6] main task exited: exit_code=0 | ||
[ 0.069128 0 axhal::platform::qemu_virt_riscv::misc:2] Shutting down... | ||
``` | ||
|
||
# STEPS | ||
|
||
## step1 | ||
|
||
[init](./init.md) | ||
|
||
After executed all initial actions, then arceos calls `main` function in `exception` app. | ||
|
||
## step2 | ||
|
||
``` Rust | ||
fn raise_break_exception() { | ||
unsafe { | ||
#[cfg(target_arch = "x86_64")] | ||
asm!("int3"); | ||
#[cfg(target_arch = "aarch64")] | ||
asm!("brk #0"); | ||
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] | ||
asm!("ebreak"); | ||
} | ||
} | ||
|
||
#[no_mangle] | ||
fn main() { | ||
println!("Running exception tests..."); | ||
raise_break_exception(); | ||
println!("Exception tests run OK!"); | ||
} | ||
``` | ||
|
||
**flow chart** | ||
|
||
```mermaid | ||
graph TD; | ||
A[" asm!(ebreak)"] --> B["raise exception"]; | ||
B --> C["axhal::arch::riscv::trap.S::trap_vector_base"]; | ||
C --> D["switch sscratch and sp"]; | ||
C -- "from U mode" --> E["Ltrap_entry_u: SAVE_REGS 1; a1 <-- 1"]; | ||
C -- "from S mode" --> F["Ltrap_entry_s: SAVE_REGS 0; a1 <-- 0"]; | ||
E --> G[axhal::arch::riscv::trap::riscv_trap_handler]; | ||
F --> G; | ||
G -- "Trap::Exception(E::Breakpoint)" --> H["handle_breakpoint(&mut tf.sepc)"]; | ||
H --> I["debug!(Exception(Breakpoint) @ {:#x} , sepc);*sepc += 2;"]; | ||
I -- "from U mode" --> J["Ltrap_entry_u: RESTORE_REGS 1"]; | ||
I -- "from S mode" --> K["Ltrap_entry_s: RESTORE_REGS 0"]; | ||
J --> L[sret]; | ||
K --> L; | ||
``` |
Oops, something went wrong.