Some classes and macros to enable quick single line trace and watch facilities. Three macros DBUG_INIT, TRACE & WATCH are used to implement all functions. DBUG_INIT is used to allocate the maximum number of watch items that are to be displayed at any time. The remainder of the VT100 emulation screen will be dedicated to the scrolling trace function. The use of macros means that they will be ignored by the compiler when the debug declaration is removed. To assist in formatting the string output I have implemented a caret field that is interpreted as a screen attribute eg ^R reverse video on ^r reverse video off. Look at the VT100 class for further details. This was completed for a rush project about 10 minutes ago so expect a few issues to become apparent.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
ChrisHatfield
Date:
Mon Jan 04 23:25:20 2010 +0000
Commit message:

Changed in this revision

Config.h Show annotated file Show diff for this revision Revisions of this file
DBug.cpp Show annotated file Show diff for this revision Revisions of this file
DBug.h Show annotated file Show diff for this revision Revisions of this file
RemoteFunc.cpp Show annotated file Show diff for this revision Revisions of this file
RemoteFunc.h Show annotated file Show diff for this revision Revisions of this file
VT100.cpp Show annotated file Show diff for this revision Revisions of this file
VT100.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 0c4137d26c2e Config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Config.h	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,6 @@
+/**********************************************************
+* Comment Out The Line Below For Release Compiler Version *
+**********************************************************/
+#define DECLARE_DEBUG
+
+#include "DBug.h"
diff -r 000000000000 -r 0c4137d26c2e DBug.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DBug.cpp	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,48 @@
+#include "VT100.h"
+#include "DBug.h"
+
+CDBug::CDBug()
+	: m_nWatches(0)
+	, m_nScrollLimit(CVT100::Rows)
+	, m_nNextWatch(0)
+{
+}
+
+CDBug::~CDBug(void)
+{
+}
+
+void CDBug::Init(unsigned char nWatches)
+{
+  m_nWatches = nWatches > CVT100::Rows * 2 ? CVT100::Rows * 2 : nWatches;
+  m_nScrollLimit = CVT100::Rows - ((m_nWatches + 1) / 2) - 1;
+  m_VT100.ClearScreen();
+  m_VT100.CursorOff();
+  m_VT100.printf(0, 0, "^_^RTRACE OUTPUT...^r");
+  m_VT100.printf(0, m_nScrollLimit + 1, "^RWATCHES...^r");
+  m_VT100.SetScroll(2, m_nScrollLimit);
+  m_VT100.MoveXY(0, 2);
+}
+																																																															 //
+void CDBug::Trace(char *lpszFormat, ...)
+{
+	va_list	args;
+	va_start(args, lpszFormat);
+	m_VT100.vprintf(lpszFormat, args);
+	va_end(args);
+}
+
+void CDBug::Watch(unsigned char &hHandle, const char *lpszFormat, ...)
+{
+  if (!hHandle && (m_nNextWatch <= m_nWatches))
+  {
+	hHandle = ++m_nNextWatch;
+  }
+  if (hHandle)
+  {
+	va_list	args;
+	va_start(args, lpszFormat);
+	m_VT100.vprintf(hHandle & 1 ?  0 : CVT100::Columns / 2, m_nScrollLimit + 2 + ((hHandle - 1) / 2), lpszFormat, args);
+	va_end(args);
+  }
+}
diff -r 000000000000 -r 0c4137d26c2e DBug.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DBug.h	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,45 @@
+#include "VT100.h"
+class CDBug
+{
+public:
+	CDBug(void);
+	~CDBug(void);
+
+//Attributes
+protected:
+	CVT100 m_VT100;
+	unsigned char m_nWatches;
+	unsigned char m_nScrollLimit;
+	unsigned char m_nNextWatch;
+// Interface
+public:
+	void Init(unsigned char nWatches);
+	void Trace(char *lpszFormat, ...);
+	void Watch(unsigned char &hHandle, const char *lpszFormat, ...);
+
+};
+
+#ifdef DECLARE_DEBUG
+extern CDBug DBug;
+#endif // DECLARE_DEBUG
+
+/**********************************************************
+* Comment Out The Line Below For Release Compiler Version *
+**********************************************************/
+#define DECLARE_DEBUG
+
+#ifdef DECLARE_DEBUG
+#define IMPLEMENT_DBUG CDBug DBug;
+#define DBUG_INIT(a) DBug.Init(a)
+#define TRACE(...) DBug.Trace(__VA_ARGS__)
+#define WATCH(...)\
+{\
+	static unsigned char hHandle(0);\
+	DBug.Watch(hHandle, __VA_ARGS__);\
+}
+#else
+#define IMPLEMENT_DBUG
+#define DBUG_INIT(a)
+#define TRACE(...)
+#define WATCH(...)
+#endif //DECLARE_DEBUG
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e RemoteFunc.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteFunc.cpp	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,9 @@
+#include "Config.h"
+
+long RemoteFunction(const long Arg)
+{
+  TRACE("Remote Function Arg %6ld\n\r", Arg);
+  long lReturn(Arg ^ 0x55AAAA & 0xFFFFFF);
+  WATCH("Remote Funtion Return   %8ld", lReturn);
+  return lReturn;
+}
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e RemoteFunc.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteFunc.h	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,2 @@
+#pragma once
+long RemoteFunction(const long Arg);
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e VT100.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VT100.cpp	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,155 @@
+#include <stdio.h>
+#include "mbed.h"
+#include "VT100.h"
+
+CVT100::CVT100(void)
+ : m_pVT100(NULL)
+{
+  m_pVT100 = new Serial(USBTX, USBRX);
+}
+
+CVT100::~CVT100(void)
+{
+  delete m_pVT100;
+}
+
+void CVT100::printf(const char *lpszFormat, ...)
+{
+    char szBuffer[256];
+    va_list args;
+    va_start(args, lpszFormat);
+    vsprintf(szBuffer, lpszFormat, args);
+    va_end(args);
+    PutString(FormatString(szBuffer));
+}
+
+void CVT100::vprintf(const char *lpszFormat, va_list args)
+{
+    char szBuffer[256];
+    vsprintf(szBuffer, lpszFormat, args);
+    printf(szBuffer);
+}
+
+void CVT100::printf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, ...)
+{
+    char szBuffer[256];
+    SaveCursor();
+    MoveXY(nCol, nRow);
+    va_list    args;
+    va_start(args, lpszFormat);
+    vsprintf(szBuffer, lpszFormat, args);
+    va_end(args);
+    printf(szBuffer);
+    RestoreCursor();
+}
+
+void CVT100::vprintf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, va_list args)
+{
+    char szBuffer[256];
+    vsprintf(szBuffer, lpszFormat, args);
+    printf(nCol, nRow, szBuffer);
+}
+
+void CVT100::ClearScreen(void)
+{
+    PutString("\x1b[2J\x1b[0m");
+}
+
+void CVT100::MoveXY(unsigned char nCol, unsigned char nRow)
+{
+    char szBuffer[32];
+    sprintf(szBuffer, "\x1b[%d;%dH", nRow, nCol);
+    PutString(szBuffer);
+}
+
+void CVT100::SetScroll(unsigned char nStart, unsigned char nEnd)
+{
+    char szBuffer[32];
+    sprintf(szBuffer, "\x1b[%d;%dr", nStart, nEnd);
+    PutString(szBuffer);
+}
+
+void CVT100::SaveCursor(void)
+{
+    PutString("\x1b""7");
+}
+
+void CVT100::RestoreCursor(void)
+{
+  PutString("\x1b""8");
+}
+
+char* CVT100::FormatString(const char *lpszFormat)
+{
+  static char buffer[4096];
+  static char copy[4096];
+
+  strcpy(copy, lpszFormat);  // Store Copies
+  strcpy(buffer, lpszFormat);
+
+  char *p = strstr(copy, "^");
+  while(p)  // Is substr in str?
+    {
+      strncpy(buffer, copy, p - copy); // Copy characters
+      switch (p[1])
+      {
+        case 'B': // Bold On
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[1m", p + 2);
+          break;
+        case 'b': // Bold off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[21m", p + 2);
+          break;
+        case 'F': // Blink On
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[5m", p + 2);
+          break;
+        case 'f': // Blink off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[25m", p + 2);
+          break;
+        case 'L': // Low Intensity On
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[2m", p + 2);
+          break;
+        case 'l': // Low Intensity off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[22m", p + 2);
+          break;
+        case 'R': // Reverse Video On
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[7m", p + 2);
+          break;
+        case 'r': //  Reverse Video off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[27m", p + 2);
+          break;
+        case 'U': // Underline On
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[4m", p + 2);
+          break;
+        case 'u': // Underline off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[24m", p + 2);
+          break;
+        case '_': // All Attributes off
+          sprintf(buffer + (p - copy), "%s%s", "\x1b[0m", p + 2);
+          break;
+        case '^': // Caret Character
+          sprintf(buffer + (p - copy), "%s%s", "^", p + 2);
+          break;
+        default: // Delete the Caret (or Infinite Loop)
+          sprintf(buffer + (p - copy), "%s", p + 2);
+          break;    
+      }
+      strcpy(copy, buffer);
+      p = strstr(copy, "^");
+  }
+  return buffer;
+}
+
+void CVT100::PutString(const char *lpszOutput)
+{
+  int i(0);
+  while(lpszOutput[i])
+    m_pVT100->putc(lpszOutput[i++]);
+}
+
+void CVT100::CursorOff(bool bOff /*= true*/)
+{
+  if (bOff)
+    PutString("\x1b[?25l");
+  else
+    PutString("\x1b[?25h");
+}
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e VT100.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VT100.h	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,27 @@
+#pragma once
+#include <stdarg.h>
+#include "mbed.h"
+
+class CVT100
+{
+public:
+    CVT100(void);
+    ~CVT100(void);
+    enum {Rows = 24, Columns = 80};
+//Attributes
+Serial* m_pVT100;
+
+//Interface
+void printf(const char *lpszFormat, ...);
+void printf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, ...);
+void vprintf(const char *lpszFormat, va_list);
+void vprintf(unsigned char nCol, unsigned char nRow, const char *lpszFormat, va_list);
+void ClearScreen(void);
+void SaveCursor(void);
+void CursorOff(bool bOff = true);
+void RestoreCursor(void);
+void MoveXY(unsigned char nCol, unsigned char nRow);
+void SetScroll(unsigned char nStart, unsigned char nEnd);
+void PutString(const char *lpszOutput);
+char* FormatString(const char *lpszFormat);
+};
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,45 @@
+
+#include "Config.h"
+#include "mbed.h"
+#include "RemoteFunc.h"
+
+//Set Up Debug Environment
+IMPLEMENT_DBUG;
+
+Ticker tkInterrupt;
+
+DigitalOut Led1(LED1);
+DigitalOut Led2(LED2);
+DigitalOut Led3(LED3);
+DigitalOut Led4(LED4);
+
+const float fWait(1.0);
+
+long nIntegrand(0);
+
+int main()
+{
+  DBUG_INIT(8);
+
+  while(true)
+  {
+    TRACE("Beginning of Loop\n\r");
+    WATCH("Integrand     %6ld", nIntegrand++);
+
+    if (nIntegrand % 3)
+      RemoteFunction(nIntegrand);
+      
+    // Display Diagnostics LEDs
+    Led1 = (nIntegrand % 2 == 0);
+    Led2 = (nIntegrand % 3 == 0);
+    Led3 = (nIntegrand % 4 == 0);
+    Led4 = (nIntegrand % 5 == 0);
+    WATCH("%s", Led1 ? "^RLED 1^r" : "LED 1");
+    WATCH("%s", Led2 ? "^RLED 2^r" : "LED 2");
+    WATCH("%s", Led3 ? "^RLED 3^r" : "LED 3");
+    WATCH("%s", Led4 ? "^RLED 4^r" : "LED 4");
+    TRACE("Waiting for %2.1f Seconds\n\r", fWait);
+    wait(fWait);
+    TRACE("End Of Loop\n\r");
+  }
+}
\ No newline at end of file
diff -r 000000000000 -r 0c4137d26c2e mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Jan 04 23:25:20 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0