Forráskód Böngészése

Fix issues found by code review, add more documentation.

Vadzim Dambrouski 8 éve
szülő
commit
22fb4a780b
3 módosított fájl, 76 hozzáadás és 9 törlés
  1. 40 3
      src/debug.rs
  2. 26 4
      src/lib.rs
  3. 10 2
      src/macros.rs

+ 40 - 3
src/debug.rs

@@ -1,5 +1,31 @@
 //! Interacting with debugging agent
+//!
+//! # Example
+//!
+//! This example will show how to terminate the QEMU session. The program
+//! should be running under QEMU with semihosting enabled
+//! (use `-semihosting` flag).
+//!
+//! Target program:
+//!
+//! ```
+//! #[macro_use]
+//! extern crate cortex_m_semihosting;
+//! use cortex_m_semihosting::debug;
+//!
+//! fn main() {
+//!     if 2 == 2 {
+//!         // report success
+//!         debug::exit(0);
+//!     } else {
+//!         // report failure
+//!         debug::exit(1);
+//!     }
+//! }
+//!
 
+/// This values are taken from section 5.5.2 of
+/// "ADS Debug Target Guide" (DUI0058)
 pub enum Exception {
     // Hardware reason codes
     BranchThroughZero = 0x20000,
@@ -26,7 +52,13 @@ pub enum Exception {
 /// Reports to the debugger that the execution has completed.
 ///
 /// If `status` is not 0 then an error is reported.
-/// This call may not return.
+///
+/// This call can be used to terminate QEMU session, and report back success
+/// or failure.
+///
+/// This call should not return. However, it is possible for the debugger
+/// to request that the application continue. In that case this call
+/// returns normally.
 ///
 pub fn exit(status: i8) {
     if status == 0 {
@@ -38,7 +70,12 @@ pub fn exit(status: i8) {
 
 /// Report an exception to the debugger directly.
 ///
-/// This call may not return.
+/// Exception handlers can use this SWI at the end of handler chains
+/// as the default action, to indicate that the exception has not been handled.
+///
+/// This call should not return. However, it is possible for the debugger
+/// to request that the application continue. In that case this call
+/// returns normally.
 ///
 /// # Arguments
 ///
@@ -47,6 +84,6 @@ pub fn exit(status: i8) {
 pub fn report_exception(reason: Exception) {
     let code = reason as usize;
     unsafe {
-        syscall!(REPORT_EXCEPTION, code);
+        syscall1!(REPORT_EXCEPTION, code);
     }
 }

+ 26 - 4
src/lib.rs

@@ -28,7 +28,10 @@
 //!
 //! Target program:
 //!
-//! ```rust,ignore
+//! ```
+//! #[macro_use]
+//! extern crate cortex_m_semihosting;
+//!
 //! fn main() {
 //!     // File descriptor (on the host)
 //!     const STDOUT: usize = 1;
@@ -112,10 +115,28 @@ pub mod io;
 pub mod nr;
 pub mod debug;
 
-/// Performs a semihosting operation
+/// Performs a semihosting operation, takes a pointer to an argument block
+#[inline(always)]
+#[cfg(target_arch = "arm")]
+pub unsafe fn syscall<T>(mut nr: usize, arg: &T) -> usize {
+    asm!("bkpt 0xAB"
+         : "+{r0}"(nr)
+         : "{r1}"(arg)
+         : "memory"
+         : "volatile");
+    nr
+}
+
+/// Performs a semihosting operation, takes a pointer to an argument block
+#[cfg(not(target_arch = "arm"))]
+pub unsafe fn syscall<T>(_nr: usize, _arg: &T) -> usize {
+    0
+}
+
+/// Performs a semihosting operation, takes one integer as an argument
 #[inline(always)]
 #[cfg(target_arch = "arm")]
-pub unsafe fn syscall<T: Sized>(mut nr: usize, arg: T) -> usize {
+pub unsafe fn syscall1(mut nr: usize, arg: usize) -> usize {
     asm!("bkpt 0xAB"
          : "+{r0}"(nr)
          : "{r1}"(arg)
@@ -124,7 +145,8 @@ pub unsafe fn syscall<T: Sized>(mut nr: usize, arg: T) -> usize {
     nr
 }
 
+/// Performs a semihosting operation, takes one integer as an argument
 #[cfg(not(target_arch = "arm"))]
-pub unsafe fn syscall<T: Sized>(_nr: usize, _arg: T) -> usize {
+pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize {
     0
 }

+ 10 - 2
src/macros.rs

@@ -2,10 +2,10 @@
 #[macro_export]
 macro_rules! syscall {
     ($nr:ident) => {
-        $crate::syscall($crate::nr::$nr, 0usize)
+        $crate::syscall1($crate::nr::$nr, 0)
     };
     ($nr:ident, $a1:expr) => {
-        $crate::syscall($crate::nr::$nr, $a1 as usize)
+        $crate::syscall($crate::nr::$nr, &[$a1 as usize])
     };
     ($nr:ident, $a1:expr, $a2:expr) => {
         $crate::syscall($crate::nr::$nr, &[$a1 as usize, $a2 as usize])
@@ -20,6 +20,14 @@ macro_rules! syscall {
     };
 }
 
+/// Macro version of `syscall1`
+#[macro_export]
+macro_rules! syscall1 {
+    ($nr:ident, $a1:expr) => {
+        $crate::syscall1($crate::nr::$nr, $a1 as usize)
+    };
+}
+
 /// Macro for printing to the **host's** standard stderr
 #[macro_export]
 macro_rules! ehprint {