<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Python &#8211; IoT Expert</title>
	<atom:link href="https://iotexpert.com/category/tools/python/feed/" rel="self" type="application/rss+xml" />
	<link>https://iotexpert.com</link>
	<description>Engineering for the Internet of Things</description>
	<lastBuildDate>Mon, 04 Jan 2021 22:05:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://iotexpert.com/wp-content/uploads/2017/01/cropped-Avatar-32x32.jpg</url>
	<title>Python &#8211; IoT Expert</title>
	<link>https://iotexpert.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Stupid Python Tricks: Implementing a c-switch</title>
		<link>https://iotexpert.com/stupid-python-tricks-implementing-a-c-switch/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-implementing-a-c-switch/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 12:25:44 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9643</guid>

					<description><![CDATA[Summary A discussion of a simple method in Python to implement the equivalent of a c programming style switch. Story Recently, I was working on an example where I would have used something like this if I was programming in C (emphasis on like) #include &#60;stdio.h&#62; typedef enum { op0, op1, op2, op3 } opcodes_t; [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of a simple method in Python to implement the equivalent of a c programming style switch.</p>
<h1>Story</h1>
<p>Recently, I was working on an example where I would have used something like this if I was programming in C (emphasis on like)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include &lt;stdio.h&gt;

typedef enum {
    op0,
    op1,
    op2,
    op3
} opcodes_t;

int main(int argc,char **argv)
{
    opcodes_t excode = op1;

    switch(excode)
    {
        case 0:
            printf("opcode 0");
            break;
        case 1:
            printf("opcode 1");
            break;
        case 2:
            printf("opcode 2");
            break;
        case 3:
            printf("opcode 3");
            break;

    }

}</pre>
<p>And, as you know, I am not a real Python programmer.  I tried switch&#8230; obviously to no avail.  So now what?  Well in the example above I have</p>
<ul>
<li>A list of keys, the enumerated opcode_t</li>
<li>That have a values e.g. &#8220;opcode 0&#8221; etc.</li>
</ul>
<p>Sounds like a dictionary.  Here is the equivalent code in Python:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">opcode_t = {
    0:"opcode 0",
    1:"opcode 1",
    2:"opcode 2",
    3:"opcode 3",
}

ex1 = 1

print(opcode_t[ex1])</pre>
<p>But what happens if a key is missing?  The bracket[] method of a dictionary is equivalent to the dictionary method &#8220;get&#8221;.   The &#8220;get&#8221; method has a default case if they key is missing from the dictionary.  Here is the example code:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">opcode_t = {
    0:"opcode 0",
    1:"opcode 1",
    2:"opcode 2",
    3:"opcode 3",
}

ex1 = 1

# will return "not found" if the key is not in the dictionary
print(opcode_t.get(ex1,"Not Found"))</pre>
<p>What if you want to do something?  Values in dictionaries can be &#8220;function pointers&#8221; (is what I would call them in C).  They are probably properly called references in Python.  Regardless, here is some absurd code that demonstrates the example.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">def opcode0():
    return "opcode 0"

def opcode1():
    return "opcode 1"

def opcode2():
    return "opcode 2"

def opcode3():
    return "opcode 3"

opcode1_t = {
    0:opcode0,
    1:opcode1,
    2:opcode2,
    3:opcode3,
}

ex1 = 1

print(opcode1_t[ex1]())
</pre>
<h1>My mDNS Example</h1>
<p>The example that lead me to this problem was decoding mDNS headers which have 8 fields of different lengths and possible values.  Here is what I actually did:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    qrText = {0:"Query",1:"Response"}
    opcodeText = {0:"Query",1:"IQuery",2:"Status",3:"reserved",4:"Notify",5:"Update"}
    aaText = {0:"Non Authoratative",1:"Authoratative"}
    tcText = {0:"No Truncation",1:"Truncation"}
    rdText = {0:"No Recursion",1:"Recursion"}
    raText = {0:"No Recursion Available",1:"Recursion Available"}
    zText = {0:"Reserved"}
    rcodeText = {
        0:"No Error",
        1:"Format Error",
        2:"Server Failure",
        3:"Name Error",
        4:"Not implemented",
        5:"Refused - probably a policy reason",
        6:"A name exists when it should not",
        7:"a resource record set exists that should not",
        8:"NX RR Set - A resource record set that should exist does not",
        9:"Not Authorized",
        10:"Not Zone",
    }

    def printHeader(self):
        print(f"id = {self.id}")
        print(f"qr = {self.qr} {self.qrText.get(self.qr,'Unknown')}")
        print(f"opcode = {self.opcode} {self.opcodeText.get(self.opcode,'Unknown')}")
        print(f"aa = {self.aa} {self.aaText.get(self.aa,'Unknown')}")
        print(f"tc = {self.tc} {self.tcText.get(self.tc,'Unknown')}")
        print(f"rd = {self.rd} {self.rdText.get(self.rd,'Unknown')}")
        print(f"ra = {self.ra} {self.raText.get(self.ra,'Unknown')}")
        print(f"z = {self.z} {self.zText.get(self.z,'Unknown')}")
        print(f"response code = {self.rcode} {self.rcodeText.get(self.rcode,'Unknown')}")
        print(f"rc question count = {self.qdcount}")
        print(f"answer count = {self.ancount}")
        print(f"name server count = {self.nscount}")
        print(f"additional record count = {self.arcount}")</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-implementing-a-c-switch/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stupid Python Tricks: C-Structures using the ctypes Module (part 2)</title>
		<link>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module-part-2/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module-part-2/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 24 Aug 2020 15:53:52 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9645</guid>

					<description><![CDATA[Summary A discussion of overriding __new__ and __init__ to simplify the creation Python cstruct.Structure objects. Creating a new cytpes.BigEndianStructure Here is a simple example of a 2-byte structure using the ctypes.BigEndianStructure class. In this example I: Derive a new class called MyStruct from the BigEndianStructure Declare three fields called first (4-bits), second (4-bits) and third (8-bits). [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of overriding __new__ and __init__ to simplify the creation Python cstruct.Structure objects.</p>
<h1>Creating a new cytpes.BigEndianStructure</h1>
<p>Here is a simple example of a 2-byte structure using the ctypes.BigEndianStructure class.</p>
<p>In this example I:</p>
<ul>
<li>Derive a new class called MyStruct from the BigEndianStructure</li>
<li>Declare three fields called first (4-bits), second (4-bits) and third (8-bits).</li>
<li>Create a new object of MyStruct type called &#8220;a&#8221;</li>
<li>Set the values of the three fields</li>
<li>Print it out.</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="c">import ctypes

class MyStruct(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [    ("first",ctypes.c_uint8,4),
                    ("second",ctypes.c_uint8,4),
                    ("third",ctypes.c_uint8,8),
                 ]

# Create a blank MyStruct
a = MyStruct()
a.first  = 0xa
a.second = 0xb
a.third  = 0xcd
print(bytes(a))</pre>
<p>When I run this you can see that indeed I get 0xABCD as the result.  Several comments about this:</p>
<ul>
<li>Notice that it is BigEndian (which is good since that is what I declared)</li>
<li>0xA = 4-bits, 0-xB=4-bit so 0xAB is the first byte.</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="c">(venv) $ python ex-struct.py 
b'\xab\xcd'</pre>
<p>You can also create a new structure by calling the class method &#8220;from_buffer_copy&#8221; with parameter of bytes type.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c"># Create a MyStruct initialized to Hex ABCD
b = MyStruct.from_buffer_copy(b"\xab\xcd")
print(bytes(b))</pre>
<p>When you run this, you get the same result.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">(venv) $ python ex-struct.py 
b'\xab\xcd'</pre>
<p>What I was really hoping to be able to do is create a new structure from an array of bytes like this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c"># Create a new MyStruct from an Array of bytes ... this is gonna crash
c = MyStruct(b"\x0abb\xcd")
print(bytes(c))</pre>
<p>But that crashes.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">(venv) $ python ex-struct.py 
b'\xab\xcd\x00\x00'
b'\nbb\xcd'
Traceback (most recent call last):
  File "ex-struct.py", line 24, in &lt;module&gt;
    c = MyStruct(b"\x0abb\xcd")
TypeError: an integer is required (got type bytes)
(venv) $</pre>
<p>And for some reason this took me a really long time to figure out.  You probably say to yourself, &#8220;Im not surprised it took him so long to figure out.  He is programming in Python so he probably isn&#8217;t very smart anyway&#8221;</p>
<h1>Overriding __new__ &amp; __init__</h1>
<p>While working to understand, I ran into the article &#8220;<a href="https://wumb0.in/a-better-way-to-work-with-raw-data-types-in-python.html" target="_blank" rel="noopener noreferrer">A better way to work with raw data types in Python</a>&#8221; which I found interesting.  Here is a screen shot of a bit of the code.</p>
<p><a href="https://iotexpert.com/2020/08/24/stupid-python-tricks-c-structures-using-the-ctypes-module-part-2/screen-shot-2020-08-09-at-10-48-02-am/" rel="attachment wp-att-9650"><img fetchpriority="high" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-1024x536.png" alt="" width="1024" height="536" class="alignnone size-large wp-image-9650" srcset="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-1024x536.png 1024w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-600x314.png 600w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-300x157.png 300w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-768x402.png 768w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-1536x804.png 1536w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-09-at-10.48.02-AM-2048x1072.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>OK.  So lets add the dunder init and dunder new methods to my class.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">class MyStruct1(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [    ("first",ctypes.c_uint8,4),
                    ("second",ctypes.c_uint8,4),
                    ("third",ctypes.c_uint8,8),
                 ]

    def __new__(self,sb=None):
        if(sb):
            return self.from_buffer_copy(sb)
        else:
            return ctypes.BigEndianStructure.__new__(self)

    def __init__(self,sb=None):
        pass

print("Next case")

c = MyStruct1()
c.first  = 0xa
c.second = 0xb
c.third  = 0xcd
print(bytes(c))

d = MyStruct1(b'\xab\xcd')
print(bytes(d))</pre>
<p>Now when I run it, things are good.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">(venv) $ python ex-struct.py 

Next case
b'\xab\xcd'
b'\xab\xcd'</pre>
<h1>Why do I need the __init__?</h1>
<p>So, why do I need the dunder init that doesn&#8217;t actually do anything? Presumably if I was a real python programmer I would have already known the answer.  But I&#8217;m not, so I didn&#8217;t.</p>
<p>The first question I had is what does the Python keyword &#8220;pass&#8221; do?  The answer is nothing.  It is a nop or void if you prefer and is there just to make the program legal as a function has to have some function.</p>
<p>Then onto the Python <a href="https://docs.python.org/3/reference/datamodel.html" target="_blank" rel="noopener noreferrer">documentation</a> where I found that if you have an __new__ method that returns an object of the subtype Python will automatically call the __init__ function.</p>
<p><a href="https://iotexpert.com/2020/08/24/stupid-python-tricks-c-structures-using-the-ctypes-module-part-2/screen-shot-2020-08-10-at-8-13-30-am/" rel="attachment wp-att-9654"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-1024x602.png" alt="" width="1024" height="602" class="alignnone size-large wp-image-9654" srcset="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-1024x602.png 1024w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-600x353.png 600w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-300x176.png 300w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-768x452.png 768w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM-1536x903.png 1536w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-10-at-8.13.30-AM.png 1636w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>A Conundrum</h1>
<p>The other interesting function that the author added was added was:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">def __str__(self):
  return buffer(self)[:]
</pre>
<p>This function actually crashes because there is no member called &#8220;buffer&#8221;.  I am not sure if the cause is:</p>
<ul>
<li>The buffer attribute was left out of the class by the author</li>
<li>The buffer was formerly an attribute of the Python 2.x ctypes base class (this is what I suspect)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module-part-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stupid Python Tricks: C-Structures using the ctypes Module</title>
		<link>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 17 Aug 2020 11:40:55 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9604</guid>

					<description><![CDATA[Summary A discussion of reading data out of stream of bytes (encoded in a C-like structure) using the Python ctypes module.  The data in the stream is a UDP packet that represents an mDNS query or request.  The purpose of this article is to explain a process for decoding bytes streams in Python Story While [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of reading data out of stream of bytes (encoded in a C-like structure) using the Python ctypes module.  The data in the stream is a UDP packet that represents an mDNS query or request.  The purpose of this article is to explain a process for decoding bytes streams in Python</p>
<h1>Story</h1>
<p>While I was working on A-Class Linux implementations I fell down the rabbit hole of mDNS.  mDNS is a part of the set of protocols that make up &#8220;Zero Configuration Networking&#8221;.  In order to understand the protocol I decided to implement (partially) an mDNS server.  You can read about that protocol and my implementation &#8211; when I get done :-).  However, all of that isn&#8217;t really important to this article, but it did bring me to dig into techniques for examining bytes in Python.</p>
<p>I doubt that this article is canonical, but I hope that it is at least useful.  I did find quite a few partial discussions of this topic, but I had to dig into to really understand.</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Python</th>
<th >Comment</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://docs.python.org/3/library/stdtypes.html?highlight=bytearray#bytes" target="_blank" rel="noopener noreferrer">bytes</a></td>
<td >A built in object to represent an immutable sequence of single bytes.</td>
</tr>

<tr><td ><a href="https://docs.python.org/3/library/stdtypes.html?highlight=bytearray#bytearray" target="_blank" rel="noopener noreferrer">bytearray</a></td>
<td >A built in object to represent a mutable sequence of single bytes.</td>
</tr>

<tr><td ><a href="https://docs.python.org/3.8/library/struct.html#module-struct" target="_blank" rel="noopener noreferrer">struct</a></td>
<td >A module to encode and decode bytes from c-like structures (unfortunately the byte is an atomic unit of the struct module)</td>
</tr>

<tr><td ><a href="https://docs.python.org/3/library/ctypes.html#module-ctypes" target="_blank" rel="noopener noreferrer">ctypes</a></td>
<td >A module to interface to C functions and data.  It contains a bunch of classes which can be used to interface with C-Structures (like the struct module)</td>
</tr>
</tbody></table></div>
<p>There are bunches of web hits on this topic.  However, here are a few which I found useful.</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Link</th>
<th >Comment</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://pythonpedia.com/en/tutorial/9050/ctypes" target="_blank" rel="noopener noreferrer">link</a></td>
<td >A basic discussion of the ctypes module and the basic classes</td>
</tr>

<tr><td ><a href="https://www.programcreek.com/python/example/1585/ctypes.sizeof" target="_blank" rel="noopener noreferrer">link</a></td>
<td >A discussion of the ctypes.sizeof function</td>
</tr>

<tr><td ><a href="http://dabeaz.blogspot.com/2010/01/few-useful-bytearray-tricks.html" target="_blank" rel="noopener noreferrer">link</a></td>
<td >A discussion of the bytearray</td>
</tr>

<tr><td ><a href="https://wumb0.in/a-better-way-to-work-with-raw-data-types-in-python.html" target="_blank" rel="noopener noreferrer">link</a></td>
<td >A Better Way to Work with Raw Data Types in Python</td>
</tr>
</tbody></table></div>
<h1>The UDP Header for a mDNS Packet</h1>
<p>The IETF <a href="https://tools.ietf.org/html/rfc6895" target="_blank" rel="noopener noreferrer">RFC 6895</a> documents the header format for mDNS (and DNS) packets.  The header contains data in Big Endian format encoded into 12 bytes that are broken up into bits, several-bits, and a few 16-bit integers.  Here is snapshot from the RFC.</p>
<p>&nbsp;</p>
<p><a href="https://iotexpert.com/2020/08/17/stupid-python-tricks-c-structures-using-the-ctypes-module/screen-shot-2020-08-08-at-11-32-36-am/" rel="attachment wp-att-9618"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM-966x1024.png" alt="" width="966" height="1024" class="alignnone size-large wp-image-9618" srcset="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM-966x1024.png 966w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM-600x636.png 600w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM-283x300.png 283w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM-768x814.png 768w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.36-AM.png 1236w" sizes="(max-width: 966px) 100vw, 966px" /></a> <a href="https://iotexpert.com/2020/08/17/stupid-python-tricks-c-structures-using-the-ctypes-module/screen-shot-2020-08-08-at-11-32-53-am/" rel="attachment wp-att-9619"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM-1024x117.png" alt="" width="1024" height="117" class="alignnone size-large wp-image-9619" srcset="https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM-1024x117.png 1024w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM-600x68.png 600w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM-300x34.png 300w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM-768x88.png 768w, https://iotexpert.com/wp-content/uploads/2020/08/Screen-Shot-2020-08-08-at-11.32.53-AM.png 1174w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>A Red Herring</h1>
<p>OK, I admit it.  I am a C-Programmer from way back.  My first inclination to decode the bytes looked like this:</p>
<ul>
<li>Using shifts and or&#8217;s to assemble the bytes into big endian uint16s e.g. line 2</li>
<li>Using bit masks and logic &#8220;and&#8221; with or&#8217;s and shifts to pick out bit fields e.g. line 12</li>
<li>Using a tower of if/elif/elif/else to decode the individual values e.g. lines</li>
</ul>
<p>Here is my first crack at this.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="&quot;c”">    id = message[0] &lt;&lt; 8 | message[1]
    print(f"Id = {id}")
   
    QRFlag = (message[2] &amp; 0x80) &gt;&gt; 7
    if QRFlag == 0:
        QRFlagText = "QUERY"
    else:
        QRFlagText = "RESPONSE"
        
    print(f"Query Flag = {QRFlagText}")

    opCode = (0b01111000 &amp; message[2]) &gt;&gt; 3
    if opCode == 0:
        opCodeText = "Query"
    elif opCode == 1:
        opCodeText = "IQUERY"
    elif opCode == 2:
        opCodeText = "Status"
    elif opCode == 3:
        opCodeText = "Reserved"
    elif opCode == 4:
        opCodeText = "Notify"
    elif opCode == 5:
        opCodeText = "Update"
    else :
        opCodeText = "Unknown"
   
    print(f"Opcode ={opCode} {opCodeText}")

    AAFlag = (message[2] &amp; 0b00000100) &gt;&gt; 2
    AAFlagText = "Authoritative" if AAFlag == 1 else "Non-Authoritative"
    print(f"AA Flag = {AAFlag} {AAFlagText}")

    TCFlag = (message[2] &amp; 0b00000010) &gt;&gt; 1
    TCFlagText = "Truncation" if TCFlag == 1 else "No Truncation"
    print(f"TCFlag = {TCFlag} {TCFlagText}")

    RDFlag = message[2] &amp; 0b00000001
    RDFlagText = "Recursion" if RDFlag == 1 else "No Recursion"
    print(f"RDFlag = {RDFlag} {RDFlagText}")

    RAFlag = (message[3] &amp; 0b10000000) &gt;&gt; 7
    RAFlagText = "Recursion Available" if RDFlag == 1 else "No Recursion Available"
    print(f"RAFlag = {RAFlag} {RAFlagText}")

    ZFlag =  (message[3] &amp; 0b01110000) &gt;&gt; 4
    print(f"Reserved ZFlag = {ZFlag}")

    RCCode = message[3] &amp; 0b00001111
    if RCCode == 0:
        RCCodeText = "No Error"
    elif RCCode == 1:
        RCCodeText == "Format Error"
    elif RCCode == 2:
        RCCodeText == "Server Failure"
    elif RCCode == 3:
        RCCodeText == "Name Error"
    elif RCCode == 4:
        RCCodeText == "Not Implemented"
    elif RCCode == 5:
        RCCodeText == "Refused"
    elif RCCode == 6:
        RCCodeText == "Yx Domain"
    elif RCCode == 7:
        RCCodeText == "YX RR Set"
    elif RCCode == 8:
        RCCodeText == "NX RR Set"
    elif RCCode == 9:
        RCCodeText == "Not Authorized"
    elif RCCode == 10:
        RCCodeText == "Not Zone"

    print(f"RCCode = {ZFlag} {RCCodeText}")


    QDCount = message[4]&lt;&lt;8  | message[5]
    ANCount = message[6]&lt;&lt;8  | message[7]
    NSCount = message[8]&lt;&lt;8  | message[9]
    ARCount = message[10]&lt;&lt;8 | message[11]
    print(f"Questions = {QDCount} Answers = {ANCount} Name Servers = {NSCount} Additional Records = {ARCount}")</pre>
<h1>Encoding a c-structure with Bits</h1>
<p>I didn&#8217;t really like the above implementation.  So I kept digging.  After a while I found the ctypes module.  This lets you</p>
<ul>
<li>Derive a new class from the BigEndianStructure class (line 1)</li>
<li>Pack all of the bits and bytes next to each other (line 2)</li>
<li>Specify the field names, type and optionally the length in bits (line</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="&quot;c”">class dnsHeader(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [    ("id",ctypes.c_uint,16),
                    ("qr",ctypes.c_uint,1),
                    ("opcode",ctypes.c_uint,4),
                    ("aa",ctypes.c_uint,1),
                    ("tc",ctypes.c_uint,1),
                    ("rd",ctypes.c_uint,1),
                    ("ra",ctypes.c_uint,1),
                    ("z",ctypes.c_uint,3),
                    ("rcode",ctypes.c_uint,4),
                    ("qdcount",ctypes.c_uint16),
                    ("ancount",ctypes.c_uint16),
                    ("nscount",ctypes.c_uint16),
                    ("arcount",ctypes.c_uint16),

    ]</pre>
<p>When you receive data from a socket you will get a tuple that contains</p>
<ol>
<li>a &#8220;bytes&#8221; type object containing the raw bytes of the message</li>
<li>a &#8220;tuple&#8221; containing the IP address (not relevant to this discussion)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="&quot;c”">    (message, address) = UDPServerSocket.recvfrom(bufferSize)</pre>
<p>Now that you have the bytes you can create an object of dnsHeader type to interpret the bytes.  The ctypes class method &#8220;from_buffer_copy&#8221; will take an array of bytes that is at least the length of the structure and return an object of the type of &#8220;dnsHeader&#8221;.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c” ">    dnsh = dnsHeader.from_buffer_copy(message)</pre>
<p>Then you can look at the individual fields like this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c” ">print(f"id = {self.id}")</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-c-structures-using-the-ctypes-module/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stupid Python Tricks &#8211; Ensure PIP &#038; Virtual Environments</title>
		<link>https://iotexpert.com/stupid-python-tricks-ensure-pip-virtual-environments/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-ensure-pip-virtual-environments/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 03 Aug 2020 12:00:25 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=8467</guid>

					<description><![CDATA[Summary This article will show you how to fix your Python setup such that virtual environments that you create will have the correct version of PIP The Story I frequently take screen shots as part of my article writing process.  And it absolutely drives me crazy to have &#8220;crap&#8221; on the screen e.g. warning messages. [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article will show you how to fix your Python setup such that virtual environments that you create will have the correct version of PIP</p>
<h1>The Story</h1>
<p>I frequently take screen shots as part of my article writing process.  And it absolutely drives me crazy to have &#8220;crap&#8221; on the screen e.g. warning messages.  I was recently working on an article about PyVISA &#8211; a Python package for interacting with Lab Instruments &#8211; when I got this error message about the wrong PIP version.</p>
<p><a href="https://iotexpert.com/?attachment_id=8487" rel="attachment wp-att-8487"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.30.11-AM.png" alt="" width="732" height="218" class="alignnone size-full wp-image-8487" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.30.11-AM.png 732w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.30.11-AM-600x179.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.30.11-AM-300x89.png 300w" sizes="auto, (max-width: 732px) 100vw, 732px" /></a></p>
<p>But how can this be as I know that I have the correct version (which at the time was 20.0.2).  You obviously can &#8220;fix&#8221; this by running an upgrade of pip in your virtual environment.</p>
<p><a href="https://iotexpert.com/?attachment_id=8497" rel="attachment wp-att-8497"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.10.32-PM.png" alt="" width="745" height="283" class="alignnone size-full wp-image-8497" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.10.32-PM.png 745w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.10.32-PM-600x228.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.10.32-PM-300x114.png 300w" sizes="auto, (max-width: 745px) 100vw, 745px" /></a></p>
<p>But that doesn&#8217;t really &#8220;fix&#8221; it.  It just means that the virtual environment you just created has the most up to date PIP.  What is frustrating is that when you exit the virtual environment, the PIP version is correct (look 20.0.2)</p>
<p><a href="https://iotexpert.com/?attachment_id=8488" rel="attachment wp-att-8488"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.33.55-AM.png" alt="" width="704" height="98" class="alignnone size-full wp-image-8488" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.33.55-AM.png 704w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.33.55-AM-600x84.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.33.55-AM-300x42.png 300w" sizes="auto, (max-width: 704px) 100vw, 704px" /></a></p>
<p>Why are the environments differ?   The answer is when you create a virtual environment it will copy Python, pip and easy_install to your binary directory.</p>
<p><a href="https://iotexpert.com/?attachment_id=8495" rel="attachment wp-att-8495"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-11.56.10-AM.png" alt="" width="561" height="175" class="alignnone size-full wp-image-8495" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-11.56.10-AM.png 561w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-11.56.10-AM-300x94.png 300w" sizes="auto, (max-width: 561px) 100vw, 561px" /></a></p>
<p>As part of doing this it will pickup the &#8220;<a href="https://docs.python.org/3/library/ensurepip.html" target="_blank" rel="noopener noreferrer">ensurepip</a>&#8221; version of PIP which is embedded in the Python installation on your computer.  Ensure pip just ensures that there will be a pip version available in any given Python installation even though Pip is not installed with Python.  On my computer the ensurepip is embedded deeply in a Hombrew directory:</p>
<p><a href="https://iotexpert.com/?attachment_id=8499" rel="attachment wp-att-8499"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.19.58-PM.png" alt="" width="733" height="371" class="alignnone size-full wp-image-8499" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.19.58-PM.png 733w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.19.58-PM-600x304.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.19.58-PM-300x152.png 300w" sizes="auto, (max-width: 733px) 100vw, 733px" /></a></p>
<p>In the screen above you can see that my ensurepip has &#8220;19.2.3&#8221; when the rest of my computer is set to &#8220;20.0.2&#8221;. So how do you fix the ensurepip?  Well I first thought that perhaps running the &#8220;ensurepip&#8221; with the upgrade flag would do it.  Here is what happens.  It seems to fix it.  (but it doesn&#8217;t).</p>
<p><a href="https://iotexpert.com/?attachment_id=8489" rel="attachment wp-att-8489"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.35.01-AM.png" alt="" width="795" height="142" class="alignnone size-full wp-image-8489" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.35.01-AM.png 795w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.35.01-AM-600x107.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.35.01-AM-300x54.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.35.01-AM-768x137.png 768w" sizes="auto, (max-width: 795px) 100vw, 795px" /></a></p>
<p>The only way that I know how to fix it is install the Python module <a href="https://pypi.org/project/upgrade-ensurepip/" target="_blank" rel="noopener noreferrer">upgrade_ensurepip</a>.  Here are the commands</p>
<ul>
<li>pip3 install upgrade_ensurepip</li>
<li>python3 -m upgrade_ensurepip</li>
</ul>
<p><a href="https://iotexpert.com/?attachment_id=8490" rel="attachment wp-att-8490"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.36.38-AM.png" alt="" width="814" height="178" class="alignnone size-full wp-image-8490" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.36.38-AM.png 814w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.36.38-AM-600x131.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.36.38-AM-300x66.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.36.38-AM-768x168.png 768w" sizes="auto, (max-width: 814px) 100vw, 814px" /></a></p>
<p>Now you when create a virtual environment you will end up with the correct PIP</p>
<p><a href="https://iotexpert.com/?attachment_id=8491" rel="attachment wp-att-8491"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.38.32-AM.png" alt="" width="768" height="130" class="alignnone size-full wp-image-8491" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.38.32-AM.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.38.32-AM-600x102.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-9.38.32-AM-300x51.png 300w" sizes="auto, (max-width: 768px) 100vw, 768px" /></a></p>
<p>If you look in the directory you will find that it adds the &#8220;pip&#8230; whl&#8221; director into the ensurepip directory</p>
<p><a href="https://iotexpert.com/?attachment_id=8500" rel="attachment wp-att-8500"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.33.05-PM.png" alt="" width="642" height="136" class="alignnone size-full wp-image-8500" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.33.05-PM.png 642w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.33.05-PM-600x127.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.33.05-PM-300x64.png 300w" sizes="auto, (max-width: 642px) 100vw, 642px" /></a></p>
<p>And it modifies the &#8220;_PIP_VERSION&#8221; in the ensurepip package __init.py</p>
<p><a href="https://iotexpert.com/?attachment_id=8501" rel="attachment wp-att-8501"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.34.32-PM.png" alt="" width="633" height="328" class="alignnone size-large wp-image-8501" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.34.32-PM.png 633w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.34.32-PM-600x311.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-21-at-1.34.32-PM-300x155.png 300w" sizes="auto, (max-width: 633px) 100vw, 633px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-ensure-pip-virtual-environments/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stupid Python Tricks: VSCODE c_cpp_properties.json for Linux Kernel Development</title>
		<link>https://iotexpert.com/stupid-python-tricks-vscode-c_cpp_properties-json-for-linux-kernel-development/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-vscode-c_cpp_properties-json-for-linux-kernel-development/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 01 Jun 2020 12:00:04 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9155</guid>

					<description><![CDATA[Summary This article shows you how to create a Python program that creates a Visual Studio Code c_cpp_properties.json which will enable intellisense when editing Linux Kernel Modules for Device Drivers. Story I am working my way through understanding, or at least trying to understand, Linux Kernel Modules &#8211; specifically Linux Device Drivers.  I have been [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article shows you how to create a Python program that creates a Visual Studio Code c_cpp_properties.json which will enable intellisense when editing Linux Kernel Modules for Device Drivers.</p>
<h1>Story</h1>
<p>I am working my way through understanding, or at least trying to understand, Linux Kernel Modules &#8211; specifically Linux Device Drivers.  I have been following through the book <a href="https://www.packtpub.com/networking-and-servers/linux-device-drivers-development" target="_blank" rel="noopener noreferrer">Linux Device Drivers Development by John Madieu</a></p>
<p><a href="https://iotexpert.com/?attachment_id=9166" rel="attachment wp-att-9166"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-827x1024.png" alt="" width="827" height="1024" class="alignnone size-large wp-image-9166" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-827x1024.png 827w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-600x743.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-242x300.png 242w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-768x951.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM-1240x1536.png 1240w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.33.12-AM.png 1626w" sizes="auto, (max-width: 827px) 100vw, 827px" /></a></p>
<p>There are a bunch of example codes in the book which you can &#8220;git&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">$ git remote -v
origin  https://github.com/PacktPublishing/Linux-Device-Drivers-Development (fetch)
origin  https://github.com/PacktPublishing/Linux-Device-Drivers-Development (push)
$</pre>
<p>When I started looking at the Chapter02 example I first opened it up in Visual Studio Code.  Where I was immediately given a warning about Visual Studio Code not knowing where to find &lt;linux/init.h&gt;</p>
<p><a href="https://iotexpert.com/?attachment_id=9163" rel="attachment wp-att-9163"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-1024x476.png" alt="" width="1024" height="476" class="alignnone size-large wp-image-9163" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-1024x476.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-600x279.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-300x140.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-768x357.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM-1536x714.png 1536w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.19.28-AM.png 1772w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And, when you try to click on the &#8220;KERN_INFO&#8221; symboled you get this nice message.</p>
<p><a href="https://iotexpert.com/?attachment_id=9165" rel="attachment wp-att-9165"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-1024x594.png" alt="" width="1024" height="594" class="alignnone size-large wp-image-9165" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-1024x594.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-600x348.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-300x174.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-768x445.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM-1536x890.png 1536w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.30.50-AM.png 1594w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In order to fix this you need to setup the &#8220;c_cpp_propertiese.json&#8221; to tell Visual Studio Code how to make intellisense work correctly. But, what is c_cpp_properties.json?</p>
<h1>C_CPP_PROPERTIES.JSON</h1>
<p>On the Visual Studio Code <a href="https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference" target="_blank" rel="noopener noreferrer">website</a> they give you a nice description of the schema.  Here is a screenshot from their website.</p>
<p><a href="https://iotexpert.com/?attachment_id=9168" rel="attachment wp-att-9168"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-1024x926.png" alt="" width="1024" height="926" class="alignnone size-large wp-image-9168" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-1024x926.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-600x543.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-300x271.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-768x695.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM-1536x1390.png 1536w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-6.47.41-AM.png 1594w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The &#8220;stuff&#8221; that seems to matter from this list is the &#8220;includePath&#8221; which tells intellisense the #includes and #defines.  OK.  How do I figure out where to find all of the files and paths for that?</p>
<h1>make &#8211;dry-run</h1>
<p>When you look at the Makefile it doesn&#8217;t appear to help very much.  I don&#8217;t know about you guys, but I actually dislike &#8220;Make&#8221; way more than I dislike Python :-).  What the hell is this Makefile telling you to do?</p>
<p>On line 3 the Makefile creates a variable called &#8220;KERNELDIR&#8221; and sets the value to the result of the shell command &#8220;uname -r&#8221; plus &#8220;/lib/modules&#8221; at the first and &#8220;/build&#8221; at the end.  If I run the command &#8220;uname -r&#8221; on my system I get &#8220;4.15.0-99-generic&#8221;</p>
<p>Then on line 9 it calls make with a &#8220;-C&#8221; option</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">obj-m := helloworld-params.o helloworld.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

all default: modules
install: modules_install

modules modules_install help clean:
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) $@</pre>
<p>Which tells Make to &#8220;change directory&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">$ make --help
Usage: make [options] [target] ...
Options:
  -b, -m                      Ignored for compatibility.
  -B, --always-make           Unconditionally make all targets.
  -C DIRECTORY, --directory=DIRECTORY
                              Change to DIRECTORY before doing anything</pre>
<p>OK when I look in that directory I see a bunch of stuff.  Most importantly a Makefile.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">$ cd /lib/modules/4.15.0-99-generic/build
$ ls
arch   crypto         firmware  init    Kconfig  Makefile        net      security  ubuntu
block  Documentation  fs        ipc     kernel   mm              samples  sound     usr
certs  drivers        include   Kbuild  lib      Module.symvers  scripts  tools     virt
$</pre>
<p>When I look in that Makefile I start to sweat because it is pages and pages of Make incantations.  Now what?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c"># SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 15
SUBLEVEL = 18
EXTRAVERSION =
NAME = Fearless Coyote

# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
# More info can be located in ./README
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.

# That's our default target when none is given on the command line
PHONY := _all
_all:

# o Do not use make's built-in rules and variables
#   (this increases performance and avoids hard-to-debug behaviour);
# o Look for make include files relative to root of kernel src
MAKEFLAGS += -rR --include-dir=$(CURDIR)

# Avoid funny character set dependencies
unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC</pre>
<p>All hope is not lost.  I turns out that you can have make do a &#8220;dry run&#8221; which will tell you what are the commands that it is going to execute.  Here is part of the output for the Chapter02 example.  Unfortunately, that is some ugly ugly stuff right there.  What am I going to do with that?</p>
<p><a href="https://iotexpert.com/?attachment_id=9171" rel="attachment wp-att-9171"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-1024x851.png" alt="" width="1024" height="851" class="alignnone size-large wp-image-9171" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-1024x851.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-600x499.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-300x249.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-768x638.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-1536x1277.png 1536w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-7.04.04-AM-2048x1702.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The answer is that I am going to do something evil &#8211; really evil.  Which you already knew since this is an article about Python and Make you knew coming in that it was going to be evil.  If you notice above there is a line that contains &#8220;&#8230;. CC [M] &#8230;&#8221;  That is one of the lines where the compiler is actually being called.  And you might notice that on the command line there are an absolute boatload of &#8220;-I&#8221; which is the gcc compiler option to add an include path.</p>
<h1>The Python Program</h1>
<p>What we are going to do here is write a Python program that does this:</p>
<ol>
<li>Runs make &#8211;dry-run</li>
<li>Looks for lines with &#8220;CC&#8221;</li>
<li>Splits the line up at the spaces</li>
<li>Searches for &#8220;-I&#8221;s and adds them to a list of include paths</li>
<li>Searches for &#8220;-D&#8221;s and adds them to a list of #defines</li>
<li>Spits the whole mess out into a json file with the right format (from the Microsoft website)</li>
</ol>
<p>I completely understand that this program is far far from a robust production worthy program.  But, as it is written in Python, you should not be too surprised.</p>
<p>To start this program off I am going to use several Python libraries</p>
<ol>
<li>JSON</li>
<li>OS (Operation System so that I can execute make and uname)</li>
<li>RE (Regular expressions)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">import json
import os
import re</pre>
<p>The next thing to do is declare some global variables.  The first three are Python Sets to hold one copy each of the includes, defines, other options and double dash options.  The Python Set class allows you to add objects to a set that are guaranteed to be unique (if you attempt to add a duplicate it will be dropped)</p>
<pre class="inline-margin:8 EnlighterJSRAW" data-enlighter-language="c" ">includePath = set()
defines = set()
otherOptions = set()
doubleDash = set()
outputJson = dict()</pre>
<p>The next block of code is a function that:</p>
<ol>
<li>Takes as an input a line from the makefile output</li>
<li>Splits the line up into tokens by using white space.  The split function take a string and divides it into a list.</li>
<li>Then I iterate over the list (line 27)</li>
<li>I use the Python string slicer syntax &#8211; the [] to grab part of the string.  The syntax [:2] means give me the first two characters of the string</li>
<li>I use 4 if statements to look to see if it is a &#8220;-I&#8221;, &#8220;-D&#8221;, &#8220;&#8211;&#8221; or &#8220;-&#8221; in which case I add it to the appropriate global variable.</li>
</ol>
<p>Obviously this method is deeply hardcoded the output of this version of make on this operating system&#8230; but if you are developing Linux Device Drivers you are probably running Linux&#8230; so hopefully it is OK.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#
# Function: processLine
#
# Take a line from the make output
# split the line into a list by using whitespace
# search the list for tokens of
# -I (gcc include)
# -D (gcc #define)
# -- (I actually ignore these but I was curious what they all were)
# - (other - options which I keep track of ... but then ignore)

def processLine(lineData):
    linelist = lineData.split()
    for i in linelist:
        if(i[:2] == "-I"):
            if(i[2:2] == '/'):
                includePath.add(i[2:])
            else:
                includePath.add(f"/usr/src/linux-headers-{kernelVersion}/{i[2:]}")
        elif (i[:2] == "-D"):
            defines.add(i[2:])
        elif (i[:2] == "--"):
            doubleDash.add(i)
        elif (i[:1] == '-'):
            otherOptions.add(i)</pre>
<p>The next block of code runs two Linux commands (uname and make &#8211;dryrun)  and puts the output into a string.  On line 51 I split the make output into a list of strings one per line.</p>
<pre class="start-line:42 EnlighterJSRAW" data-enlighter-language="c""># figure out which version of the kernel we are using
stream = os.popen('uname -r')
kernelVersion = stream.read()
# get rid of the \n from the uname command
kernelVersion = kernelVersion[:-1]

# run make to find #defines and -I includes
stream = os.popen('make --dry-run')
outstring = stream.read()
lines = outstring.split('\n')</pre>
<p>In the next block of code I iterate through the makefile output looking for lines that have the &#8220;CC&#8221; in them.  I try to protect myself by requiring that the CC have white space before and after.  Notice one line 56 that I use a regular expression to look for the &#8220;CC&#8221;.</p>
<pre class="start-line:54 EnlighterJSRAW" data-enlighter-language="c" ">for i in lines:
    # look for a line with " CC "... this is a super ghetto method
    val = re.compile(r'\s+CC\s+').search(i)
    if val:
        processLine(i)</pre>
<p>The last block of code actually create the JSON and writes it to the output file c_cpp_properties.json.</p>
<pre class="start-line:61 EnlighterJSRAW" data-enlighter-language="c" "># Create the JSON 
outputJson["configurations"] = []

configDict = {"name" : "Linux"}
configDict["includePath"] = list(includePath)
configDict["defines"] = list(defines)
configDict["intelliSenseMode"] = "gcc-x64"
configDict["compilerPath"]= "/usr/bin/gcc"
configDict["cStandard"]= "c11"
configDict["cppStandard"] = "c++17"

outputJson["configurations"].append(configDict)
outputJson["version"] = 4

# Convert the Dictonary to a string of JSON
jsonMsg = json.dumps(outputJson)

# Save the JSON to the files
outF = open("c_cpp_properties.json", "w")
outF.write(jsonMsg)
outF.close()</pre>
<p>Thats it.  You can then:</p>
<ol>
<li>Run the program</li>
<li>move the file c_cpp_properties.json in the .vscode directory</li>
</ol>
<p>And now everything is more better <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" />  When I hover over the &#8220;KERN_INFO&#8221; I find that it is #define to &#8220;6&#8221;</p>
<p><a href="https://iotexpert.com/?attachment_id=9173" rel="attachment wp-att-9173"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM-1024x630.png" alt="" width="1024" height="630" class="alignnone size-large wp-image-9173" srcset="https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM-1024x630.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM-600x369.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM-300x184.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM-768x472.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/Screen-Shot-2020-05-16-at-8.26.56-AM.png 1262w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I will say that I am not a fan of having the compiler automatically concatenate two strings, but given that this article is written about a Python program who am I to judge?</p>
<h1>What could go wrong?</h1>
<p>There are quite a few things that could go wrong with this program.</p>
<ol>
<li>The make output format could change</li>
<li>There could be multiple compiles that have conflicting options</li>
<li>I could spontaneously combust from writing Python programs</li>
<li>The hardcoded cVersion, cStandard, compilerPath, intelliSenseMode could change enough to cause problems</li>
</ol>
<p>All of these things could be fixed, or at least somewhat mitigated.  But I already spent more time down this rabbit hole that I really wanted.</p>
<h1>The Final Program</h1>
<pre class="EnlighterJSRAW" data-enlighter-language="c"># This program runs "make --dry-run" then processes the output to create a visual studio code
# c_cpp_properties.json file

import json
import os
import re

includePath = set()
defines = set()
otherOptions = set()
doubleDash = set()
outputJson = dict()

# Take a line from the make output
# split the line into a list by using whitespace
# search the list for tokens of
# -I (gcc include)
# -D (gcc #define)
# -- (I actually ignore these but I was curious what they all were)
# - (other - options which I keep track of ... but then ignore)

def processLine(lineData):
    linelist = lineData.split()
    for i in linelist:
        if(i[:2] == "-I"):
            if(i[2:2] == '/'):
                includePath.add(i[2:])
            else:
                includePath.add(f"/usr/src/linux-headers-{kernelVersion}/{i[2:]}")
        elif (i[:2] == "-D"):
            defines.add(i[2:])
        elif (i[:2] == "--"):
            doubleDash.add(i)
        elif (i[:1] == '-'):
            otherOptions.add(i)

# figure out which version of the kernel we are using
stream = os.popen('uname -r')
kernelVersion = stream.read()
# get rid of the \n from the uname command
kernelVersion = kernelVersion[:-1]

# run make to find #defines and -I includes
stream = os.popen('make --dry-run')
outstring = stream.read()
lines = outstring.split('\n')


for i in lines:
    # look for a line with " CC "... this is a super ghetto method
    val = re.compile(r'\s+CC\s+').search(i)
    if val:
        processLine(i)


# Create the JSON 
outputJson["configurations"] = []

configDict = {"name" : "Linux"}
configDict["includePath"] = list(includePath)
configDict["defines"] = list(defines)
configDict["intelliSenseMode"] = "gcc-x64"
configDict["compilerPath"]= "/usr/bin/gcc"
configDict["cStandard"]= "c11"
configDict["cppStandard"] = "c++17"

outputJson["configurations"].append(configDict)
outputJson["version"] = 4

# Convert the Dictonary to a string of JSON
jsonMsg = json.dumps(outputJson)

# Save the JSON to the files
outF = open("c_cpp_properties.json", "w")
outF.write(jsonMsg)
outF.close()

</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-vscode-c_cpp_properties-json-for-linux-kernel-development/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Stupid Python Tricks: Install MBED-CLI on macOS</title>
		<link>https://iotexpert.com/stupid-python-tricks-install-mbed-cli-on-macos/</link>
					<comments>https://iotexpert.com/stupid-python-tricks-install-mbed-cli-on-macos/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 02 Mar 2020 13:00:06 +0000</pubDate>
				<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=8543</guid>

					<description><![CDATA[Summary This article describes a good set of steps to install the ARM MBED-CLI onto your Mac into a Python Virtual Environment.  You COULD make MBED-CLI work on your Mac a bunch of other/different ways, but, what I describe in this article is the best way.  You could follow the specific ARM instructions here. The big steps [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article describes a good set of steps to install the ARM MBED-CLI onto your Mac into a Python Virtual Environment.  You COULD make MBED-CLI work on your Mac a bunch of other/different ways, but, what I describe in this article is the best way.  You could follow the specific ARM instructions <a href="https://os.mbed.com/docs/mbed-os/v5.15/tools/manual-installation.html" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>The big steps are:</p>
<ol>
<li>Install Homebrew</li>
<li>Install Python3</li>
<li>Create a Virtual Python Environment</li>
<li>Use PIP to Install MBED-CLI</li>
<li>Download the GCC Compiler</li>
<li>Configure the Compiler</li>
<li>Test</li>
</ol>
<h1>macOS Homebrew &amp; Python3</h1>
<p>You need to be able to run Python, and in my opinion, specifically Python 3.  There are problems with doing this, first most of the macOS versions do not have Python 3 built in (and the Python 2 is old).  But, on macOS Catalina, you could use the macOS built-in Python3 and install MBED-CLI into the system libraries.  But, I believe that you should never make changes to the macOS system which could collide with its normal functioning.  I think that the easiest way to get a standalone Python onto your computer is to use &#8220;<a href="https://brew.sh" target="_blank" rel="noopener noreferrer">Homebrew</a>&#8221; package manager.   Homebrew will enable you to easily install Python3 (and a bunch of other stuff) into /usr/local/bin.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-16-36-am/" rel="attachment wp-att-8600"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM-1024x498.png" alt="" width="1024" height="498" class="alignnone size-large wp-image-8600" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM-1024x498.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM-600x292.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM-300x146.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM-768x373.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.16.36-AM.png 1267w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>To install Homebrew run:</p>
<ul>
<li>/usr/bin/ruby -e &#8220;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&#8221;</li>
</ul>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/thumbnail_screen-shot-2020-02-28-at-10-44-05-am/" rel="attachment wp-att-8616"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM-1024x557.png" alt="" width="1024" height="557" class="alignnone size-large wp-image-8616" srcset="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM-1024x557.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM-600x326.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM-300x163.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM-768x418.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.05-AM.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And after a bunch of streaming console messages, it finishes:</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/thumbnail_screen-shot-2020-02-28-at-10-43-46-am/" rel="attachment wp-att-8617"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM-1024x867.png" alt="" width="1024" height="867" class="alignnone size-large wp-image-8617" srcset="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM-1024x867.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM-600x508.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM-300x254.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM-768x650.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.43.46-AM.png 1134w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now you can use Homebrew to install python3 into /usr/local/bin by running:</p>
<ul>
<li>brew install python3</li>
</ul>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/thumbnail_screen-shot-2020-02-28-at-10-44-57-am/" rel="attachment wp-att-8615"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM-1024x865.png" alt="" width="1024" height="865" class="alignnone size-large wp-image-8615" srcset="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM-1024x865.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM-600x507.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM-300x253.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM-768x649.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.44.57-AM.png 1138w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And it puts out a bunch of stuff on the console&#8230; finally ending like this:<a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/thumbnail_screen-shot-2020-02-28-at-10-45-07-am/" rel="attachment wp-att-8614"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM-1024x450.png" alt="" width="1024" height="450" class="alignnone size-large wp-image-8614" srcset="https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM-1024x450.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM-600x264.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM-300x132.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM-768x338.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/thumbnail_Screen-Shot-2020-02-28-at-10.45.07-AM.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now you should be able to &#8220;which python3&#8221; and see that python 3.7.6 is installed.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-11-30-43-am/" rel="attachment wp-att-8621"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.30.43-AM.png" alt="" width="486" height="211" class="alignnone size-full wp-image-8621" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.30.43-AM.png 486w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.30.43-AM-300x130.png 300w" sizes="auto, (max-width: 486px) 100vw, 486px" /></a></p>
<h1>Create a Virtual Environment and Install mbed-cli</h1>
<p>I always use a virtual environment when I run python to insure that all of the packages I install are together.  Run:</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Command</th>
<th >Comment</th>
</tr>
</thead>
<tbody>
<tr><td >mkdir mbed-cli-example</td>
<td >Create a directory to hold the virtual environments</td>
</tr>

<tr><td >cd mbed-cli-example</td>
<td ></td>
</tr>

<tr><td >python3 -m venv venv</td>
<td >Create the virtual environment in the directory called "venv"</td>
</tr>

<tr><td >source venv/bin/activate</td>
<td >Activate the virtual environment</td>
</tr>

<tr><td >pip install mbed-cli</td>
<td >Download the Mbed-cli package and install it into the virtual environment</td>
</tr>
</tbody></table></div>
<p>Here is what is looks like:</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-21-57-am/" rel="attachment wp-att-8602"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM-1024x934.png" alt="" width="1024" height="934" class="alignnone size-large wp-image-8602" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM-1024x934.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM-600x547.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM-300x274.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM-768x700.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.21.57-AM.png 1234w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Once that is done you can run &#8220;which mbed&#8221; where you will find that the MBED-CLI is in your virtual environment path.  And when you run &#8220;mbed&#8221; you should see all of the options.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-23-01-am/" rel="attachment wp-att-8603"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.23.01-AM.png" alt="" width="892" height="857" class="alignnone size-full wp-image-8603" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.23.01-AM.png 892w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.23.01-AM-600x576.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.23.01-AM-300x288.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.23.01-AM-768x738.png 768w" sizes="auto, (max-width: 892px) 100vw, 892px" /></a></p>
<h1>Download the GCC Compiler</h1>
<p>In order to actually do something with the MBED-CLI you also need to have an ARM compiler toolchain installed e.g. GCC.  The easiest (best?) way to get this done is download it from this the ARM website <a href="https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-04-34-am/" rel="attachment wp-att-8597"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.04.34-AM.png" alt="" width="796" height="1024" class="alignnone size-large wp-image-8597" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.04.34-AM.png 796w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.04.34-AM-600x772.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.04.34-AM-233x300.png 233w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.04.34-AM-768x988.png 768w" sizes="auto, (max-width: 796px) 100vw, 796px" /></a></p>
<p>After you download the Mac OS X 64-bit Tarball file you will end up with a &#8220;&#8230;tar.bz2&#8221; file in your Downloads directory.  When you double click the file, the finder will unzip and untar the file into a folder with all of the stuff you need for the Mac.</p>
<h1><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-10-18-am/" rel="attachment wp-att-8598"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.10.18-AM.png" alt="" width="843" height="63" class="alignnone size-full wp-image-8598" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.10.18-AM.png 843w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.10.18-AM-600x45.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.10.18-AM-300x22.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.10.18-AM-768x57.png 768w" sizes="auto, (max-width: 843px) 100vw, 843px" /></a></h1>
<p>I have a directory on my Mac called ~/proj where I hold all of my &#8220;project&#8221; stuff.  So after downloading and untaring the file, I move it to my project directory with &#8220;mv ~/download/gcc-arm-none-eabi-9-2019-q4-major ~/proj&#8221;</p>
<h1>Configure the Compiler</h1>
<p>The final step is to tell the MBED-CLI where your toolchain is located.  There are a bunch of slightly different variants for how to do this.  BUT I think that the best is to change the mbed global configuration by running:</p>
<ul>
<li>mbed config &#8211;global GCC_ARM_PATH ~/proj/gcc-arm-none-eabi-9-2019-q4-major/bin</li>
</ul>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-28-13-am/" rel="attachment wp-att-8604"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.28.13-AM.png" alt="" width="886" height="188" class="alignnone size-full wp-image-8604" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.28.13-AM.png 886w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.28.13-AM-600x127.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.28.13-AM-300x64.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.28.13-AM-768x163.png 768w" sizes="auto, (max-width: 886px) 100vw, 886px" /></a></p>
<p>The &#8220;&#8211;global&#8221; flag will store that configuration variable in the file ~/.mbed/.mbed (notice a directory called .mbed and a file called .mbed)</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-11-51-28-am/" rel="attachment wp-att-8624"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.51.28-AM.png" alt="" width="630" height="112" class="alignnone size-full wp-image-8624" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.51.28-AM.png 630w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.51.28-AM-600x107.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.51.28-AM-300x53.png 300w" sizes="auto, (max-width: 630px) 100vw, 630px" /></a></p>
<p>It took me a while to figure out which directory you should put in the path because there are multiple bin directories in the &#8220;gcc-arm&#8230;&#8221; directory.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-11-49-09-am/" rel="attachment wp-att-8623"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.49.09-AM.png" alt="" width="571" height="255" class="alignnone size-full wp-image-8623" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.49.09-AM.png 571w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-11.49.09-AM-300x134.png 300w" sizes="auto, (max-width: 571px) 100vw, 571px" /></a></p>
<p>If you want to use one of the other toolchains mbed has configuration variables for those as well:</p>
<h1><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-03-31-am/" rel="attachment wp-att-8596"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM-1024x486.png" alt="" width="1024" height="486" class="alignnone size-large wp-image-8596" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM-1024x486.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM-600x285.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM-300x142.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM-768x365.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.03.31-AM.png 1118w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></h1>
<p>You can also configure these paths with environment variables, but I dont like that.</p>
<h1>macOS Gatekeeper</h1>
<p>On macOS there is a security infrastructure called <a href="https://en.wikipedia.org/wiki/Gatekeeper_(macOS)" target="_blank" rel="noopener noreferrer">Gatekeeper</a> that will prevent you from running applications that Gatekeeper doesn&#8217;t know about.  This includes the GCC toolchain (which you just downloaded).  To make it so that you can run the toolchain there are a couple of things you COULD do, but I think that the best thing to do is tell Gatekeeper that the Terminal program is exempt from the Gatekeeper rules.</p>
<p>To do this type the following command into a terminal: &#8220;spctl developer-mode enable-terminal&#8221;</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-8-51-40-am/" rel="attachment wp-att-8591"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.51.40-AM.png" alt="" width="742" height="463" class="alignnone size-large wp-image-8591" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.51.40-AM.png 742w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.51.40-AM-600x374.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.51.40-AM-300x187.png 300w" sizes="auto, (max-width: 742px) 100vw, 742px" /></a></p>
<p>Then go to the System Preferences &#8211;&gt; Security &amp; Privacy &#8211;&gt; Developer Tools and check that the &#8220;Terminal&#8221; is exempt from the Gatekeeper Rules.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-8-49-45-am/" rel="attachment wp-att-8590"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.49.45-AM.png" alt="" width="662" height="573" class="alignnone size-full wp-image-8590" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.49.45-AM.png 662w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.49.45-AM-600x519.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-8.49.45-AM-300x260.png 300w" sizes="auto, (max-width: 662px) 100vw, 662px" /></a></p>
<p>You can read more <a href="https://github.com/microsoft/azure-pipelines-agent/issues/2457" target="_blank" rel="noopener noreferrer">here</a> and <a href="http://www.theinstructional.com/guides/gatekeeper-fundamentals-part-2" target="_blank" rel="noopener noreferrer">here</a>.</p>
<h1>Test</h1>
<p>To test everything you have done, you should:</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Command</th>
<th >Comment</th>
</tr>
</thead>
<tbody>
<tr><td >mbed import mbed-os-example-blinky</td>
<td >Load the example project.  Notice that mbed also will install the Python requirements into your virtual environment.  It does this by running "pip install -r mbed-os/requirements.txt"</td>
</tr>

<tr><td >cd mbed-os-example-blinky</td>
<td ></td>
</tr>

<tr><td >mbed config target CY8CKIT_062S2_43012</td>
<td >Setup the target (in my case the really cool P6 43012 devout)</td>
</tr>

<tr><td >mbed config toolchain GCC_ARM</td>
<td >Set the toolchain to the one we setup in the previous step</td>
</tr>

<tr><td >mbed detect</td>
<td >See if mbed can detect the development kit&#8230; it can</td>
</tr>
</tbody></table></div>
<p>Here is what it looks like:</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-35-14-am/" rel="attachment wp-att-8606"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM-1024x439.png" alt="" width="1024" height="439" class="alignnone size-large wp-image-8606" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM-1024x439.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM-600x257.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM-300x129.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM-768x329.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.35.14-AM.png 1073w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>You can now run the compiler (with the -f option to program).  It should start up and barf out the compile messages.</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-38-38-am/" rel="attachment wp-att-8607"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM-1024x229.png" alt="" width="1024" height="229" class="alignnone size-large wp-image-8607" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM-1024x229.png 1024w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM-600x134.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM-300x67.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM-768x172.png 768w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.38-AM.png 1071w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a> <a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-38-56-am/" rel="attachment wp-att-8608"></a></p>
<p>Eventually it ends&#8230; then programs the development kit</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-9-38-56-am/" rel="attachment wp-att-8608"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.56-AM.png" alt="" width="789" height="523" class="alignnone size-large wp-image-8608" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.56-AM.png 789w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.56-AM-600x398.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.56-AM-300x199.png 300w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-9.38.56-AM-768x509.png 768w" sizes="auto, (max-width: 789px) 100vw, 789px" /></a></p>
<p>The last thing to do is turn off the virtual environment</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-10-56-54-am/" rel="attachment wp-att-8618"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.56.54-AM.png" alt="" width="735" height="69" class="alignnone size-full wp-image-8618" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.56.54-AM.png 735w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.56.54-AM-600x56.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.56.54-AM-300x28.png 300w" sizes="auto, (max-width: 735px) 100vw, 735px" /></a></p>
<p>Which can later be turned back on with &#8220;source venv/bin/activate&#8221;</p>
<p><a href="https://iotexpert.com/2020/03/02/stupid-python-tricks-install-mbed-cli-on-macos/screen-shot-2020-02-28-at-10-58-25-am/" rel="attachment wp-att-8619"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.58.25-AM.png" alt="" width="676" height="192" class="alignnone size-full wp-image-8619" srcset="https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.58.25-AM.png 676w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.58.25-AM-600x170.png 600w, https://iotexpert.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-28-at-10.58.25-AM-300x85.png 300w" sizes="auto, (max-width: 676px) 100vw, 676px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/stupid-python-tricks-install-mbed-cli-on-macos/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
