<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>golang | Craig Hesling</title><link>https://new.craighesling.com/tag/golang/</link><atom:link href="https://new.craighesling.com/tag/golang/index.xml" rel="self" type="application/rss+xml"/><description>golang</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Sun, 03 Jun 2018 07:46:59 -0500</lastBuildDate><image><url>https://new.craighesling.com/media/icon_hud2fdbe3c21f96e183bc7961971f91459_788_512x512_fill_lanczos_center_3.png</url><title>golang</title><link>https://new.craighesling.com/tag/golang/</link></image><item><title>SafetyFast</title><link>https://new.craighesling.com/project/safetyfast/</link><pubDate>Sun, 03 Jun 2018 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/safetyfast/</guid><description>&lt;p>Put thread-safety first, with the performance of safety last.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/SafetyFast_Preview.png" alt="Example SafetyFast Atomic usage" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>This is a Go library that implements synchronization primitives over
&lt;a href="https://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions" target="_blank" rel="noopener">Intel TSX&lt;/a> (Intel&amp;rsquo;s hardware transactional primitives).
The library exposes interfaces to make use of Intel HLE and Intel RTM.&lt;/p>
&lt;h1 id="usage-patterns">Usage Patterns&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">go get github.com/linux4life798/safetyfast
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="rtm-context">RTM Context&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="s">&amp;#34;github.com/linux4life798/safetyfast&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">r&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">safetyfast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewRTMContexDefault&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Atomic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">func&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">btc&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Touch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// Any action
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="hle-spin-lock">HLE Spin Lock&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;sync&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;github.com/linux4life798/safetyfast&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">m&lt;/span> &lt;span class="nx">sync&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Locker&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">safetyfast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">SpinHLEMutex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Lock&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">btc&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Touch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// Any action
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unlock&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="poster">Poster&lt;/h1>
&lt;a href="https://craighesling.com/files/SafetyFast_Poster.pdf">Download PDF&lt;/a>
&lt;p>A preview of the PDF should appear below. If it does not show up soon, please refresh the page.&lt;/p>
&lt;iframe src="https://docs.google.com/gview?url=https%3a%2f%2fcraighesling.com%2ffiles%2fSafetyFast_Poster.pdf&amp;embedded=true" style="width:100%; height:600px;" frameborder="0">
This browser does not support PDFs. Please download the PDF to view it: &lt;a href="https://craighesling.com/files/SafetyFast_Poster.pdf">Download PDF&lt;/a>
&lt;/iframe>
&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/linux4life798/safetyfast" target="_blank" rel="noopener">SafetyFast on Github&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions" target="_blank" rel="noopener">Intel TSX&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>GOBF</title><link>https://new.craighesling.com/post/gobf/</link><pubDate>Fri, 04 May 2018 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/gobf/</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>I have always been fascinated by compilers.
I think the idea of representing one language&amp;rsquo;s structure inside
of another language is just downright cool.
Furthermore, the ability to analyze another language and optimize it really peaks my interest.&lt;/p>
&lt;p>Recently, I worked on a project that would allow you to more precisely manage
which processor core a set of Goroutines would run on.
The idea was that Goroutines that communicate more than they process independently
would benefit from sharing that same processor core&amp;rsquo;s cache. I called them
M-Groups. The implementation called for modifying the &lt;code>runtime&lt;/code> package
and the Go scheduler.
While ripping through the Go internals, I stumbled upon quite a bit of the Go
compiler code, including the SSA library. As I ripped into it more,
I started to form an itch to make my own compiler of some kind.&lt;/p>
&lt;p>Fast forward a few months and I found myself staring at some examples of
my favorite simple esoteric language, &lt;a href="https://en.wikipedia.org/wiki/Brainfuck" target="_blank" rel="noopener">BF&lt;/a>.
BF is the perfect language to write a compiler / optimizer for because of its
extremely minimal syntax.
It only has 8 possible syntax items(called commands), &lt;code>&amp;lt;&amp;gt;+-.,[]&lt;/code>, but
those simple syntax items quickly form complex programs
(not in the sense of awesome functionality).&lt;/p>
&lt;p>Here is Hello World in BF&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-brainfuck" data-lang="brainfuck">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">++++++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">---&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++++++&lt;/span>&lt;span class="nt">..&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">--------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="c">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="gobf-overview">GOBF Overview&lt;/h2>
&lt;p>Introducing GOBF, an interpreter/optimizer/compiler/code_generator for the BF language.
It has two primary modes of operation, interpreting/running (as-is) and
converting BF to optimized Go code.&lt;/p>
&lt;h3 id="interpreting">Interpreting&lt;/h3>
&lt;p>Interpreting and running was the first mode of operation that really just
served to solidify my understanding of the BF language.
It simply sets up a virtual environment for the BF program and acts on each
syntax item as they come. There is no optimization here.&lt;/p>
&lt;h3 id="optimizing--compiling">Optimizing / Compiling&lt;/h3>
&lt;p>Next, I wanted to focus on how I would be able to generate super fast
binaries from my BF programs.
I considered lots of approaches, but the two most prominent ones were to
directly assemble a binary from the BF commands and convert BF to equivalent Go code.&lt;/p>
&lt;p>Directly assemble an x86 binary from the the BF commands seems like a natural
extension, since BF forces the programmer to act somewhat like a state machine.
The downside to this approach is that it would lack portability and would loose
out on further architectural optimizations that are found in modern compilers.&lt;/p>
&lt;p>I ultimately chose the ladder solution, where I convert the BF commands into
equivalent Go code.
Although it seems like a bulky implementation strategy, the program&amp;rsquo;s
functionality is quite limited and we gain the builtin compiler inlining.&lt;/p>
&lt;p>I have designed GOBF to parse BF programs and generate a internal
intermediate representation(IR) that resembles a tree.
The next major observation that BF contains lots of repetitive actions,
like &lt;code>++++++++&lt;/code>, which increments the local accumulator eight times, only to
save the value &lt;code>8&lt;/code>.
These repetitive actions can easily be smashed into a single operation, which
can yield massive speedups.
The GOBF optimizer traverses the IR tree and coalesces these
repetitive actions into a more descriptive single action.&lt;/p>
&lt;p>When the optimizer finishes, GOBF generates Go code from the IR
and optionally compiles it.&lt;/p>
&lt;h2 id="benchmarking">Benchmarking&lt;/h2>
&lt;p>I ran some of the typical BF programs you can find on the internet.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>BF Program&lt;/th>
&lt;th>Run Time&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>mandelbrot.b&lt;/td>
&lt;td>8.162s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hanoi.b&lt;/td>
&lt;td>5.401s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>helloworld.b&lt;/td>
&lt;td>0.003s&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;div class="alert alert-note">
&lt;div>
Running on an Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
&lt;/div>
&lt;/div>
&lt;h2 id="future-work">Future Work&lt;/h2>
&lt;p>I would like to create a reverse code generator that takes a high-level
language, such as Go, and generates BF.&lt;/p>
&lt;h3 id="links">Links&lt;/h3>
&lt;p>&lt;a href="https://github.com/linux4life798/gobf" target="_blank" rel="noopener">GOBF on Github&lt;/a>&lt;/p></description></item><item><title>dproto</title><link>https://new.craighesling.com/project/dproto/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/dproto/</guid><description>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/dproto_initialization.jpg" alt="Basic dproto usage" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>An on the fly Google protobuf decoder/encoder library.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>This library allows you to use Protobufs (Google Protocol Buffers) without needing to
generate protobuf code and compile it into your project.
This means you don&amp;rsquo;t need to compile .proto files.&lt;/p>
&lt;p>This library is designed for marshaling and unmarshalling protobufs in a &lt;em>dynamic&lt;/em> way.
It is designed to interface with any standard protobuf library and is tested against
the official protobuf C++ and Golang bindings, in addition to the C
&lt;a href="https://github.com/nanopb/nanopb" target="_blank" rel="noopener">Nanopdb&lt;/a> library.&lt;/p>
&lt;p>The intent of this library was to allow creating long running services that can
interpret and interface with clients using new/unknown protobuf messages.&lt;/p>
&lt;p>The basic idea is that you construct a &lt;code>ProtoFieldMap&lt;/code> that contains any protobuf
field number to protobuf type associations you are interested in and then you
call &lt;code>DecodeBUffer&lt;/code> on the protobuf payload.
&lt;code>DecodeBuffer&lt;/code> returns an array of &lt;code>FieldValue&lt;/code>s that it decoded from the payload.
Each &lt;code>FieldValue&lt;/code> specifies the protobuf field number and value decoded as a Golang
primitive(must be inside a &lt;code>interface{}&lt;/code>).&lt;/p>
&lt;h2 id="example-usage">Example Usage&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Encodes and Decodes a protobuf buffer that would interface with
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// a .proto file message containing &amp;#34;bool status =1;&amp;#34; and
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// &amp;#34;int64 intensity = 2;&amp;#34;.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="nf">ExampleNewProtoFieldMap&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Setup the ProtoFieldMap to interface with the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// following .proto file:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// message LightStatus {
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// bool status = 1;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// int64 intensity = 2;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Setup a FieldMap that holds the type-fieldnumber association
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// This is effectively the information held in a .proto file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">fm&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewProtoFieldMap&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Add Protobuf bool as field 1 (&amp;#34;bool status = 1;&amp;#34;)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">descriptor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldDescriptorProto_TYPE_BOOL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to add bool field 1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Add Protobuf int64 as field 2 (&amp;#34;int64 intensity = 2;&amp;#34;)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">descriptor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldDescriptorProto_TYPE_INT64&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to add bool field 1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Provide some values for our &amp;#34;status&amp;#34; and &amp;#34;intensity&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">values&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Field&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// status field number
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">Value&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">bool&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Field&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// intensity field number
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">Value&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int64&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Encode out values into the protobuf message described in fm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">bytes&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">EncodeBuffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">values&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Error Encoding: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">err&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Error&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;ProtobufBinary: [ %# x ]\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">bytes&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Decode all protobuf fields
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">decodedValues&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">DecodeBuffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">bytes&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Error Decoding: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">err&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Error&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">decodedValues&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%v: %v\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Field&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Value&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Unordered output:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ProtobufBinary: [ 0x08 0x01 0x10 0x0a ]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 1: true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 2: 10
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/linux4life798/dproto" target="_blank" rel="noopener">Dproto on Github&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://developers.google.com/protocol-buffers/" target="_blank" rel="noopener">Google Protobufs&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Easybits Serialization Service</title><link>https://new.craighesling.com/project/easybits/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/easybits/</guid><description>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/easybits_config_example3.png" alt="Example Easybits device configuration" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Easybits is an on-the-fly Google protobuf stream decoder/encoder for
&lt;a href="https://new.craighesling.com/project/openchirp/">OpenChirp&lt;/a>.
This service is one of the core services that an embedded device may
need in it&amp;rsquo;s OpenChirp data pipeline.&lt;/p>
&lt;p>The idea is that your device would use Google Protobufs to serialize
(and deserialize) it&amp;rsquo;s data and sends it to OpenChirp.
The Easybits service is then invoked, which deserializes your data and
publishes human readable values back to OpenChirp.&lt;/p>
&lt;p>Easybits just needs the user to describe what protobuf types were declared
and where to place the data.&lt;/p>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;p>Google Protobufs are great for creating compact serialized data packets for
typical sensor values.&lt;/p>
&lt;p>Protobufs requires you to create a &lt;code>.proto&lt;/code> file that
describes what data you intend to send back and forth. It then compiles this
&lt;code>.proto&lt;/code> file into a set of language specific interface files, which
containing functions and objects to represent and aggregate your data.&lt;/p>
&lt;blockquote>
&lt;p>Here is an example &lt;code>.proto&lt;/code> file description for a smart light bulb.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// SmartBulb.proto
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">syntax&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;proto3&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="kd">message&lt;/span> &lt;span class="nc">LightStatus&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">status&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="n">intensity&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Due to this native language integration, protobufs are easy for end users to
pack up and send data messages, but it is non-trivial to create long running
services that can interpret all possible custom protobuf messages, without
recompilation.&lt;/p>
&lt;p>To get around the Protobuf constraint of recompiling for every new protobuf
message, Easybits uses &lt;a href="https://new.craighesling.com/project/dproto/">dproto&lt;/a> to adapt to new user
described messages, without even restarting.&lt;/p>
&lt;h2 id="links">Links&lt;/h2>
&lt;p>&lt;a href="https://github.com/OpenChirp/easybits-service" target="_blank" rel="noopener">Easybits on Github&lt;/a>&lt;/p></description></item><item><title>OpenChirp</title><link>https://new.craighesling.com/project/openchirp/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/openchirp/</guid><description>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Gateway 1" href="https://new.craighesling.com/project/openchirp/GSIA_GW_hu8af566d35e172a1448aad7b439b9ad98_1089158_1920x0_resize_q75_lanczos.jpg">
&lt;img alt="GSIA_GW.jpg" src="https://new.craighesling.com/project/openchirp/GSIA_GW_hu8af566d35e172a1448aad7b439b9ad98_1089158_1920x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="OpenChirp Logo" href="https://new.craighesling.com/project/openchirp/OCStickerDark.svg">
&lt;img alt="OCStickerDark.svg" src="https://new.craighesling.com/project/openchirp/OCStickerDark.svg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="A gateway up-close" href="https://new.craighesling.com/project/openchirp/OnGround_Wean_GW_hu2ae3da5a428bf1047e2250f9a743cb87_3037040_3024x0_resize_q75_lanczos.jpg">
&lt;img alt="OnGround_Wean_GW.jpg" src="https://new.craighesling.com/project/openchirp/OnGround_Wean_GW_hu2ae3da5a428bf1047e2250f9a743cb87_3037040_3024x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Gateway 2" href="https://new.craighesling.com/project/openchirp/SouthCraig_GW_hu3c1fbb5776c28c3856df7474a5b76c50_1314334_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="SouthCraig_GW.jpg" src="https://new.craighesling.com/project/openchirp/SouthCraig_GW_hu3c1fbb5776c28c3856df7474a5b76c50_1314334_3120x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Gateway 3" href="https://new.craighesling.com/project/openchirp/Wean_GW_hu9b7bdac86ca23d1aa5a7028c80665157_715377_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="Wean_GW.jpg" src="https://new.craighesling.com/project/openchirp/Wean_GW_hu9b7bdac86ca23d1aa5a7028c80665157_715377_3120x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;/div>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>We are creating a community-driven low-power wireless connectivity solution for
IoT.&lt;/p>
&lt;h2 id="my-contributions">My Contributions&lt;/h2>
&lt;ul>
&lt;li>Designed, built, and installed outdoor gateways&lt;/li>
&lt;li>Created custom Debian packages for gateway software and configuration - &lt;a href="https://github.com/OpenChirp/ocgw" target="_blank" rel="noopener">ocgw&lt;/a>&lt;/li>
&lt;li>Created gateway system monitoring service - &lt;a href="https://github.com/OpenChirp/sysmonitor-device" target="_blank" rel="noopener">SysMonitor Device&lt;/a>&lt;/li>
&lt;li>Created the Golang framework for Users, Devices, and Services - &lt;a href="https://github.com/OpenChirp/framework" target="_blank" rel="noopener">framework&lt;/a> and &lt;a href="https://github.com/OpenChirp/example-service" target="_blank" rel="noopener">Example Service&lt;/a>&lt;/li>
&lt;li>Created the LoRaWAN integration service&lt;/li>
&lt;li>Created data serialization/deserialization services - &lt;a href="https://github.com/OpenChirp/bytetranslator-service" target="_blank" rel="noopener">ByteTranslator Service&lt;/a> and &lt;a href="https://new.craighesling.com/project/easybits">Easybits Service&lt;/a>&lt;/li>
&lt;li>Created prototype trigger service - &lt;a href="https://github.com/OpenChirp/trigger-service" target="_blank" rel="noopener">Trigger Service&lt;/a>&lt;/li>
&lt;li>Designed and built ultra low-power LoRaWAN client devices - &lt;a href="https://new.craighesling.com/project/lorabug">The LoRaBug&lt;/a>&lt;/li>
&lt;li>Created the hardware abstraction layer and adapted the necessary firmware stacks for the LoRaBug - &lt;a href="https://new.craighesling.com/project/lorabug/#software">LoRaBug Software&lt;/a>&lt;/li>
&lt;li>Created serial bootloader tool to flash the LoRaBug over micro USB - &lt;a href="https://new.craighesling.com/post/cc2538-cc26xx-bootloader/">ccbootutil&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Checkout the &lt;a href="http://OpenChirp.io" target="_blank" rel="noopener">OpenChirp.io Website&lt;/a>&lt;/p></description></item><item><title>System Monitor Device (for OpenChirp)</title><link>https://new.craighesling.com/post/sysmonitor-device/</link><pubDate>Mon, 06 Nov 2017 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/sysmonitor-device/</guid><description>&lt;h2 id="summary">Summary&lt;/h2>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;h2 id="links">Links&lt;/h2>
&lt;p>&lt;a href="https://github.com/OpenChirp/sysmonitor-device" target="_blank" rel="noopener">sysmonitor-device on Github&lt;/a>&lt;/p></description></item><item><title>TI CC2538/CC26xx Serial Bootloader Utility on Linux</title><link>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</link><pubDate>Tue, 11 Apr 2017 11:30:41 -0500</pubDate><guid>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</guid><description>&lt;p>If you have ever been curious about using the TI CC2650 and other similar SimpleLink devices&amp;rsquo; serial bootloader, wonder no longer.&lt;/p>
&lt;p>I recently implemented the TI CC2538/CC26xx Serial Bootloader protocol in a Go library, called &lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">ccboot&lt;/a>.
This simply uses standard IO operations that can be used with a generic serial library.&lt;/p>
&lt;p>Since a library is no fun without a command line interface, I have also implemented &lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">ccbootutil&lt;/a>, which exposes most of the low level bootloader primitives(which can be shell scripted) and has a complete program sequence that reads ELF binaries, flashes, and resets the chip. You simply run the following command and ccbootutil did the rest:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cbootutil /dev/ttyUSB0 prgm YourCompiledProgramInStandardELFFormat.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When implementing ccbootutil, I used a Go serial port interface library that indicated that it should work cross platform, so Windows and OSX users should not feel left out of the command line and scriptable goodness.&lt;/p>
&lt;p>I have compiled the utility for each of the platforms in the repository &lt;a href="https://github.com/OpenChirp/ccbootutil/tree/master/builds" target="_blank" rel="noopener">builds/&lt;/a> directory.&lt;/p>
&lt;h2 id="notes">Notes&lt;/h2>
&lt;ul>
&lt;li>I have found that the serial bootloader can flash the CC2650 faster than an XDS110 over cJTAG.&lt;/li>
&lt;li>TI Smart RF Flash Programmer 2 certainly works, but is strictly for Windows and is not scriptable.&lt;/li>
&lt;/ul>
&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">https://github.com/OpenChirp/ccbootutil&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">https://github.com/OpenChirp/ccboot&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Please let me know if you find any issues. Happy coding!&lt;/p></description></item></channel></rss>