Module: xenomai-forge Branch: master Commit: b29d078a6f47a3bcfd432680e90a055a49ae29c4 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=b29d078a6f47a3bcfd432680e90a055a49ae29c4
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Sep 6 11:59:36 2013 +0200 lib/cobalt, cobalt/shadow: allow user-space to issue serial debug output In desperate cases, it may be convenient to write raw debug output directly to the console UART from the current domain, without any intermediate buffering. This internal debug service is available from the inner Cobalt interface as __cobalt_serial_debug(const char *fmt, ...). The formatted output is directed to __ipipe_serial_debug(). NOTE: for the output to take place, the support for serial console and CONFIG_IPIPE_DEBUG must be enabled in the kernel. --- include/cobalt/uapi/asm-generic/syscall.h | 1 + kernel/cobalt/shadow.c | 22 +++++++++++++++++++++- lib/cobalt/internal.c | 20 ++++++++++++++++++++ lib/cobalt/internal.h | 2 ++ 4 files changed, 44 insertions(+), 1 deletions(-) diff --git a/include/cobalt/uapi/asm-generic/syscall.h b/include/cobalt/uapi/asm-generic/syscall.h index 4eb95d9..056fc6c 100644 --- a/include/cobalt/uapi/asm-generic/syscall.h +++ b/include/cobalt/uapi/asm-generic/syscall.h @@ -34,6 +34,7 @@ #define sc_nucleus_current_info 7 /* r = xnshadow_current_info(&info) */ #define sc_nucleus_mayday 8 /* request mayday fixup */ #define sc_nucleus_backtrace 9 /* collect backtrace (relax tracing) */ +#define sc_nucleus_serialdbg 10 /* output to serial console (__ipipe_serial_debug()) */ struct xnbindreq { int feat_req; /* Features userland requires. */ diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c index ab72f70..2fb0b42 100644 --- a/kernel/cobalt/shadow.c +++ b/kernel/cobalt/shadow.c @@ -1587,13 +1587,32 @@ static int xnshadow_sys_current_info(struct xnthread_info __user *u_info) return __xn_safe_copy_to_user(u_info, &info, sizeof(*u_info)); } -static int xnshadow_sys_backtrace(int nr, unsigned long *u_backtrace, +static int xnshadow_sys_backtrace(int nr, unsigned long __user *u_backtrace, int reason) { xndebug_trace_relax(nr, u_backtrace, reason); return 0; } +static int xnshadow_sys_serialdbg(const char __user *u_msg, int len) +{ + char buf[128]; + int n; + + while (len > 0) { + n = len; + if (n > sizeof(buf)) + n = sizeof(buf); + if (__xn_safe_copy_from_user(buf, u_msg, n)) + return -EFAULT; + __ipipe_serial_debug("%.*s", n, buf); + u_msg += n; + len -= n; + } + + return 0; +} + static void post_ppd_release(struct xnheap *h) { struct xnsys_ppd *p = container_of(h, struct xnsys_ppd, sem_heap); @@ -1712,6 +1731,7 @@ static struct xnsyscall user_syscalls[] = { SKINCALL_DEF(sc_nucleus_current_info, xnshadow_sys_current_info, shadow), SKINCALL_DEF(sc_nucleus_mayday, xnshadow_sys_mayday, oneway), SKINCALL_DEF(sc_nucleus_backtrace, xnshadow_sys_backtrace, current), + SKINCALL_DEF(sc_nucleus_serialdbg, xnshadow_sys_serialdbg, any), }; static struct xnpersonality user_personality = { diff --git a/lib/cobalt/internal.c b/lib/cobalt/internal.c index 10b2ce1..603791b 100644 --- a/lib/cobalt/internal.c +++ b/lib/cobalt/internal.c @@ -28,6 +28,7 @@ #include <unistd.h> #include <signal.h> #include <errno.h> +#include <stdarg.h> #include <pthread.h> #include <asm/xenomai/syscall.h> #include "current.h" @@ -60,6 +61,25 @@ void ___cobalt_prefault(void *p, size_t len) } while (_p < end); } +int __cobalt_serial_debug(const char *fmt, ...) +{ + char msg[128]; + va_list ap; + int n, ret; + + /* + * The serial debug output handler disables hw IRQs while + * writing to the UART console port, so the message ought to + * be reasonably short. + */ + va_start(ap, fmt); + n = vsnprintf(msg, sizeof(msg), fmt, ap); + ret = XENOMAI_SYSCALL2(sc_nucleus_serialdbg, msg, n); + va_end(ap); + + return ret; +} + size_t cobalt_get_stacksize(size_t size) { static const size_t default_size = PTHREAD_STACK_MIN * 4; diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 75ce011..6a32f3f 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -65,6 +65,8 @@ void __cobalt_thread_harden(void); int __cobalt_thread_stat(pid_t pid, struct cobalt_threadstat *stat); +int __cobalt_serial_debug(const char *fmt, ...); + int cobalt_monitor_init(cobalt_monitor_t *mon, int flags); int cobalt_monitor_destroy(cobalt_monitor_t *mon); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git