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