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