arceos_api/lib.rs
1//! Public APIs and types for [ArceOS] modules
2//!
3//! [ArceOS]: https://github.com/arceos-org/arceos
4
5#![no_std]
6#![feature(doc_auto_cfg)]
7#![feature(doc_cfg)]
8#![allow(unused_imports)]
9
10#[cfg(any(
11 feature = "alloc",
12 feature = "fs",
13 feature = "net",
14 feature = "multitask",
15 feature = "dummy-if-not-enabled"
16))]
17extern crate alloc;
18
19#[macro_use]
20mod macros;
21mod imp;
22
23pub use axerrno::{AxError, AxResult};
24
25/// Platform-specific constants and parameters.
26pub mod config {
27 pub use axconfig::*;
28}
29
30/// System operations.
31pub mod sys {
32 define_api! {
33 /// Shutdown the whole system and all CPUs.
34 pub fn ax_terminate() -> !;
35 }
36}
37
38/// Time-related operations.
39pub mod time {
40 define_api_type! {
41 pub type AxTimeValue;
42 }
43
44 define_api! {
45 /// Returns the time elapsed since system boot.
46 pub fn ax_monotonic_time() -> AxTimeValue;
47 /// Returns the time elapsed since epoch, also known as realtime.
48 pub fn ax_wall_time() -> AxTimeValue;
49 }
50}
51
52/// Memory management.
53pub mod mem {
54 use core::{alloc::Layout, ptr::NonNull};
55
56 define_api! {
57 @cfg "alloc";
58 /// Allocates a continuous memory blocks with the given `layout` in
59 /// the global allocator.
60 ///
61 /// Returns [`None`] if the allocation fails.
62 ///
63 /// # Safety
64 ///
65 /// This function is unsafe because it requires users to manually manage
66 /// the buffer life cycle.
67 pub unsafe fn ax_alloc(layout: Layout) -> Option<NonNull<u8>>;
68 /// Deallocates the memory block at the given `ptr` pointer with the given
69 /// `layout`, which should be allocated by [`ax_alloc`].
70 ///
71 /// # Safety
72 ///
73 /// This function is unsafe because it requires users to manually manage
74 /// the buffer life cycle.
75 pub unsafe fn ax_dealloc(ptr: NonNull<u8>, layout: Layout);
76 }
77
78 define_api_type! {
79 @cfg "dma";
80 pub type DMAInfo;
81 }
82
83 define_api! {
84 @cfg "dma";
85 /// Allocates **coherent** memory that meets Direct Memory Access (DMA)
86 /// requirements.
87 ///
88 /// Returns [`None`] if the allocation fails.
89 ///
90 /// # Safety
91 ///
92 /// This function is unsafe because it requires users to manually manage
93 /// the buffer life cycle.
94 pub unsafe fn ax_alloc_coherent(layout: Layout) -> Option<DMAInfo>;
95 /// Deallocates coherent memory previously allocated.
96 ///
97 /// # Safety
98 ///
99 /// This function is unsafe because it requires users to manually manage
100 /// the buffer life cycle.
101 pub unsafe fn ax_dealloc_coherent(dma: DMAInfo, layout: Layout);
102 }
103}
104
105/// Standard input and output.
106pub mod stdio {
107 use core::fmt;
108 define_api! {
109 /// Reads a slice of bytes from the console, returns the number of bytes written.
110 pub fn ax_console_read_bytes(buf: &mut [u8]) -> crate::AxResult<usize>;
111 /// Writes a slice of bytes to the console, returns the number of bytes written.
112 pub fn ax_console_write_bytes(buf: &[u8]) -> crate::AxResult<usize>;
113 /// Writes a formatted string to the console.
114 pub fn ax_console_write_fmt(args: fmt::Arguments) -> fmt::Result;
115 }
116}
117
118/// Multi-threading management.
119pub mod task {
120 define_api_type! {
121 @cfg "multitask";
122 pub type AxTaskHandle;
123 pub type AxWaitQueueHandle;
124 pub type AxCpuMask;
125 }
126
127 define_api! {
128 /// Current task is going to sleep, it will be woken up at the given deadline.
129 ///
130 /// If the feature `multitask` is not enabled, it uses busy-wait instead
131 pub fn ax_sleep_until(deadline: crate::time::AxTimeValue);
132
133 /// Current task gives up the CPU time voluntarily, and switches to another
134 /// ready task.
135 ///
136 /// If the feature `multitask` is not enabled, it does nothing.
137 pub fn ax_yield_now();
138
139 /// Exits the current task with the given exit code.
140 pub fn ax_exit(exit_code: i32) -> !;
141 }
142
143 define_api! {
144 @cfg "multitask";
145
146 /// Returns the current task's ID.
147 pub fn ax_current_task_id() -> u64;
148 /// Spawns a new task with the given entry point and other arguments.
149 pub fn ax_spawn(
150 f: impl FnOnce() + Send + 'static,
151 name: alloc::string::String,
152 stack_size: usize
153 ) -> AxTaskHandle;
154 /// Waits for the given task to exit, and returns its exit code (the
155 /// argument of [`ax_exit`]).
156 pub fn ax_wait_for_exit(task: AxTaskHandle) -> Option<i32>;
157 /// Sets the priority of the current task.
158 pub fn ax_set_current_priority(prio: isize) -> crate::AxResult;
159 /// Sets the cpu affinity of the current task.
160 pub fn ax_set_current_affinity(cpumask: AxCpuMask) -> crate::AxResult;
161 /// Blocks the current task and put it into the wait queue, until
162 /// other tasks notify the wait queue, or the the given duration has
163 /// elapsed (if specified).
164 pub fn ax_wait_queue_wait(wq: &AxWaitQueueHandle, timeout: Option<core::time::Duration>) -> bool;
165 /// Blocks the current task and put it into the wait queue, until the
166 /// given condition becomes true, or the the given duration has elapsed
167 /// (if specified).
168 pub fn ax_wait_queue_wait_until(
169 wq: &AxWaitQueueHandle,
170 until_condition: impl Fn() -> bool,
171 timeout: Option<core::time::Duration>,
172 ) -> bool;
173 /// Wakes up one or more tasks in the wait queue.
174 ///
175 /// The maximum number of tasks to wake up is specified by `count`. If
176 /// `count` is `u32::MAX`, it will wake up all tasks in the wait queue.
177 pub fn ax_wait_queue_wake(wq: &AxWaitQueueHandle, count: u32);
178 }
179}
180
181/// Filesystem manipulation operations.
182pub mod fs {
183 use crate::AxResult;
184
185 define_api_type! {
186 @cfg "fs";
187 pub type AxFileHandle;
188 pub type AxDirHandle;
189 pub type AxOpenOptions;
190 pub type AxFileAttr;
191 pub type AxFileType;
192 pub type AxFilePerm;
193 pub type AxDirEntry;
194 pub type AxSeekFrom;
195 #[cfg(feature = "myfs")]
196 pub type AxDisk;
197 #[cfg(feature = "myfs")]
198 pub type MyFileSystemIf;
199 }
200
201 define_api! {
202 @cfg "fs";
203
204 /// Opens a file at the path relative to the current directory with the
205 /// options specified by `opts`.
206 pub fn ax_open_file(path: &str, opts: &AxOpenOptions) -> AxResult<AxFileHandle>;
207 /// Opens a directory at the path relative to the current directory with
208 /// the options specified by `opts`.
209 pub fn ax_open_dir(path: &str, opts: &AxOpenOptions) -> AxResult<AxDirHandle>;
210
211 /// Reads the file at the current position, returns the number of bytes read.
212 ///
213 /// After the read, the cursor will be advanced by the number of bytes read.
214 pub fn ax_read_file(file: &mut AxFileHandle, buf: &mut [u8]) -> AxResult<usize>;
215 /// Reads the file at the given position, returns the number of bytes read.
216 ///
217 /// It does not update the file cursor.
218 pub fn ax_read_file_at(file: &AxFileHandle, offset: u64, buf: &mut [u8]) -> AxResult<usize>;
219 /// Writes the file at the current position, returns the number of bytes
220 /// written.
221 ///
222 /// After the write, the cursor will be advanced by the number of bytes
223 /// written.
224 pub fn ax_write_file(file: &mut AxFileHandle, buf: &[u8]) -> AxResult<usize>;
225 /// Writes the file at the given position, returns the number of bytes
226 /// written.
227 ///
228 /// It does not update the file cursor.
229 pub fn ax_write_file_at(file: &AxFileHandle, offset: u64, buf: &[u8]) -> AxResult<usize>;
230 /// Truncates the file to the specified size.
231 pub fn ax_truncate_file(file: &AxFileHandle, size: u64) -> AxResult;
232 /// Flushes the file, writes all buffered data to the underlying device.
233 pub fn ax_flush_file(file: &AxFileHandle) -> AxResult;
234 /// Sets the cursor of the file to the specified offset. Returns the new
235 /// position after the seek.
236 pub fn ax_seek_file(file: &mut AxFileHandle, pos: AxSeekFrom) -> AxResult<u64>;
237 /// Returns attributes of the file.
238 pub fn ax_file_attr(file: &AxFileHandle) -> AxResult<AxFileAttr>;
239
240 /// Reads directory entries starts from the current position into the
241 /// given buffer, returns the number of entries read.
242 ///
243 /// After the read, the cursor of the directory will be advanced by the
244 /// number of entries read.
245 pub fn ax_read_dir(dir: &mut AxDirHandle, dirents: &mut [AxDirEntry]) -> AxResult<usize>;
246 /// Creates a new, empty directory at the provided path.
247 pub fn ax_create_dir(path: &str) -> AxResult;
248 /// Removes an empty directory.
249 ///
250 /// If the directory is not empty, it will return an error.
251 pub fn ax_remove_dir(path: &str) -> AxResult;
252 /// Removes a file from the filesystem.
253 pub fn ax_remove_file(path: &str) -> AxResult;
254 /// Rename a file or directory to a new name.
255 ///
256 /// It will delete the original file if `old` already exists.
257 pub fn ax_rename(old: &str, new: &str) -> AxResult;
258
259 /// Returns the current working directory.
260 pub fn ax_current_dir() -> AxResult<alloc::string::String>;
261 /// Changes the current working directory to the specified path.
262 pub fn ax_set_current_dir(path: &str) -> AxResult;
263 }
264}
265
266/// Networking primitives for TCP/UDP communication.
267pub mod net {
268 use crate::{AxResult, io::AxPollState};
269 use core::net::{IpAddr, SocketAddr};
270
271 define_api_type! {
272 @cfg "net";
273 pub type AxTcpSocketHandle;
274 pub type AxUdpSocketHandle;
275 }
276
277 define_api! {
278 @cfg "net";
279
280 // TCP socket
281
282 /// Creates a new TCP socket.
283 pub fn ax_tcp_socket() -> AxTcpSocketHandle;
284 /// Returns the local address and port of the TCP socket.
285 pub fn ax_tcp_socket_addr(socket: &AxTcpSocketHandle) -> AxResult<SocketAddr>;
286 /// Returns the remote address and port of the TCP socket.
287 pub fn ax_tcp_peer_addr(socket: &AxTcpSocketHandle) -> AxResult<SocketAddr>;
288 /// Moves this TCP socket into or out of nonblocking mode.
289 pub fn ax_tcp_set_nonblocking(socket: &AxTcpSocketHandle, nonblocking: bool) -> AxResult;
290
291 /// Connects the TCP socket to the given address and port.
292 pub fn ax_tcp_connect(handle: &AxTcpSocketHandle, addr: SocketAddr) -> AxResult;
293 /// Binds the TCP socket to the given address and port.
294 pub fn ax_tcp_bind(socket: &AxTcpSocketHandle, addr: SocketAddr) -> AxResult;
295 /// Starts listening on the bound address and port.
296 pub fn ax_tcp_listen(socket: &AxTcpSocketHandle, _backlog: usize) -> AxResult;
297 /// Accepts a new connection on the TCP socket.
298 ///
299 /// This function will block the calling thread until a new TCP connection
300 /// is established. When established, a new TCP socket is returned.
301 pub fn ax_tcp_accept(socket: &AxTcpSocketHandle) -> AxResult<(AxTcpSocketHandle, SocketAddr)>;
302
303 /// Transmits data in the given buffer on the TCP socket.
304 pub fn ax_tcp_send(socket: &AxTcpSocketHandle, buf: &[u8]) -> AxResult<usize>;
305 /// Receives data on the TCP socket, and stores it in the given buffer.
306 /// On success, returns the number of bytes read.
307 pub fn ax_tcp_recv(socket: &AxTcpSocketHandle, buf: &mut [u8]) -> AxResult<usize>;
308 /// Returns whether the TCP socket is readable or writable.
309 pub fn ax_tcp_poll(socket: &AxTcpSocketHandle) -> AxResult<AxPollState>;
310 /// Closes the connection on the TCP socket.
311 pub fn ax_tcp_shutdown(socket: &AxTcpSocketHandle) -> AxResult;
312
313 // UDP socket
314
315 /// Creates a new UDP socket.
316 pub fn ax_udp_socket() -> AxUdpSocketHandle;
317 /// Returns the local address and port of the UDP socket.
318 pub fn ax_udp_socket_addr(socket: &AxUdpSocketHandle) -> AxResult<SocketAddr>;
319 /// Returns the remote address and port of the UDP socket.
320 pub fn ax_udp_peer_addr(socket: &AxUdpSocketHandle) -> AxResult<SocketAddr>;
321 /// Moves this UDP socket into or out of nonblocking mode.
322 pub fn ax_udp_set_nonblocking(socket: &AxUdpSocketHandle, nonblocking: bool) -> AxResult;
323
324 /// Binds the UDP socket to the given address and port.
325 pub fn ax_udp_bind(socket: &AxUdpSocketHandle, addr: SocketAddr) -> AxResult;
326 /// Receives a single datagram message on the UDP socket.
327 pub fn ax_udp_recv_from(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)>;
328 /// Receives a single datagram message on the UDP socket, without
329 /// removing it from the queue.
330 pub fn ax_udp_peek_from(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)>;
331 /// Sends data on the UDP socket to the given address. On success,
332 /// returns the number of bytes written.
333 pub fn ax_udp_send_to(socket: &AxUdpSocketHandle, buf: &[u8], addr: SocketAddr) -> AxResult<usize>;
334
335 /// Connects this UDP socket to a remote address, allowing the `send` and
336 /// `recv` to be used to send data and also applies filters to only receive
337 /// data from the specified address.
338 pub fn ax_udp_connect(socket: &AxUdpSocketHandle, addr: SocketAddr) -> AxResult;
339 /// Sends data on the UDP socket to the remote address to which it is
340 /// connected.
341 pub fn ax_udp_send(socket: &AxUdpSocketHandle, buf: &[u8]) -> AxResult<usize>;
342 /// Receives a single datagram message on the UDP socket from the remote
343 /// address to which it is connected. On success, returns the number of
344 /// bytes read.
345 pub fn ax_udp_recv(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult<usize>;
346 /// Returns whether the UDP socket is readable or writable.
347 pub fn ax_udp_poll(socket: &AxUdpSocketHandle) -> AxResult<AxPollState>;
348
349 // Miscellaneous
350
351 /// Resolves the host name to a list of IP addresses.
352 pub fn ax_dns_query(domain_name: &str) -> AxResult<alloc::vec::Vec<IpAddr>>;
353 /// Poll the network stack.
354 ///
355 /// It may receive packets from the NIC and process them, and transmit queued
356 /// packets to the NIC.
357 pub fn ax_poll_interfaces() -> AxResult;
358 }
359}
360
361/// Graphics manipulation operations.
362pub mod display {
363 define_api_type! {
364 @cfg "display";
365 pub type AxDisplayInfo;
366 }
367
368 define_api! {
369 @cfg "display";
370 /// Gets the framebuffer information.
371 pub fn ax_framebuffer_info() -> AxDisplayInfo;
372 /// Flushes the framebuffer, i.e. show on the screen.
373 pub fn ax_framebuffer_flush();
374 }
375}
376
377/// Input/output operations.
378pub mod io {
379 define_api_type! {
380 pub type AxPollState;
381 }
382}
383
384/// Re-exports of ArceOS modules.
385///
386/// You should prefer to use other APIs rather than these modules. The modules
387/// here should only be used if other APIs do not meet your requirements.
388pub mod modules {
389 pub use axconfig;
390 pub use axhal;
391 pub use axlog;
392 pub use axruntime;
393 pub use axsync;
394
395 #[cfg(feature = "alloc")]
396 pub use axalloc;
397 #[cfg(feature = "display")]
398 pub use axdisplay;
399 #[cfg(feature = "dma")]
400 pub use axdma;
401 #[cfg(any(feature = "fs", feature = "net", feature = "display"))]
402 pub use axdriver;
403 #[cfg(feature = "fs")]
404 pub use axfs;
405 #[cfg(feature = "paging")]
406 pub use axmm;
407 #[cfg(feature = "net")]
408 pub use axnet;
409 #[cfg(feature = "multitask")]
410 pub use axtask;
411}