Here's a little module I cooked up so that I could use
something like printk() inside RTLinux, and have the message
appear in log files, i.e., dmesg and /var/log/messages.
rtl_printf() in the new betas only prints things to the
console, although it does it in real-time. This is great
for debugging, but not so great if you aren't at the
console.
How it works:
When you call rt_printk(), the output is buffered in a ring
buffer. The ring buffer is then printk()'ed in a soft interrupt.
Thus, the output is not written to the console in real-time,
so there is the possibility that the order of printk() and
rt_printk() messages getting scrambled. The function has the
same prototype as the normal printk()/printf(), which you need
to add to your source file, as there is no rt_printk.h.
This only works with RTLinux 2.2. If you backport it, send
me the changes.
dave...
(To unpack, run 'patch <this_mail_message' in an empty directoy.)
diff -urN mt/Makefile rt_printk/Makefile
--- mt/Makefile Wed Dec 31 16:00:00 1969
+++ rt_printk/Makefile Sat Jun 19 13:21:40 1999
@@ -0,0 +1,12 @@
+
+
+CFLAGS=-D__KERNEL__ -D__RTL__ -DMODULE -Wall -O2
+
+all: rt_printk.o
+
+rt_printk.o: rt_printk.c
+ cc -c rt_printk.c ${CFLAGS}
+
+clean:
+ rm -f rt_printk.o
+
diff -urN mt/rt_printk.c rt_printk/rt_printk.c
--- mt/rt_printk.c Wed Dec 31 16:00:00 1969
+++ rt_printk/rt_printk.c Sat Jun 19 13:26:34 1999
@@ -0,0 +1,118 @@
+/*
+ * rt_printk.c, hacked from linux/kernel/printk.c
+ *
+ * Modified for RT support, David Schleef
+ */
+
+#ifdef MODULE
+#define EXPORT_SYMTAB
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <linux/rtl.h>
+#include <string.h>
+
+
+#define BUF_LEN (16384)
+
+static char rt_printk_buf[BUF_LEN];
+static char buf[1024];
+
+static int buf_front,buf_back;
+
+static int rt_printk_irq;
+
+/* this is rather bogus, but it will catch most errors */
+static volatile int rt_printk_lock;
+
+static void rt_printk_interrupt(int irq,void *junk,struct pt_regs *regs);
+
+int rt_printk(const char *fmt, ...)
+{
+ va_list args;
+ int len,i;
+
+ if(rtl_rt_system_is_idle()){
+ va_start(args, fmt);
+ len=printk(fmt,args);
+ va_end(args);
+ return len;
+ }
+
+ if(rt_printk_lock){
+ /* force a panic */
+ *(int *)0=0;
+ }
+ rt_printk_lock=1;
+
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf)-1 */
+ va_end(args);
+
+ if(buf_front+len>=BUF_LEN){
+ i=BUF_LEN-buf_front;
+ memcpy(rt_printk_buf+buf_front,buf,i);
+ memcpy(rt_printk_buf,buf+i,len-i);
+ buf_front=len-i;
+ }else{
+ memcpy(rt_printk_buf+buf_front,buf,len);
+ buf_front+=len;
+ }
+
+ rt_printk_lock=0;
+
+ rtl_global_pend_irq(rt_printk_irq);
+
+ return len;
+}
+
+
+void rt_printk_interrupt(int irq,void *junk,struct pt_regs *regs)
+{
+ int tmp;
+
+ for(;;){
+ tmp=buf_front;
+ if(buf_back>tmp){
+ printk("%.*s",BUF_LEN-buf_back,rt_printk_buf+buf_back);
+ buf_back=0;
+ }
+ if(buf_back==tmp)break;
+ printk("%.*s",tmp-buf_back,rt_printk_buf+buf_back);
+ buf_back=tmp;
+ }
+}
+
+#ifdef MODULE
+#define INIT_MODULE init_module
+
+void cleanup_module(void)
+{
+ free_irq(rt_printk_irq,NULL);
+ rt_printk_irq=0;
+}
+
+#else
+#define INIT_MODULE init_rt_printk
+#endif
+
+int INIT_MODULE(void)
+{
+ rt_printk_irq=rtl_get_soft_irq(rt_printk_interrupt,"rt_printk");
+ if(rt_printk_irq<0){
+ printk("rt_printk: can't allocate soft irq\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* exported functions */
+
+EXPORT_SYMBOL(rt_printk);
+
--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/