Commits

Anonymous committed a0c6fed

added log.h

Comments (0)

Files changed (3)

 	"Tiny virtual machine for Forth language" \
 	"virtual machine, vm, forth, interpreter, compiler, assembler, stack, embedded, small, retro"> ivm.html
 
+./gendoc.sh "nikl" pages/log.mkd\
+	"Ultra-leightweight logging for embedded system" \
+	"log, embedded, variable-length, printf, format" \
+	> log.html
+
+<!DOCTYPE HTML> 
+<html lang=en>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+	<title>nikl</title>
+	<meta name="description" content="Ultra-leightweight logging for embedded system" />
+	<meta name="keywords" content="log, embedded, variable-length, printf, format" />
+
+	<link rel="stylesheet" href="style.css" type="text/css"/>
+	<script type="text/javascript">
+
+	var _gaq = _gaq || [];
+	_gaq.push(['_setAccount', 'UA-16690724-5']);
+	_gaq.push(['_trackPageview']);
+
+	(function() {
+	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+	var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+</head>
+<body>
+<div id="container">
+	<div id="content">
+<h1>log.h</h1>
+
+<p>log.h is a ultra-leight logging library for <a href="nikl.html">nikl</a> framework.
+You can use it to profile your code or debug time-critical parts.</p>
+
+<h2>idea</h2>
+
+<p>Real hackers don't use debuggers, they use <code>printf</code> instead, right?
+But <code>printf</code> is often too heavy for your tiny 8-bit MCU.</p>
+
+<p>Nikl's logger sends only printf payload (e.g. arguments, without even format 
+string) and some information to find the line in the source file and 
+get format string from there. </p>
+
+<p>It allows you to send (let's assume that sending 1 byte takes 1 instruction):</p>
+
+<ul>
+<li><code>TRACE()</code> message: 5 bytes, 10 instructions.</li>
+<li><code>LOG("status =  %d", s);</code> where <code>s=2</code>, s is a 32-bit number: 6 bytes, 20
+instructions.</li>
+</ul>
+
+<h2>protocol</h2>
+
+<p>Data is sent using very simple datagram protocol. Each datagram has the format:</p>
+
+<pre><code>+-----+----------+---------+---------+-----+-----+
+| STX | FILE_TAG | LINE_HI | LINE_LO | ... | ETX |
++-----+----------+---------+---------+-----+-----+
+</code></pre>
+
+<ul>
+<li><code>STX</code> - start of the datagram. <code>STX = 0xFC</code></li>
+<li><code>ETX</code> - end of the datagram. <code>ETX = 0xFD</code></li>
+<li><code>FILE_TAG</code> - label of the source file (1 byte)</li>
+<li><code>LINE_HI</code> and <code>LINE_LO</code> - high and low byte of <code>__LINE__</code> value (2 bytes in total).</li>
+</ul>
+
+<p>After <code>LINE_LO</code> but before <code>ETX</code> byte there is datagram body. Datagram body can
+contain 3 data types:</p>
+
+<ul>
+<li>Integer numbers</li>
+<li>NULL-terminated strings</li>
+<li>Binary data of known length</li>
+</ul>
+
+<p>Let's see how these type are encoded.</p>
+
+<h2>data types</h2>
+
+<p>Integers are passed using variable-length format.
+Everything depends on the 1st byte:</p>
+
+<ul>
+<li><code>0nnnnnnn</code>:  7-bit number</li>
+<li><code>10nnnnnn nnnnnnnn</code>: 14-bit number</li>
+<li><code>110nnnnn nnnnnnnn nnnnnnnn</code>: 21-bit number</li>
+<li><code>11100nnn nnnnnnnn nnnnnnnn nnnnnnnn</code>: 27-bit number</li>
+<li><code>11101nnn nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn</code>: 35-bit number</li>
+<li><code>11111100</code> - STX</li>
+<li><code>11111101</code> - ETX</li>
+<li><code>11111011</code> - Zero-terminated string</li>
+<li><code>11111111 ....</code> - variable-length data. Length is a variable-length number. 
+Data comes after length.</li>
+</ul>
+
+<p>Easy, right?</p>
+
+<h2>internals</h2>
+
+<p>Well, sending TRACE() is simple - it's just a function that sends 5 bytes.</p>
+
+<p>LOG() is somewhat more complicated. Normally, LOG() arguments are passed
+comma-separated. As you know, statements in C can be also written separated
+with commas. All we need to do is to wrap each parameter with a function,
+depending on its type. Unfortunatelly, there seems to be no way to do this 
+automatically, so the programmer must to it manually:</p>
+
+<pre><code>LOG("status = %d", _I(status)); /* _I() - for numbers */
+LOG("request = %s", _S(req));   /* _S() - for strings */
+LOG("payload = %v", _D(buf, 512)); /* _D() for binary data */
+</code></pre>
+	</div>
+</div>
+</body>
+</html>
+log.h
+=====
+
+log.h is a ultra-leight logging library for [nikl](nikl.html) framework.
+You can use it to profile your code or debug time-critical parts.
+
+idea
+----
+
+Real hackers don't use debuggers, they use `printf` instead, right?
+But `printf` is often too heavy for your tiny 8-bit MCU.
+
+Nikl's logger sends only printf payload (e.g. arguments, without even format 
+string) and some information to find the line in the source file and 
+get format string from there. 
+
+It allows you to send (let's assume that sending 1 byte takes 1 instruction):
+
+* `TRACE()` message: 5 bytes, 10 instructions.
+* `LOG("status =  %d", s);` where `s=2`, s is a 32-bit number: 6 bytes, 20
+	instructions.
+
+protocol
+--------
+
+Data is sent using very simple datagram protocol. Each datagram has the format:
+
+	+-----+----------+---------+---------+-----+-----+
+	| STX | FILE_TAG | LINE_HI | LINE_LO | ... | ETX |
+	+-----+----------+---------+---------+-----+-----+
+
+* `STX` - start of the datagram. `STX = 0xFC`
+* `ETX` - end of the datagram. `ETX = 0xFD`
+* `FILE_TAG` - label of the source file (1 byte)
+* `LINE_HI` and `LINE_LO` - high and low byte of `__LINE__` value (2 bytes in total).
+
+After `LINE_LO` but before `ETX` byte there is datagram body. Datagram body can
+contain 3 data types:
+
+* Integer numbers
+* NULL-terminated strings
+* Binary data of known length
+
+Let's see how these type are encoded.
+
+data types
+----------
+
+Integers are passed using variable-length format.
+Everything depends on the 1st byte:
+
+* `0nnnnnnn`:  7-bit number
+* `10nnnnnn nnnnnnnn`: 14-bit number
+* `110nnnnn nnnnnnnn nnnnnnnn`: 21-bit number
+* `11100nnn nnnnnnnn nnnnnnnn nnnnnnnn`: 27-bit number
+* `11101nnn nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn`: 35-bit number
+* `11111100` - STX
+* `11111101` - ETX
+* `11111011` - Zero-terminated string
+* `11111111 ....` - variable-length data. Length is a variable-length number. 
+	Data comes after length.
+
+Easy, right?
+
+internals
+---------
+
+Well, sending TRACE() is simple - it's just a function that sends 5 bytes.
+
+LOG() is somewhat more complicated. Normally, LOG() arguments are passed
+comma-separated. As you know, statements in C can be also written separated
+with commas. All we need to do is to wrap each parameter with a function,
+depending on its type. Unfortunatelly, there seems to be no way to do this 
+automatically, so the programmer must to it manually:
+
+	LOG("status = %d", _I(status)); /* _I() - for numbers */
+	LOG("request = %s", _S(req));   /* _S() - for strings */
+	LOG("payload = %v", _D(buf, 512)); /* _D() for binary data */
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.