cortex_m_semihosting/debug.rs
1//! Interacting with debugging agent
2//!
3//! # Example
4//!
5//! This example will show how to terminate the QEMU session. The program
6//! should be running under QEMU with semihosting enabled
7//! (use `-semihosting` flag).
8//!
9//! Target program:
10//!
11//! ```no_run
12//! use cortex_m_semihosting::debug::{self, EXIT_SUCCESS, EXIT_FAILURE};
13//!
14//! fn main() {
15//! if 2 == 2 {
16//! // report success
17//! debug::exit(EXIT_SUCCESS);
18//! } else {
19//! // report failure
20//! debug::exit(EXIT_FAILURE);
21//! }
22//! }
23//!
24
25/// This values are taken from section 5.5.2 of
26/// ADS Debug Target Guide (DUI0058).
27// TODO document
28#[allow(missing_docs)]
29pub enum Exception {
30 // Hardware reason codes
31 BranchThroughZero = 0x20000,
32 UndefinedInstr = 0x20001,
33 SoftwareInterrupt = 0x20002,
34 PrefetchAbort = 0x20003,
35 DataAbort = 0x20004,
36 AddressException = 0x20005,
37 IRQ = 0x20006,
38 FIQ = 0x20007,
39 // Software reason codes
40 BreakPoint = 0x20020,
41 WatchPoint = 0x20021,
42 StepComplete = 0x20022,
43 RunTimeErrorUnknown = 0x20023,
44 InternalError = 0x20024,
45 UserInterruption = 0x20025,
46 ApplicationExit = 0x20026,
47 StackOverflow = 0x20027,
48 DivisionByZero = 0x20028,
49 OSSpecific = 0x20029,
50}
51
52/// Status enum for `exit` syscall.
53pub type ExitStatus = Result<(), ()>;
54
55/// Successful execution of a program.
56pub const EXIT_SUCCESS: ExitStatus = Ok(());
57
58/// Unsuccessful execution of a program.
59pub const EXIT_FAILURE: ExitStatus = Err(());
60
61/// Reports to the debugger that the execution has completed.
62///
63/// This call can be used to terminate QEMU session and report back success
64/// or failure. If you need to pass more than one type of error, consider
65/// using `report_exception` syscall instead.
66///
67/// This call should not return. However, it is possible for the debugger
68/// to request that the application continue. In that case this call
69/// returns normally.
70///
71pub fn exit(status: ExitStatus) {
72 match status {
73 EXIT_SUCCESS => report_exception(Exception::ApplicationExit),
74 EXIT_FAILURE => report_exception(Exception::RunTimeErrorUnknown),
75 }
76}
77
78/// Report an exception to the debugger directly.
79///
80/// Exception handlers can use this SWI at the end of handler chains
81/// as the default action, to indicate that the exception has not been handled.
82///
83/// This call should not return. However, it is possible for the debugger
84/// to request that the application continue. In that case this call
85/// returns normally.
86///
87/// # Arguments
88///
89/// * `reason` - A reason code reported back to the debugger.
90///
91pub fn report_exception(reason: Exception) {
92 let code = reason as usize;
93 unsafe {
94 syscall1!(REPORT_EXCEPTION, code);
95 }
96}