|
| 1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| 2 | +<html xmlns="http://www.w3.org/1999/xhtml"> |
| 3 | +<head> |
| 4 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| 5 | + <meta http-equiv="Content-Style-Type" content="text/css" /> |
| 6 | + <meta name="generator" content="pandoc" /> |
| 7 | + <meta name="author" content="Chris Hodapp" /> |
| 8 | + <title>Embedded Haskell, part 1: EDSLs & Metaprogramming</title> |
| 9 | + <style type="text/css">code{white-space: pre;}</style> |
| 10 | + <!-- configuration parameters --> |
| 11 | + <meta name="defaultView" content="slideshow" /> |
| 12 | + <meta name="controlVis" content="hidden" /> |
| 13 | + <!-- style sheet links --> |
| 14 | + <link rel="stylesheet" href="../s5/default/slides.css" type="text/css" media="projection" id="slideProj" /> |
| 15 | + <link rel="stylesheet" href="../s5/default/outline.css" type="text/css" media="screen" id="outlineStyle" /> |
| 16 | + <link rel="stylesheet" href="../s5/default/print.css" type="text/css" media="print" id="slidePrint" /> |
| 17 | + <link rel="stylesheet" href="../s5/default/opera.css" type="text/css" media="projection" id="operaFix" /> |
| 18 | + <!-- S5 JS --> |
| 19 | + <script src="../s5/default/slides.js" type="text/javascript"></script> |
| 20 | +</head> |
| 21 | +<body> |
| 22 | +<div class="layout"> |
| 23 | +<div id="controls"></div> |
| 24 | +<div id="currentSlide"></div> |
| 25 | +<div id="header"></div> |
| 26 | +<div id="footer"> |
| 27 | + <h1>CincyFP, 2015-06-09</h1> |
| 28 | + <h2>Embedded Haskell, part 1: EDSLs & Metaprogramming</h2> |
| 29 | +</div> |
| 30 | +</div> |
| 31 | +<div class="presentation"> |
| 32 | +<div class="titleslide slide"> |
| 33 | + <h1>Embedded Haskell, part 1: EDSLs & Metaprogramming</h1> |
| 34 | + <h2>Chris Hodapp</h2> |
| 35 | + <h3>CincyFP, 2015-06-09</h3> |
| 36 | +</div> |
| 37 | +<div id="why-use-haskell-there-at-all" class="slide section level1"> |
| 38 | +<h1>Why use Haskell there at all?</h1> |
| 39 | +<ol class="incremental" style="list-style-type: decimal"> |
| 40 | +<li>Because you can.</li> |
| 41 | +<li>With apologies to Kernighan & Ritchie: Because C is kind of horrid for this. (And with apologies to no one: Because C++ is also a train-wreck.)</li> |
| 42 | +<li>Because Haskell has a very powerful type system, and this can work wonders when dealing with embedded systems that are notoriously finicky and fragile.</li> |
| 43 | +<li>Because arcane concepts like "functional programming" and "pure functions" and "monads" turn out to be useful for something besides ivory-tower navel-gazing.</li> |
| 44 | +</ol> |
| 45 | +</div> |
| 46 | +<div id="approaches-to-embedded-haskell" class="slide section level1"> |
| 47 | +<h1>Approaches to embedded Haskell</h1> |
| 48 | +<p><em>Disclaimer:</em> I made these categories up, and I'm excluding languages like Cryptol and Idris that only incidentally involve Haskell.</p> |
| 49 | +<ul> |
| 50 | +<li>Full compilation, reduced runtime approach</li> |
| 51 | +<li>Static analysis approach</li> |
| 52 | +<li>Compiled EDSL approach (the focus of this presentation)</li> |
| 53 | +</ul> |
| 54 | +</div> |
| 55 | +<div id="full-compilation-reduced-runtime" class="slide section level1"> |
| 56 | +<h1>Full compilation, reduced runtime</h1> |
| 57 | +<p>This compiles Haskell code to run directly on an embedded target. This requires:</p> |
| 58 | +<ul> |
| 59 | +<li>reducing the fairly heavy Haskell runtime,</li> |
| 60 | +<li>optimizing the garbage collection,</li> |
| 61 | +<li>making the lazy evaluation less of a pain.</li> |
| 62 | +</ul> |
| 63 | +<div class="incremental"> |
| 64 | +<p>Ajhc (<a href="https://github.com/ajhc/ajhc" class="uri">https://github.com/ajhc/ajhc</a>), a JHC-derived compiler from Kiwamu Okabe of METASEPI, is the only example of this I found - it could compile and execute on ARM Cortex-M3/M4. His subsequent switch to the ATS language may be a hint.</p> |
| 65 | +</div> |
| 66 | +</div> |
| 67 | +<div id="static-analysis" class="slide section level1"> |
| 68 | +<h1>Static analysis</h1> |
| 69 | +<p>This uses an existing compiler for certain stages (such as the parsing and type-checking), but a custom back-end to actually produce code. This may adapt or disallow certain constructs.</p> |
| 70 | +<p>GHC readily accomodates this by allowing developers to invoke GHC functionality, from Haskell, as a library. (<em>GHCJS</em>, a Haskell to JavaScript compiler, uses this.)</p> |
| 71 | +</div> |
| 72 | +<div id="static-analysis-examples" class="slide section level1"> |
| 73 | +<h1>Static analysis examples</h1> |
| 74 | +<p><em>CλaSH</em> (<a href="http://www.clash-lang.org/" class="uri">http://www.clash-lang.org/</a>) from Christiaan Baaij uses this to compile a subset of Haskell to VHDL and SystemVerilog. CλaSH disallows certain things: recursive functions, recursive types, side effects, floating-point...</p> |
| 75 | +<div class="incremental"> |
| 76 | +<p><em>Reduceron</em> (<a href="https://github.com/tommythorn/Reduceron" class="uri">https://github.com/tommythorn/Reduceron</a>) is an "FPGA Haskell machine" relying on massively-parallel graph reduction, complete with GC and lazy evaluation.</p> |
| 77 | +</div> |
| 78 | +<div class="incremental"> |
| 79 | +<p>Conal Elliott worked with a Silicon Valley startup, <em>Tabula</em>, on massively-parallel execution of Haskell code on a new architecture (<em>Spacetime</em>), using an approach based on Cartesian Closed Categories (<a href="http://conal.net/blog/posts/haskell-to-hardware-via-cccs" class="uri">http://conal.net/blog/posts/haskell-to-hardware-via-cccs</a> & <a href="https://github.com/conal/lambda-ccc/" class="uri">https://github.com/conal/lambda-ccc/</a>).</p> |
| 80 | +</div> |
| 81 | +</div> |
| 82 | +<div id="compiled-edsl" class="slide section level1"> |
| 83 | +<h1>Compiled EDSL</h1> |
| 84 | +<p>This uses an EDSL (embedded domain-specific language) inside of Haskell to direct the process of code generation to a lower-level representation. (Otherwise called: <em>compiling</em>.)</p> |
| 85 | +<p>Note that in this case, Haskell code never actually <em>runs</em> on the embedded target. Rather, it uses specifications in the EDSL to build a representation of what <em>will</em> run there - in other words, a sort of metaprogramming.</p> |
| 86 | +<p>The code that runs on the target is entirely decoupled from the Haskell runtime.</p> |
| 87 | +</div> |
| 88 | +<div id="compiled-edsl-examples" class="slide section level1"> |
| 89 | +<h1>Compiled EDSL: Examples</h1> |
| 90 | +<ul class="incremental"> |
| 91 | +<li>The entire <em>Lava</em> family for circuit design and verification. (Compiles to: VHDL, Verilog, netlist? Reduceron from a few slides ago is implemented in York Lava.)</li> |
| 92 | +<li><em>Atom</em> for reactive, hard real-time, synchronous systems. (Compiles to: C)</li> |
| 93 | +<li><em>Copilot</em> for stream-oriented, hard real-time systems. (Compiles to: C via Atom & SBV, CBMC model checker)</li> |
| 94 | +<li><em>SBV</em> for theorem proving oriented around SMT. (Compiles to: C, various SMT solvers)</li> |
| 95 | +<li><em>Ivory</em> for safe systems programming. (Compiles to: C, LLVM(?), CVC4 & ACL2 theorem provers)</li> |
| 96 | +</ul> |
| 97 | +</div> |
| 98 | +<div id="atom-edsl" class="slide section level1"> |
| 99 | +<h1>Atom EDSL</h1> |
| 100 | +<p>The official definition: "Atom is a Haskell EDSL for designing hard realtime embedded software. Based on guarded atomic actions (similar to STM), Atom enables highly concurrent programming without the need for mutex locking. In addition, Atom performs compile-time task scheduling and generates code with deterministic execution time and constant memory use, simplifying the process of timing verification and memory consumption in hard realtime applications. Without mutex locking and run-time task scheduling, Atom eliminates the need and overhead of RTOSes for many embedded applications."</p> |
| 101 | +<p>Short version: Atom is a <em>synchronous language</em>: One specifies rules that apply on specific clock ticks, and all rules are atomic. Feed a specification into Atom, and Atom generates fairly bulletproof, deterministic C code.</p> |
| 102 | +</div> |
| 103 | +<div id="imaginary-atom-scenario" class="slide section level1"> |
| 104 | +<h1>Imaginary Atom scenario</h1> |
| 105 | +<ol class="incremental" style="list-style-type: decimal"> |
| 106 | +<li>You have a fairly resource-constrained microcontroller.</li> |
| 107 | +<li>It contains a hardware watchdog timer which you must reset every 15 milliseconds.</li> |
| 108 | +<li>You must monitor an input voltage. If it ever goes below 1.9 V, then the chip must cease all other operation (aside from resetting the watchdog) until it has stayed above 2.0 V for at least 10 milliseconds.</li> |
| 109 | +<li>There is an input button. If it is pressed for at least 50 milliseconds, its respective output pin should be toggled.</li> |
| 110 | +<li>There are incidentally 15 other buttons (and respective output pins) that behave the same way.</li> |
| 111 | +</ol> |
| 112 | +</div> |
| 113 | +<div id="my-workflow-for-those-interested" class="slide section level1"> |
| 114 | +<h1>My workflow, for those interested</h1> |
| 115 | +<ul> |
| 116 | +<li>Haskell code contains: |
| 117 | +<ul> |
| 118 | +<li>Specifications in Atom & Ivory</li> |
| 119 | +<li>Build targets for Shake (a Haskell-based build system)</li> |
| 120 | +</ul></li> |
| 121 | +<li>Shake build is responsible for: |
| 122 | +<ul> |
| 123 | +<li>Generating C code with Atom & Ivory</li> |
| 124 | +<li>Compiling & linking C code with GCC</li> |
| 125 | +<li>Producing a firmware image and commands for flashing it</li> |
| 126 | +</ul></li> |
| 127 | +<li>GDB communicates with GDB server</li> |
| 128 | +<li>JLink/OpenOCD implements GDB server and communicates with target via SWD</li> |
| 129 | +<li>Emacs communicates with GDB, handles Haskell and C code, and handles Shake build</li> |
| 130 | +</ul> |
| 131 | +</div> |
| 132 | +<div id="references-mindless-self-promotion" class="slide section level1"> |
| 133 | +<h1>References & Mindless Self-Promotion</h1> |
| 134 | +<p>Nearly everything that I reference should have a link at: <a href="http://haskellembedded.github.io/pages/links.html" class="uri">http://haskellembedded.github.io/pages/links.html</a></p> |
| 135 | +<p>My Atom introduction is at: <a href="http://haskellembedded.github.io/posts/2015-02-17-atom-examples.html" class="uri">http://haskellembedded.github.io/posts/2015-02-17-atom-examples.html</a></p> |
| 136 | +<p>In explaining the "How?" and "What?", I probably ignored much of the "Why?", and this explains some of that: <a href="http://haskellembedded.github.io/posts/2015-02-06-how-i-got-here.html" class="uri">http://haskellembedded.github.io/posts/2015-02-06-how-i-got-here.html</a></p> |
| 137 | +<p>See the <em>#haskell-embedded</em> IRC channel on Freenode to find me (<em>hodapp</em>) and a bunch of other people who are way better at this than I am.</p> |
| 138 | +</div> |
| 139 | +</div> |
| 140 | +</body> |
| 141 | +</html> |
0 commit comments