<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>BEC Systems</title>
    <subtitle>I help small teams build connected products — capable teams that need to ship real hardware, and keep shipping. Consulting, open-source tools, and writing on platform thinking for embedded Linux and IoT.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bec-systems.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bec-systems.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-10-28T00:00:00+00:00</updated>
    <id>https://bec-systems.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Human Friendly Industrial Device IDs</title>
        <published>2025-10-28T00:00:00+00:00</published>
        <updated>2025-10-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2563/human-friendly-industrial-device-ids/"/>
        <id>https://bec-systems.com/2563/human-friendly-industrial-device-ids/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2563/human-friendly-industrial-device-ids/">&lt;p&gt;Do you deploy 10’s to 1000’s of devices and need to quickly identify them in the field for configuration, maintenance, or troubleshooting? This article explores how this can be made much easier by using device IDs that are easy for humans to process.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;05&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:207px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In a &lt;a href=&quot;&#x2F;2417&#x2F;survey-of-device-id-mechanisms&#x2F;&quot;&gt;previous article (A Survey of device ID mechanisms)&lt;&#x2F;a&gt;, we explored some of the commonly used options (MAC addresses, UUID, 2D barcodes, etc.). However, most of these are optimized for consumer devices and scenarios where machines process the IDs.&lt;&#x2F;p&gt;
&lt;p&gt;Why are human-friendly IDs important? Consider a few scenarios:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;8 identical temperature sensors are located at various places on a piece of equipment, and we need to identify the location of each one.&lt;&#x2F;li&gt;
&lt;li&gt;3 IO modules are attached to a gateway, and we need to select which module a sensor is connected to when creating a virtual component in a dashboard.&lt;&#x2F;li&gt;
&lt;li&gt;One of the above 3 IO modules in a crowded control panel has failed, and we need to replace it. How do we identify it?&lt;&#x2F;li&gt;
&lt;li&gt;A user calls with a technical support problem on a piece of equipment, and we want to quickly look up the details on the hardware they have (model, version, etc).&lt;&#x2F;li&gt;
&lt;li&gt;We need to list and verify the device serial numbers on a packing list for a shipment to a customer.&lt;&#x2F;li&gt;
&lt;li&gt;Devices are provisioned and configured in the shop for several sites, and during installation, we need to make sure we install the right device in the right location.&lt;&#x2F;li&gt;
&lt;li&gt;A device’s mDNS name defaults to the device’s serial number. Once a device is attached to a network, the user needs to access the Web UI using the address: &lt;code&gt;http:&#x2F;&#x2F;&amp;lt;device id&amp;gt;.local&lt;&#x2F;code&gt;. It is helpful if the ID is simple enough for a user to read from a label and easily type into a browser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the real world, especially the industrial world, there are many cases where humans need to interact with equipment beyond the initial provisioning.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-15.png&quot; alt=&quot;&quot; style=&quot;width:433px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;the-problem-with-only-qr-codes&quot;&gt;The problem with (only) QR Codes&lt;&#x2F;h2&gt;
&lt;p&gt;QR Codes are increasingly being used to identify devices. We buy a new device, scan the QR code with an app on our phone, and the device gets added to the system – pretty slick! QR Codes are optimized for provisioning, with data flowing in one direction – from the QR code to the system. However, using the QR code to identify a device that is already deployed in the field is more challenging. We need to be able to look at multiple devices in the field and quickly identify them. Also, consider the scenario where you are on the phone supporting a customer – large QR codes are not transmitted over the phone very well. QR codes alone do not solve every problem.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-16.png&quot; alt=&quot;&quot; style=&quot;width:292px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;What works well in the consumer space is not always appropriate for the industrial space. While there are many consumer technologies we can leverage, what Google, Apple, and Amazon are doing is not automatically the best solution for industrial applications. It may be possible to identify a device using a QR code using a complex standard like Matter, but do we have the development resources to make this happen? Do we need the complex security and privacy features in an industrial context? Is there a simpler&#x2F;better solution?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-makes-an-id-easy-for-humans-to-process&quot;&gt;What makes an ID easy for humans to process?&lt;&#x2F;h2&gt;
&lt;p&gt;Many MFA (multi-factor authentication), one-time passwords, and authenticator apps use codes that are composed of 6 digits split into two chunks:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-17.png&quot; alt=&quot;&quot; style=&quot;width:178px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;From experience, we know these numbers are easy to remember and type into a form. Even on our phones, it is often more work to copy and paste than simply look and remember. Why is this? Human short-term memory can typically hold about 7 items at once (plus or minus 2). Chunking these numbers further reduces cognitive load for users. For example, “283-178” is easier to remember than “283178”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;human-friendly-ids-hfid&quot;&gt;Human-friendly IDs (HFID)&lt;&#x2F;h2&gt;
&lt;p&gt;If we start with the format used by authorization codes (&lt;code&gt;XXX-XXX&lt;&#x2F;code&gt;), which is six digits, this gives us one million possibilities (10^6). That is a lot of devices, and may be adequate for some applications.&lt;&#x2F;p&gt;
&lt;p&gt;If we expand this ID to also include capital letters (example: &lt;code&gt;N8H-9MJ&lt;&#x2F;code&gt;), then possible combinations are over 2 billion (36^6).&lt;&#x2F;p&gt;
&lt;p&gt;If we eliminate letters and numbers that are easily confused (&lt;code&gt;0&lt;&#x2F;code&gt;, &lt;code&gt;O&lt;&#x2F;code&gt;, &lt;code&gt;1&lt;&#x2F;code&gt;, &lt;code&gt;I&lt;&#x2F;code&gt;, &lt;code&gt;2&lt;&#x2F;code&gt;, and &lt;code&gt;Z&lt;&#x2F;code&gt;), then reducing the base from 36 to 30 characters (30^6) gives us ~729 million combinations. Randomizing the characters in the ID also helps ensure that the IDs are visually unique and not easily confused with IDs on neighboring devices. We might also want to require a letter and a number in each 3-character chunk to make the ID easily recognizable as an HFID, which would reduce the number of combinations to ~340 million.&lt;&#x2F;p&gt;
&lt;p&gt;340 million is far more than most organizations in the industrial space will ever produce. If there is ever a need for more IDs, then the number of characters could be expanded with a minor loss in usability (example: PU89-V6M2), which gives us 656 billion combinations (30^8).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;managing-device-ids-hfid-org&quot;&gt;Managing Device IDs (hfid.org)&lt;&#x2F;h2&gt;
&lt;p&gt;This scheme does require a central authority to create these IDs – ideally, an API that various manufacturing processes (including subcontractors) can interface with and pull new IDs in real-time. The real value occurs when multiple companies can use the same ID registry, and thus devices from different manufacturers can interoperate. For this, it would be beneficial if there were a vendor-neutral organization that generated these IDs on demand. We created a prototype of a system to do this.&lt;&#x2F;p&gt;
&lt;p&gt;🌐 &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;app.hfid.org&quot;&gt;&lt;strong&gt;https:&#x2F;&#x2F;app.hfid.org&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once your account is approved, you can generate new HFIDs via the website or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;app.hfid.org&#x2F;documentation&quot;&gt;API&lt;&#x2F;a&gt;. Check it out …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-not-both&quot;&gt;Why not both?&lt;&#x2F;h2&gt;
&lt;p&gt;Why not both an HFID and a small QR code containing the HFID on your device? Then it is easy for both humans and machines to process the ID.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;05&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:217px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Human-friendly device IDs are a way to uniquely identify a large number of devices, yet make it easy for humans to quickly and accurately identify devices in the field. Similar to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;tlsl01uxUfE&quot;&gt;Internal Part Numbers designed for humans&lt;&#x2F;a&gt;, systems designed to work well with humans are key to reducing mistakes and improving efficiency.&lt;&#x2F;p&gt;
&lt;p&gt;Even if you are using devices&#x2F;sensors&#x2F;equipment manufactured by others that already have an ID, adding an HFID to any device you deploy allows you to identify it with less effort.&lt;&#x2F;p&gt;
&lt;p&gt;The human eye and brain are remarkable instruments. Implementing IDs that are easy for humans to process has countless benefits as you manufacture, track, deploy, maintain, and service your products, devices, and equipment. Quickly identifying a device is the first step to doing anything with it.&lt;&#x2F;p&gt;
&lt;p&gt;Don’t just use an ID, use an HFID.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Survey of device ID mechanisms</title>
        <published>2025-04-15T00:00:00+00:00</published>
        <updated>2025-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2417/survey-of-device-id-mechanisms/"/>
        <id>https://bec-systems.com/2417/survey-of-device-id-mechanisms/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2417/survey-of-device-id-mechanisms/">&lt;p&gt;Are you implementing an IoT system that requires you to identify many connected devices? This post reviews different types of IDs and provides some technical details to help you decide if any of these are appropriate for your application.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-14.png&quot; alt=&quot;&quot; style=&quot;width:343px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Note: some of the below information was generated by Perplexity and may not be 100% accurate. The goal of this article is to get a sense of all the different types of IDs in use. To implement anything, use the official documentation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uuids&quot;&gt;UUIDs&lt;&#x2F;h2&gt;
&lt;p&gt;UUIDs (Universally Unique Identifiers) are often used in distributed software systems where multiple distributed systems create objects that must be uniquely identified. UUIDs are typically 128-bit numbers represented in a 36-character format that might look like: d50ae174-b65f-4ab9-b938-5f99b67ac50b. Base64 encoded UUIDs can be as short as 22 characters and look like: 1QrhdLZfSrm5OF-ZtnrFCw. UUIDs are typically constructed using the time and the MAC address of the device generating the UUID.&lt;&#x2F;p&gt;
&lt;p&gt;These IDs are attractive because no central organization or database is required to prevent conflicts - they can be created anywhere at will with a statistically insignificant possibility that there will ever be a collision. However, these IDs are large and best processed by machines, not humans.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mac-address-eui-48&quot;&gt;MAC Address&#x2F;EUI-48&lt;&#x2F;h2&gt;
&lt;p&gt;Network devices use a MAC (Media Access Control) address, also called (EUI-48), to uniquely identify a device on a network. These are 48-bit numbers typically displayed as 12 hexadecimal digits and grouped into 6 pairs (&lt;code&gt;00:1A:2B:3C:4D:5E&lt;&#x2F;code&gt;). The first half of the MAC address is called the OUI (Organizationally Unique Identifier). &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;standards.ieee.org&#x2F;products-programs&#x2F;regauth&#x2F;&quot;&gt;IEEE is the registration authority&lt;&#x2F;a&gt; for MAC address blocks. You can purchase 4K, 1M, and 16M size blocks; the cost ranges from $1,080 to $3,680 at the time of writing.&lt;&#x2F;p&gt;
&lt;p&gt;You can also purchase EEPROM integrated circuits, like the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;en-us&#x2F;product&#x2F;24AA02E48&quot;&gt;24AA02E48&lt;&#x2F;a&gt; from Microchip, that have a EUI-48 number already programmed into it. This is a nice option for lower volume products where you don’t want to mess around with managing the EUI-48 numbers.&lt;&#x2F;p&gt;
&lt;p&gt;One advantage of using a MAC address is that it may already be programmed into the device you are using, so it does not require any extra effort to allocate and program the ID.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bluetooth-low-energy-ble&quot;&gt;Bluetooth Low Energy (BLE)&lt;&#x2F;h2&gt;
&lt;p&gt;BLE uses “MAC” (EUI-48) hardware addresses from the same pool as Ethernet. Additionally, the following IDs are used:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Identifier Type&lt;&#x2F;th&gt;&lt;th&gt;Size&lt;&#x2F;th&gt;&lt;th&gt;Purpose&#x2F;Usage&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Bluetooth Address (EUI-48)&lt;&#x2F;td&gt;&lt;td&gt;48 bits&lt;&#x2F;td&gt;&lt;td&gt;Device-level unique ID (public or random)&lt;&#x2F;td&gt;&lt;td&gt;12:34:56:78:9A:BC&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;UUID (16&#x2F;32&#x2F;128-bit)&lt;&#x2F;td&gt;&lt;td&gt;16&#x2F;32&#x2F;128b&lt;&#x2F;td&gt;&lt;td&gt;Service&#x2F;characteristic identification&lt;&#x2F;td&gt;&lt;td&gt;0x180D, 12345678-...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Company Identifier&lt;&#x2F;td&gt;&lt;td&gt;16 bits&lt;&#x2F;td&gt;&lt;td&gt;Manufacturer&#x2F;vendor identification&lt;&#x2F;td&gt;&lt;td&gt;0x004C (Apple)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;System ID (Device Info)&lt;&#x2F;td&gt;&lt;td&gt;64 bits&lt;&#x2F;td&gt;&lt;td&gt;Encodes device&#x27;s MAC address (optional)&lt;&#x2F;td&gt;&lt;td&gt;(varies)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Local Name&lt;&#x2F;td&gt;&lt;td&gt;Variable&lt;&#x2F;td&gt;&lt;td&gt;Human-readable device name&lt;&#x2F;td&gt;&lt;td&gt;&quot;Charge HR&quot;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Appearance&#x2F;Class Codes&lt;&#x2F;td&gt;&lt;td&gt;16 bits&lt;&#x2F;td&gt;&lt;td&gt;Device type&#x2F;classification&lt;&#x2F;td&gt;&lt;td&gt;0x0340 (Heart Rate Sensor)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;bluetooth-mesh&quot;&gt;Bluetooth Mesh&lt;&#x2F;h2&gt;
&lt;p&gt;Bluetooth Mesh networking introduces several unique identifiers (IDs) at various layers of the protocol to manage devices, messages, and network security. These IDs serve different purposes than traditional Bluetooth or BLE device addresses.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unicast Address (Node Address&#x2F;Element Address)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Each node (device) in a Bluetooth Mesh network is assigned a unique &lt;strong&gt;unicast address&lt;&#x2F;strong&gt; during the provisioning process. This is a 16-bit value that uniquely identifies the node or its elements within the mesh network.&lt;&#x2F;li&gt;
&lt;li&gt;A node can have multiple elements, each with its own unicast address in a contiguous range.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Group Address&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;16-bit values used to address multiple nodes simultaneously (e.g., all lights in a room). Nodes can subscribe to one or more group addresses, enabling efficient publish&#x2F;subscribe communication.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Virtual Address&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;128-bit values derived from a UUID. They allow addressing of a logical group of nodes, regardless of their physical location or provisioning sequence. Virtual addresses are mapped to a 16-bit address space for use in messages.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Key (DevKey)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A unique 128-bit cryptographic key assigned to each node during provisioning. It is used for secure communication between the provisioner and the node, especially for configuration and management messages.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network Key (NetKey) and Application Key (AppKey)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Network Keys&lt;&#x2F;strong&gt; are shared among all nodes in a mesh network and are used to secure network layer messages.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Application Keys&lt;&#x2F;strong&gt; are used to secure application-specific messages, allowing for separation of different functionalities (e.g., lighting vs. sensor data).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Model Identifier&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Each mesh model (defining device behavior, such as a light switch or sensor) is assigned a unique identifier:&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;SIG-adopted models&lt;&#x2F;strong&gt;: Identified by a 16-bit model identifier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Vendor-specific models&lt;&#x2F;strong&gt;: Identified by a 16-bit vendor ID and a 16-bit model ID.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Message Sequence Number&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Every message sent by a node includes a &lt;strong&gt;sequence number&lt;&#x2F;strong&gt; to prevent replay attacks and ensure message uniqueness.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Property ID&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For sensor and property models, each property (e.g., temperature, humidity) is assigned a unique &lt;strong&gt;Device Property ID&lt;&#x2F;strong&gt; as per the Bluetooth Mesh device properties specification.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Node ID&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Some documentation refers to a &lt;strong&gt;Node ID&lt;&#x2F;strong&gt; (or nodeId), typically a 2-byte value, as a unique identifier for a mesh device within the network, used for addressing and control.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;ipv6-eui-64&quot;&gt;IPv6&#x2F;EUI-64&lt;&#x2F;h2&gt;
&lt;p&gt;IPv6&#x2F;EUI-64 addresses are a 64-bit number commonly used in IPv6 and typically displayed as 8 groups of four hexadecimal digits: &lt;code&gt;2001:0db8:85a3:0000:0000:8a2e:0370:7334&lt;&#x2F;code&gt;. Consecutive groups of zeros can be replaced with a double colon. For example, &lt;code&gt;2001:0db8:0000:0000:0000:0000:0000:0001&lt;&#x2F;code&gt; can be shorted to &lt;code&gt;2001:0db8::1&lt;&#x2F;code&gt;. Note, leading zeros in the group are also omitted. IPv6 address blocks are assigned by the Internet Assigned Numbers Authority (IANA), which allocates large blocks of addresses to Regional Internet Registries (RIRs). These RIRs then distribute smaller blocks to Internet Service Providers (ISPs) and other organizations. The ARIN (American Registry for Internet Numbers) provides blocks of IPv6 addresses. The annual fee for a 3X-Small block (288 addresses) is $262.50 at the time of writing.&lt;&#x2F;p&gt;
&lt;p&gt;There are also EEPROM and other ICs that have EUI-64 numbers preprogrammed, such as the Microchip &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;en-us&#x2F;product&#x2F;24AA02E64&quot;&gt;24AA02E64&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qr-codes&quot;&gt;QR Codes&lt;&#x2F;h2&gt;
&lt;p&gt;QR codes provide the opportunity to easily read a UUIDs or some other long ID on every device using a phone camera. This relieves some of the complexity of humans having to deal with long IDs.&lt;&#x2F;p&gt;
&lt;p&gt;Entering a known device in the field into an application is easy with QR codes. However, finding a device (one among many) in the field can be difficult unless the application has a feature designed just for this.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-13.png&quot; alt=&quot;&quot; style=&quot;width:392px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There is no central registry for QR codes. Instead, the process of QR code generation and use is decentralized and relies on the vast number of possible QR code combinations to avoid conflicts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;snmp-private-enterprise-numbers-pen&quot;&gt;SNMP&#x2F;Private Enterprise Numbers (PEN)&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;strong&gt;SNMP Private Enterprise Number (PEN)&lt;&#x2F;strong&gt; is a unique identifier assigned by the Internet Assigned Numbers Authority (IANA) to organizations, individuals, or entities. It is primarily used in network management protocols like Simple Network Management Protocol (SNMP) to identify objects defined by an enterprise within the Management Information Base (MIB) structure.&lt;&#x2F;p&gt;
&lt;p&gt;PENs are part of the Object Identifier (OID) hierarchy under the prefix &lt;code&gt;1.3.6.1.4.1&lt;&#x2F;code&gt;, which corresponds to &lt;code&gt;.iso.org.dod.internet.private.enterprise&lt;&#x2F;code&gt;. This prefix ensures that each PEN is globally unique.&lt;&#x2F;p&gt;
&lt;p&gt;Any entity can request a PEN assignment &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;enterprise-numbers&#x2F;&quot;&gt;from IANA at no cost&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;automobile-vin&quot;&gt;Automobile VIN&lt;&#x2F;h2&gt;
&lt;p&gt;The modern 17-character Vehicle Identification Number (VIN) format was first conceptualized and standardized by the United States National Highway Traffic Safety Administration (NHTSA) in 1981. This standardization aimed to unify the previously inconsistent vehicle identification practices across manufacturers and facilitate more effective tracking of recalls, registrations, and thefts. The VIN system introduced by NHTSA was later adopted globally and is now governed by the International Organization for Standardization (ISO), specifically under ISO 3779 (content and structure) and ISO 4030 (location and attachment)&lt;&#x2F;p&gt;
&lt;p&gt;An example of an automobile VIN (Vehicle Identification Number) is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1P8ZA1279SZ215470&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;VINs are always 17 characters long and use a combination of capital letters and digits. Each section of the VIN provides specific information about the vehicle:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The first three characters (World Manufacturer Identifier) indicate the manufacturer and country of origin.&lt;&#x2F;li&gt;
&lt;li&gt;Characters 4–8 describe features such as model, body type, and engine.&lt;&#x2F;li&gt;
&lt;li&gt;The 9th character is a check digit for security.&lt;&#x2F;li&gt;
&lt;li&gt;The 10th character indicates the model year (e.g., “S” for 1995, “R” for 1994 or 2024).&lt;&#x2F;li&gt;
&lt;li&gt;The 11th character shows the assembly plant.&lt;&#x2F;li&gt;
&lt;li&gt;The last six characters are a unique serial number for that vehicle.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;knx-serial-number&quot;&gt;KNX Serial Number&lt;&#x2F;h2&gt;
&lt;p&gt;KNX is a popular building automation standard. The KNX &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;support.knx.org&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;4641703241234-KNX-Serial-Number&quot;&gt;serial numbers&lt;&#x2F;a&gt; follow the following format:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Length:&lt;&#x2F;strong&gt; The KNX serial number is always 6 bytes (octets) long.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manufacturer Code:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Octets 6 and 5&lt;&#x2F;strong&gt; (the first two bytes, when read from left to right) contain the official KNX Manufacturer Code assigned to each manufacturer by the KNX Association.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device-Specific Portion:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Octets 4 to 1&lt;&#x2F;strong&gt; (the remaining four bytes) are managed by the manufacturer.&lt;&#x2F;li&gt;
&lt;li&gt;This part may encode information such as production site, date, series, batch, or simply a sequential unique number.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bacnet&quot;&gt;BACnet&lt;&#x2F;h2&gt;
&lt;p&gt;BACnet Device IDs, also known as Device Object Identifiers or Device Instance Numbers, are unique numerical values assigned to each BACnet device on a network to identify them distinctly.&lt;&#x2F;p&gt;
&lt;p&gt;The Device ID is a 22-bit unsigned integer ranging from 0 to 4,194,302 (decimal). The value 4,194,303 (0x3FFFFF) is reserved and cannot be used as a valid Device ID.&lt;&#x2F;p&gt;
&lt;p&gt;This Device ID corresponds to the object instance number portion of the BACnet Device Object’s Object_Identifier property.&lt;&#x2F;p&gt;
&lt;p&gt;The full Object_Identifier is a 32-bit value composed of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Object Type (10 bits): For a Device object, this is fixed as 8.&lt;&#x2F;li&gt;
&lt;li&gt;Object Instance (22 bits): The Device ID itself.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;BACnet IDs are not assigned during manufacturing, but rather during setup&#x2F;installation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;matter&quot;&gt;Matter&lt;&#x2F;h2&gt;
&lt;p&gt;Matter devices include a Device Attestation Certificate (DACs) generated through a hierarchical Public Key Infrastructure (PKI) process, ensuring each device is uniquely authenticated. Each device is cryptographically verified, making spoofing difficult.&lt;&#x2F;p&gt;
&lt;p&gt;The DAC is part of a chain of trust:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product Attestation Authority (PAA):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Root certificate issued by the Connectivity Standards Alliance (CSA) or an approved third party.&lt;&#x2F;li&gt;
&lt;li&gt;Stored in the Distributed Compliance Ledger (DCL), a global registry of trusted certificates.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product Attestation Intermediate (PAI):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Intermediate certificate signed by the PAA.&lt;&#x2F;li&gt;
&lt;li&gt;Typically includes the manufacturer’s Vendor ID (VID).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Device Attestation Certificate (DAC):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unique per-device certificate signed by the PAI.&lt;&#x2F;li&gt;
&lt;li&gt;Contains the device’s VID, Product ID (PID), public key, and serial number.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Additionally, devices use rotating keys, which makes tracking difficult and preserves privacy. End users scan a QR code to onboard devices.&lt;&#x2F;p&gt;
&lt;p&gt;Matter attempts to be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Authentic (not counterfeit)&lt;&#x2F;li&gt;
&lt;li&gt;Secure (resistant to hacking)&lt;&#x2F;li&gt;
&lt;li&gt;Private (resistant to tracking)&lt;&#x2F;li&gt;
&lt;li&gt;Interoperable (works with any ecosystem)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;serial-numbers&quot;&gt;Serial Numbers&lt;&#x2F;h2&gt;
&lt;p&gt;Other custom serial numbers take many different forms. Some examples are shown below:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Format Type&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;th&gt;Typical Use Cases&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Sequential&lt;&#x2F;td&gt;&lt;td&gt;D000001&lt;&#x2F;td&gt;&lt;td&gt;Incremented by one, often padded with zeros&lt;&#x2F;td&gt;&lt;td&gt;Manufacturing, inventory&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Alphanumeric&lt;&#x2F;td&gt;&lt;td&gt;TBL-101A234&lt;&#x2F;td&gt;&lt;td&gt;Letters and numbers, often with category or model encoded&lt;&#x2F;td&gt;&lt;td&gt;Electronics, equipment rental&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Random&lt;&#x2F;td&gt;&lt;td&gt;X9F4-7T32-ZY6&lt;&#x2F;td&gt;&lt;td&gt;Unpredictable, generated by algorithm&lt;&#x2F;td&gt;&lt;td&gt;Security-sensitive items&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Date&#x2F;Batch Embedded&lt;&#x2F;td&gt;&lt;td&gt;20230715-001-123&lt;&#x2F;td&gt;&lt;td&gt;Encodes date and batch with sequence number&lt;&#x2F;td&gt;&lt;td&gt;Quality control, traceability&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;systemd-network-interfaces&quot;&gt;Systemd network interfaces&lt;&#x2F;h2&gt;
&lt;p&gt;Systemd’s predictable network interface name encodes the physical path of the device. Example of how &lt;strong&gt;enp0s13f0u2c2&lt;&#x2F;strong&gt; is constructed:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;en&lt;&#x2F;strong&gt;: Ethernet device (prefix for Ethernet interfaces).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;p0&lt;&#x2F;strong&gt;: PCI bus 0&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;s13&lt;&#x2F;strong&gt;: PCI slot 13 (device 13 on the bus)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;f0&lt;&#x2F;strong&gt;: PCI function 0&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;u2&lt;&#x2F;strong&gt;: USB port 2 (the device is connected via USB, possibly a USB Ethernet adapter)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;c2&lt;&#x2F;strong&gt;: USB configuration or child port 2 (sometimes used to indicate a specific port or configuration on a USB hub)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;I’m sure there are many other examples – please leave a comment if you’d like to share other interesting formats. In a future post, we’ll explore a new standard for device IDs that is optimized for human interaction in the field. Subscribe below to stay informed of the latest developments.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement Zephyr web applications</title>
        <published>2025-04-08T00:00:00+00:00</published>
        <updated>2025-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/"/>
        <id>https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2420/how-to-implement-zephyr-web-applications/">&lt;p&gt;Are you considering implementing a web UI in your &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zephyrproject.org&#x2F;&quot;&gt;Zephyr RTOS&lt;&#x2F;a&gt; application and perplexed by the endless number of web technologies available today? This article traces my journey through trying several options and presents some of the tradeoffs.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-10.png&quot; alt=&quot;&quot; style=&quot;width:377px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Modern microcontrollers (MCUs) have many connectivity options (Ethernet, WiFi, Bluetooth, Cellular, etc.), and when coupled with the Zephyr OS, implementing a web application on these devices often makes sense. Once you start doing this, you soon realize that this is not Ruby-on-Rails. Rather, Zephyr is still a very constrained environment (see my &lt;a href=&quot;&#x2F;1540&#x2F;microcontroller-mcu-or-microprocessor-mpu&#x2F;&quot;&gt;article on the differences between MPUs and MCUs&lt;&#x2F;a&gt;). While we can still leverage modern web technologies, we need to be selective because of the constraints of MCU systems. An example of a web UI in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-siot&#x2F;tree&#x2F;main&#x2F;apps&#x2F;siot-net&quot;&gt;Zephyr SimpleIoT project&lt;&#x2F;a&gt; is shown below:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;primary-concerns-in-an-mcu-system&quot;&gt;Primary concerns in an MCU system&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;size&quot;&gt;Size&lt;&#x2F;h2&gt;
&lt;p&gt;The memory resources on MCU and MPU systems are &lt;a href=&quot;&#x2F;1540&#x2F;microcontroller-mcu-or-microprocessor-mpu&#x2F;&quot;&gt;vastly different&lt;&#x2F;a&gt; – a difference of over 1,000x.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table class=&quot;has-fixed-layout&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MCU (Internal)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MCU (External)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;MPU (Server)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Flash&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;0.5-2MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;500GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;RAM&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;0.25 - 1MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16MB&lt;&#x2F;td&gt;&lt;td class=&quot;has-text-align-center&quot; data-align=&quot;center&quot;&gt;16GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;While it is possible to use larger memory devices with MCUs, like an SD card or SDRAM, the above table is for the more common scenarios.&lt;&#x2F;p&gt;
&lt;p&gt;If we want to serve the web application entirely from a Zephyr device, then the web assets must fit in flash. The RAM size also limits the number of connections we can handle and the size of the data payloads we can transmit and receive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stability-includes-maintainability-and-security&quot;&gt;&lt;strong&gt;Stability (includes maintainability and security)&lt;&#x2F;strong&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The constraints of an MCU drive us toward doing more in the browser (frontend) because resources there are free and plentiful. This typically ends up being a Single-Page Application (SPA) architecture, where the web application is a free-running application that fetches and sends data to the MCU (backend). All rendering happens in the browser instead of the MCU. Because of this, the web application needs to be stable. Extra care must be taken so that the application does not crash and freeze or pop up annoying messages telling the user to reload the page, which can easily happen with JavaScript.&lt;&#x2F;p&gt;
&lt;p&gt;We also need to consider how the application is hosted. A typical web application is hosted in the cloud in one place. If there is a problem, we have complete control over updating and fixing it as needed. Embedded applications are a completely different matter – there may be thousands of devices. If there are problems, it is not as simple as updating a single server. We may have a firmware update mechanism in the device, but it is often up to the user to decide when to update. Users expect embedded devices to be stable. Many of them are used in critical applications. An instability in the web UI of the device does not give a positive impression, even though it may only be a web frontend crash, and the device is still functioning fine.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:600px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;It seems simple to write an initial prototype, but maintaining a web application over time is a different matter. Security can also be a concern as many web frameworks pull in mountains of JavaScript dependencies via NPM, which are difficult to audit for security problems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;state-management&quot;&gt;&lt;strong&gt;State Management&lt;&#x2F;strong&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;One of the hardest parts of a web application is maintaining state. The reason for this is that user interfaces can be deeply nested and complex. The naive approach is to distribute the state into each UI component. The difficulty with this is keeping everything in sync. There has been a continual stream of new frontend state management libraries (Redux, MobX, VueX, React Context, XState, react-easy-state, etc.). This is not an easy problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;options&quot;&gt;Options&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;serve-site-assets-from-external-server&quot;&gt;Serve site&#x2F;assets from external server&lt;&#x2F;h2&gt;
&lt;p&gt;One way to work around the asset size constraint in MCUs is to serve large assets (like a Bootstrap CSS file) from an external server.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-2.png&quot; alt=&quot;&quot; style=&quot;width:375px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are several potential issues with this:&lt;&#x2F;p&gt;
&lt;p&gt;❌ The external asset must always be available, and if it goes away or changes, then the web application on the device must be updated to point to the new location.&lt;&#x2F;p&gt;
&lt;p&gt;❌ If the entire site is served from an external server, then you must host all versions of the web application or be very careful to maintain backward compatibility to all previous versions of firmware running on the Zephyr device.&lt;&#x2F;p&gt;
&lt;p&gt;❌ You may need the Zephyr UI to function if the Internet is down or unavailable (example: air-gapped secure setups or during device setup). In many systems, device state is mirrored to an upstream server, so the only time you would use the local UI is during setup or when the Internet is down.&lt;&#x2F;p&gt;
&lt;p&gt;✅ &lt;strong&gt;The most reliable way to host a Zephyr web application is on the device itself.&lt;&#x2F;strong&gt; You certainly have many more options if you host it externally, but there are tradeoffs that must be considered.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-build-just-html-js-css&quot;&gt;No Build, just HTML, JS, CSS&lt;&#x2F;h2&gt;
&lt;p&gt;DHH and others are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;once-1-is-entirely-nobuild-for-the-front-end-ce56f6d7&quot;&gt;advocating No-Build&lt;&#x2F;a&gt; web solutions. However, they have Rails for a backend, and we have Zephyr. I investigated this approach, but manually mutating HTML elements in JavaScript in a complex app is messy and scattered – you’ll eventually create a framework anyway, so you may as well start with something close to meeting your needs.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-6.png&quot; alt=&quot;&quot; style=&quot;width:400px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;HTML&#x2F;JS&#x2F;CSS development is powerful and flexible, but is tailored to design, not programming. In its raw state, it is like developing a program where everything is a global variable. If you have a dynamic web application responding to real-world events, this quickly becomes a programming problem that is difficult to manage with 200 global variables. You need an abstraction on top of this. Again, a powerful templating engine on the backend helps a lot, which we do not have in Zephyr applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;react-vue-angular-non-compiled-frameworks&quot;&gt;React, Vue, Angular (non-compiled frameworks)&lt;&#x2F;h2&gt;
&lt;p&gt;Solutions like React are too large for many MCU applications as they typically require a megabyte or more of web assets to be transferred from the host. Additionally, you have the issue of JavaScript crashes and the continual bloat and churn of the NPM package ecosystem. Updating to new versions of packages can be a lot of work as APIs sometimes change. While this solution can work for large-scale cloud-hosted apps, it is not ideal for embedded web UIs where you often don’t have control over the device and can’t easily patch the system if there is a problem.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-12.png&quot; alt=&quot;&quot; style=&quot;width:420px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;I’ve been writing&#x2F;maintaining a 50K SLOC Meteor&#x2F;React app for the past 10 years – it works and has been very successful. However, we’ve had a handful of frontend crashes. Being a cloud app, we were able to deploy fixes for this quickly, but it is still an inconvenience for users. In another project developed by a very experienced JavaScript developer, we also had a number of JavaScript crashes in the frontend. There are likely ways to reduce or avoid these stability problems, but it is not inherent in the system&#x2F;language. It requires a high degree of carefulness and discipline. It is not easy to refactor JavaScript and know that you have fixed all the issues caused by your code change.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-11.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are slimmer solutions like Preact which may solve the size issue, but you likely lose some of the integration with all the libraries written for React.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;htmx&quot;&gt;htmx&lt;&#x2F;h2&gt;
&lt;p&gt;htmx is the cool kid on the block right now – supposedly simple and easy to use. I tried this for the first iteration of a Zephyr web application and got a prototype running, but concluded it works best if you have a powerful backend that can do most of your rendering, and the frontend just handles a little bit of reactivity. Additionally, with htmx, you typically open up a network connection for every widget to get updates, and this requires a lot of connection resources on the backend, which are expensive in a Zephyr system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-7.png&quot; alt=&quot;&quot; style=&quot;width:313px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;svelte&quot;&gt;Svelte&lt;&#x2F;h2&gt;
&lt;p&gt;Svelte is a compiled language that generates small assets, so it works well from a size perspective. It also appears to be a well-maintained project with good tooling. However, there are two downsides: 1) it is still JavaScript, so you have potential stability issues when maintaining applications long-term. 2) It puts the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;free-code-camp&#x2F;react-s-jsx-the-other-side-of-the-coin-2ace7ab62b98#.rvo6p4jsq&quot;&gt;“JS” in the “HTML” instead of the “HTML” in the “JS”&lt;&#x2F;a&gt; (like React or Elm). This is largely a matter of preference, but as a programmer, I prefer the latter. The success of React indicates that many others do, too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;functional-languages&quot;&gt;Functional Languages&lt;&#x2F;h2&gt;
&lt;p&gt;Functional languages are becoming more common in frontend development because they solve many reliability and refactoring challenges. Some options include ClojureScript, Elm (discussed below), PureScript, ReasonML, F#, Scala.js. Some of these options likely have smaller asset sizes than non-compiled options.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elm&quot;&gt;Elm&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt; is a compiled language that produces small assets. It is like React JSX in that it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;free-code-camp&#x2F;react-s-jsx-the-other-side-of-the-coin-2ace7ab62b98#.rvo6p4jsq&quot;&gt;puts the “HTML” in the “Elm&lt;&#x2F;a&gt;“. Elm is a functional language that solves many of the challenges with web programming, including stability and managing state. Runtime errors in an Elm application are very rare. I wrote the Simple IoT UI in Elm, which is now 18,610 lines of code, and have maintained it since 2018. It has never crashed, and it is easy to add new features. Code density&#x2F;reuse in Elm is very high. If it compiles, it generally works, so very little time is spent in the browser console debugging stuff. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mdgriffith&#x2F;elm-ui&quot;&gt;elm-ui&lt;&#x2F;a&gt; package offers a powerful style and layout system that eliminates most of the pain with web programming and allows someone (like me) who is not a dedicated web developer to maintain a pretty nice web application without learning the intricacies of CSS.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;04&#x2F;image-9.png&quot; alt=&quot;&quot; style=&quot;width:279px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As you maintain an Elm project, you’ll find that the language pushes you to a cleaner design. It nudges you in the right direction. The opposite generally happens in JavaScript projects, where a lot more discipline is required to keep things from becoming a mess.&lt;&#x2F;p&gt;
&lt;p&gt;Elm allows for creating powerful functions like the following for a text input form:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;textInput Point.typeBitRate &amp;quot;Bit rate&amp;quot; &amp;quot;250000&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This line of code renders a form element and automatically posts a new point to the backend of type &lt;code&gt;BitRate&lt;&#x2F;code&gt; when the content is changed, nothing else in the system needs to change for this to happen. There are no “handlers” that need to be attached to this element. Elm also has some of the best tooling in this industry – elm-review, elm-land, etc. This tooling is largely made possible by the language.&lt;&#x2F;p&gt;
&lt;p&gt;Elm is a small project and community, but it is a stable&#x2F;friendly community that has existed for many years, and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jah2488&#x2F;elm-companies&quot;&gt;many companies are successfully using Elm&lt;&#x2F;a&gt;. The Elm package system is fairly comprehensive and has most of what you might need to implement web apps. Since Elm packages are pure Elm, the entire ecosystem is stable and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.perplexity.ai&#x2F;search&#x2F;is-elm-considered-a-secure-lan-aAvNu0V6TfCAe4uVg9kXMw&quot;&gt;relatively secure&lt;&#x2F;a&gt;. There is some concern about the future of Elm as the compiler does not get frequent updates. Some have produced new versions of the compiler to meet special needs. The packages and tooling around Elm are where most innovation is happening right now, and it is phenomenal. Elm got it mostly right, so there is not much that needs immediate improvement in the core.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;There is no silver bullet in technology. With any choice, there are tradeoffs. Most people stick with mainstream JavaScript for frontend programming as the “safe” approach. However, in Zephyr&#x2F;MCU-based systems, there are constraints that we don’t face in server environments.&lt;&#x2F;p&gt;
&lt;p&gt;There are significant challenges in the HTML&#x2F;JS&#x2F;CSS world. While it is nice to have options, the continual churn of new frameworks (jQuery -&amp;gt; Backbone -&amp;gt; Ember -&amp;gt; Angular -&amp;gt; Meteor -&amp;gt; React -&amp;gt; Angular2 -&amp;gt; Vue -&amp;gt; Svelte -&amp;gt; Next.js) (and many others) indicates there is some fundamental problem with the Javacript approach that has not been solved in a general way. The number of NPM package dependencies pulled into a typical project is staggering and nearly impossible for small teams to audit for security and longevity. NPM installs routinely break for various reasons. NPM suffers from some of the same problems as Python, as many packages compile C code in non-standard ways during the package install process, which can be fragile.&lt;&#x2F;p&gt;
&lt;p&gt;There is also the issue of what might be viewed as an impedance mismatch – what the technology mega-companies produce and use is not always the best fit for small companies&#x2F;teams with limited resources. Facebook faces different problems on a different scale than a small embedded team. While React is right for them, we can’t assume it is right for everyone. Most of us are not facing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.bradfieldcs.com&#x2F;you-are-not-google-84912cf44afb&quot;&gt;Google-scale problems&lt;&#x2F;a&gt; that require a system as complex as Kubernetes. Ansible and a few servers work just fine. Facebook has near-infinite resources. They have ways to deal with the inherent stability problems of JavaScript. A small company&#x2F;team does not have these resources, so different technologies like Elm may be a better fit.&lt;&#x2F;p&gt;
&lt;p&gt;When faced with the need for a Zephyr web application, I tried htmx first, then looked at “no build”. Neither of these worked very well for me. Having worked on decent-sized React and Elm projects, Elm looked like a better fit for the next try due to asset size, reliability, and maintainability. Additionally, I had already solved the problem of how to effectively deal with &lt;a href=&quot;&#x2F;2432&#x2F;struggling-to-scale-your-iot-system-simplify-your-data&#x2F;&quot;&gt;data in a distributed IoT system&lt;&#x2F;a&gt;, and had &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;blob&#x2F;master&#x2F;frontend&#x2F;src&#x2F;UI&#x2F;NodeInputs.elm&quot;&gt;frontend code already written&lt;&#x2F;a&gt; to interface with this dataflow in Simple IoT. It was easy to port the Simple IoT frontend to a smaller version tailored for MCUs, and thus far it seems to be working well. Check out the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;zephyr-siot&#x2F;tree&#x2F;main&#x2F;apps&#x2F;siot-net&quot;&gt;Simple IoT Zephyr Networking Example&lt;&#x2F;a&gt; to learn more.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Struggling to scale your IoT system? Simplify your data.</title>
        <published>2025-03-29T00:00:00+00:00</published>
        <updated>2025-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/"/>
        <id>https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2432/struggling-to-scale-your-iot-system-simplify-your-data/">&lt;p&gt;Have you struggled with adapting your IoT system to new applications and requirements? Is handling configuration updates at both the cloud and edge a challenge? Is synchronizing required data between cloud and edge instances a challenge? This article describes a simple way to model data that eliminates many of these difficulties.&lt;&#x2F;p&gt;
&lt;p&gt;We can scale an IoT system both &lt;strong&gt;horizontally&lt;&#x2F;strong&gt; (deploy more units) and &lt;strong&gt;vertically&lt;&#x2F;strong&gt; (add features and address new applications). While the ideas presented in this essay are focused on vertical scale, any simplification will likely help with horizontal scale as well.&lt;&#x2F;p&gt;
&lt;p&gt;Previously, we explored &lt;a href=&quot;&#x2F;1884&#x2F;layered-event-and-data-centric-architectures-in-distributed-iot-systems&#x2F;&quot;&gt;data-centric architectures in IoT systems&lt;&#x2F;a&gt;. This post expands on this by describing how to represent data using Nodes and Points in a way that drastically simplifies IoT data storage, exchange, and synchronization. This is in contrast to encodings and mechanisms used in traditional web and cloud systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-are-iot-systems-different&quot;&gt;How are IoT systems different?&lt;&#x2F;h2&gt;
&lt;p&gt;IoT systems 🌐 have the following properties, which differentiate them from traditional computer&#x2F;web&#x2F;cloud applications:&lt;&#x2F;p&gt;
&lt;p&gt;🌐 IoT systems are inherently distributed (equipment is located in many physically different locations).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Data must exist concurrently in multiple places (cloud and many edge instances).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Data is not fully replicated on every instance (a cloud server instance might contain the entire dataset, whereas an edge instance only has a tiny fraction of the dataset that is relevant at that site).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 Instances are not symmetrical (edge instances are very different than cloud instances. It is not a cluster).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 There can be many instances (thousands of edge devices).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 The network is even less reliable (edge systems are often in uncontrolled environments).&lt;&#x2F;p&gt;
&lt;p&gt;🌐 The system must continue to operate during network interruptions (it is not a cluster).&lt;&#x2F;p&gt;
&lt;p&gt;We can attempt to address these challenges by adding constraints such as: 1) data only flows in one direction, 2) device configuration is only changed in the cloud, and 3) the data payload format will not change over time. However, if we think realistically about these constraints, they are impractical for many systems. In distributed computer systems, change is the constant. Because a system can be networked, its capabilities are endless. The ability to connect to new and different systems means new systems and new value can always be created, and &lt;em&gt;&lt;strong&gt;things will change&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;. If you don’t, somebody else will.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-struct&quot;&gt;The &lt;em&gt;“struct”&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Cloud&#x2F;Web APIs have traditionally used various encoding schemes and patterns such as Protobuf, JSON, REST, gRPC, etc. Tools exist to manage schemas, such as GraphQL and JSON Schema. Synchronization mechanisms can be used to manage conflicts (Raft, CRDT, etc.). Most of these schemes assume that the complex &lt;em&gt;struct&lt;&#x2F;em&gt; with multiple and sometimes nested fields is the fundamental element of data representation, storage, and transmission. An example is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;type EmployeeData struct {
    ID                 int
    Name               string
    Age                int
    Email              string
    Phone              string
    Street             string
    City               string
    Country            string
    PostalCode         string
    EmploymentHistory  []struct {
        Company  string
        Position string
        Years    int
    }
    Skills             map[string]struct {
        Proficiency     string
        YearsExperience int
    }
    LastUpdated        time.Time
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Structs are great – they are a powerful tool for organizing data in a computer program. They are so useful that we have also assumed structs are the best way to store and transfer data outside a program. Thus, we have tables in SQL databases, REST APIs, Protobuf&#x2F;JSON encoding, etc. This works fairly well and is likely the right solution in many domains. However, we have the following problems with using the &lt;code&gt;struct&lt;&#x2F;code&gt; outside a computer program:&lt;&#x2F;p&gt;
&lt;p&gt;❌ Updating the &lt;code&gt;struct&lt;&#x2F;code&gt; tends to be an all-or-nothing proposition. Fetching the data from a REST API gives you the entire &lt;code&gt;struct&lt;&#x2F;code&gt;. Likewise, when updating, you send the entire &lt;code&gt;struct&lt;&#x2F;code&gt;. There are tools, such as GraphQL, that attempt to solve this problem.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Schema changes are painful. Many very elaborate tools are dedicated to solving the problem of database migrations.&lt;&#x2F;p&gt;
&lt;p&gt;❌ API schema changes are even more painful.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Distributed systems are hard, especially if the &lt;code&gt;struct&lt;&#x2F;code&gt; may be updated by multiple systems concurrently and then requires merging. CRDTs and various other distributed system algorithms attempt to solve this problem, but they are complex.&lt;&#x2F;p&gt;
&lt;p&gt;❌ Nested data is problematic and compounds issues with schema changes and synchronization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-in-iot-systems&quot;&gt;Data in IoT Systems&lt;&#x2F;h2&gt;
&lt;p&gt;What are desirable features for handling data in a distributed IoT system?&lt;&#x2F;p&gt;
&lt;p&gt;✔️ We can generate&#x2F;change data anywhere (in the cloud, at the edge, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Synchronization between instances is granular, simple, and reliable.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ Data can flow in any direction.&lt;&#x2F;p&gt;
&lt;p&gt;✔️ One mechanism&#x2F;transport can be used for all types of data (config, sensor samples, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;✔️ All data changes in the system are recorded in history.&lt;&#x2F;p&gt;
&lt;p&gt;On the surface, this seems like a hard problem. If you have a &lt;em&gt;struct&lt;&#x2F;em&gt; that exists in multiple places, and one field gets changed in one location, and another field gets changed in a second location, how do you reconcile the differences and record what has changed?&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned before, there are solutions such as CRDTs or sending data changes over the wire. Some systems only store changes (mutations) and then compute the current state from all the changes. However, all these schemes are mostly just adding layers of complexity on top of an existing paradigm and are rarely a good fit for IoT systems where you accumulate many thousands of data samples (changes) over time. Maybe it’s time to change the paradigm …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;points-and-nodes&quot;&gt;Points and Nodes&lt;&#x2F;h2&gt;
&lt;p&gt;What if we rethink our concept of data representation? Instead of trying to make a generic &lt;code&gt;struct&lt;&#x2F;code&gt; the fundamental unit of data, we take a more granular approach and focus on each piece of data in a struct. Can we create a simple unit of data that is easy to store and synchronize, and then build on top of this? This same unit of data is used for everything, including configuration, sample data, notifications, etc. The data unit we have arrived at in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;&quot;&gt;Simple IoT project&lt;&#x2F;a&gt; (after many iterations) is the “Point.”&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-3.png&quot; alt=&quot;&quot; style=&quot;width:250px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The data type is typically a &lt;code&gt;string&lt;&#x2F;code&gt;, &lt;code&gt;int&lt;&#x2F;code&gt;, or &lt;code&gt;float&lt;&#x2F;code&gt;, but it can be anything you want.&lt;&#x2F;p&gt;
&lt;p&gt;Points are organized in a hierarchical tree of nodes, where each node contains an array of points.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image.png&quot; alt=&quot;&quot; style=&quot;width:300px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Because a &lt;code&gt;point&lt;&#x2F;code&gt; is defined by both a &lt;code&gt;type&lt;&#x2F;code&gt; and a &lt;code&gt;key&lt;&#x2F;code&gt;, it is possible to construct arrays and maps by populating the &lt;code&gt;key&lt;&#x2F;code&gt; field with either an array index or a map key. This allows us to easily represent one level of structure (arrays and maps) in a node as shown in the following example:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-6.png&quot; alt=&quot;&quot; style=&quot;width:600px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;If a deeper structure is required, then nest additional nodes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benefits&quot;&gt;Benefits&lt;&#x2F;h2&gt;
&lt;p&gt;There are multiple benefits to this data architecture.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Data is granular.&lt;&#x2F;strong&gt; An edge instance can update a node’s sensor reading, and the user can update a node’s config setting in the cloud simultaneously. The points are easily merged as they are received into the node at both locations, without conflicts. This works very well because different users&#x2F;instances tend to update different points. The exception to this may occur when a user at the edge and a cloud user update a config item at the same time. In this case, we simply use the point with the latest timestamp.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;The storage and communication infrastructure does not change.&lt;&#x2F;strong&gt; One of the biggest problems in traditional storage mechanisms and network APIs is that schema and encoding changes can be very painful. If you add a field to a data structure, every piece of code that touches the data as it travels throughout the system needs to be updated. With nodes and points, only the ends of your system need to be updated. Everything in between (transmission, storage, sync, etc) can stay the same.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2025&#x2F;03&#x2F;image-4.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Introspection and monitoring are easy.&lt;&#x2F;strong&gt; Since our data format is simple and fixed, it is easy to watch and decode traffic anywhere to see what is going on.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Integration is easy.&lt;&#x2F;strong&gt; Because we have standardized the data to be very simple, it is easy for one service to provide data that another can use.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;Everything is data that can be acted upon.&lt;&#x2F;strong&gt; In the past, we might have had a rules engine that could respond to sensor data changes. Since config changes are now the same kind of data, the rules engine can now respond to and make config changes as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;History is easily logged for all changes.&lt;&#x2F;strong&gt; Likewise, since config and sensor sample data are now the same type of data, everything that happens in the system can be easily recorded in history. The system is automatically auditable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;It is efficient.&lt;&#x2F;strong&gt; Because the data is granular, only what changes is transmitted and processed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;✔️&lt;&#x2F;strong&gt; &lt;strong&gt;It works both internally and externally.&lt;&#x2F;strong&gt; While this data scheme was primarily developed to efficiently communicate between systems connected by networks, it also works very well for communicating between threads in an application. When an application is architected this way, it is very easy to extend, it as the communication scheme internally and externally is the same. This architecture scales.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;objections&quot;&gt;Objections&lt;&#x2F;h2&gt;
&lt;p&gt;🚩&lt;strong&gt;Objection #1: But isn’t this a lot of overhead to store a type&#x2F;key&#x2F;timestamp&#x2F;etc with every bit of data?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We need to focus on where the bottlenecks&#x2F;hard&#x2F;expensive parts of the system are. Synchronizing data from many different instances over networks is the hard part of IoT systems. Local storage and CPU processing are relatively cheap in comparison. Networks are also relatively slow compared to the additional processing time required to process this data. CPU and storage are now abundant, even on microcontrollers. Development, operations, and deployment are not cheap.&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #2: Nodes and Points are hard to deal with.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;True, dealing with raw &lt;code&gt;nodes&lt;&#x2F;code&gt; and &lt;code&gt;points&lt;&#x2F;code&gt; is not as convenient as a &lt;code&gt;struct&lt;&#x2F;code&gt;, but we &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;data&quot;&gt;can create tools&lt;&#x2F;a&gt; that easily convert &lt;code&gt;structs&lt;&#x2F;code&gt; to and from &lt;code&gt;nodes&#x2F;points&lt;&#x2F;code&gt;. We do it all the time – JSON, Protobuf, etc. Computers are very good at encoding&#x2F;decoding data – let them do it.&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #3: How do you protect your data if anyone can update anything?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;AuthZ&#x2F;AuthN is a valid concern and has not been fully solved yet. One idea is to authorize access to data at the node level – each user or instance would have access to a set of nodes. However, this says that an edge device could change its own config parameters. Perhaps this is OK because, without physical security, you don’t have true security. It may also be useful to differentiate between&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;running-a-nats-service&#x2F;configuration&#x2F;securing_nats&#x2F;authorization#permissions-configuration-map&quot;&gt;read and write access&lt;&#x2F;a&gt; to node data. Ideas are welcome!&lt;&#x2F;p&gt;
&lt;p&gt;🚩 &lt;strong&gt;Objection #4: If points for a single struct are flowing in at different times, how do I know when a change is complete and when to process it?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is also a valid concern. One option is to set a timer that gets reset any time the config changes, and the changes are only processed once the timer expires. With a little creativity, we can probably come up with other schemes to signal the change is complete – perhaps a special point that is sent at the end of a sequence of points.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #5: What if the data is more complex than what can be represented with a simple data type like a number or string?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can store anything you want in the point data field (JSON, Protobuf, etc.) This should provide enough flexibility for things like messages, where it probably does not make sense to separate the data into separate points.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #6: How do you deal with schema changes?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There may be instances where there are point type name changes, node topography changes, etc. In this case, each client, which provides the backend code for a node type, should be responsible for handling any schema changes. This localizes the migration logic to each client (including external clients that plug into the system at runtime) rather than requiring a central system to understand all migrations. A node may contain a version point if necessary.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #7: Do I have to represent all my data as points?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If data needs to be distributed between instances on a network, then it is very beneficial to use points. However, for local processing of data, there is nothing preventing you from using more conventional techniques, storage, etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #8: How do you store data as nodes and points? SQL databases are not designed for this.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That is an excellent question and part of our research in the Simple IoT project. We are currently using SQLite, but we are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;adr&#x2F;7-jetstream-store.html&quot;&gt;moving to NATS Jetstream&lt;&#x2F;a&gt;. Stay tuned!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #9: Will this scale to a bazillion devices?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Probably not. If you need to connect a bazillion devices, then perhaps AWS IoT or something else is a better fit. However, what we are presenting here is a flexible architecture that will scale over time to many different applications and configurations as your needs evolve and change. How do you want to scale? Think carefully about this, as scaling in one dimension sometimes limits how far you can scale in another.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #10: This will not work for data sampled at 100 bazillion samples per second.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For moderate data rates, transmitting blocks of data with every point by putting an array of data in a point data field may work. For high-rate data that flows, a custom data encoding and transport will likely be required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #11: You can’t depend on time in a computer system, so last-write-wins (LWW) is not reliable.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;True, time, like networks, is not always reliable. However, in IoT systems, most of the time, you do not have the same data being edited in multiple locations, so LWW is only used in the rare case where two human users make changes at different locations. A little clock drift is not a huge deal. You can also do things like check if two systems have similar times before you synchronize data between them, and verify a system has a valid time before writing any data. You can also require that every instance in the system has its own RTC clock and that some engineering effort is made to ensure it is reliable and reasonably accurate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #12: Why not send commands, events, changes, etc.?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sending “commands” is a common paradigm in IoT systems, but it is the siren song into complexity. How do you deal with cases where the command does not make it due to a network problem? There are valid cases for events such as orders or notifications, but in most cases, commands&#x2F;events are an unnecessary abstraction and only complicate things. A sensor is at value X. The config setting is Y. Keep things declarative. Just send the data itself, keep some amount of history, and if you want to know when something changed, look at history. Utilizing new technologies like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;adr&#x2F;7-jetstream-store.html&quot;&gt;NATs Jetstream&lt;&#x2F;a&gt; is a critical piece of this puzzle.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;🚩 Objection #13: But this is different !?!?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yup, I’ve never seen anything like it before either. But it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;When we want to advance something, we often need to simplify it first.&lt;&#x2F;strong&gt; Piling on layers of complexity will only get us so far – at times, we need to go back to ground zero and re-think things.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to specify contracts between systems, such as APIs and schemas. A more fundamental contract focuses on a more granular unit of data. Points in an IoT system are like atoms in matter. A Node tree in an IoT system is like the DNA in a living organism. The composition of points and structure of nodes (like atoms and DNA) is infinitely flexible. It is this simplicity and flexibility that allows atoms and DNA to define so many different types of matter and species of organisms. It is time to throw out the custom struct as the defined unit of data between systems and focus on something more granular, flexible, and scalable.&lt;&#x2F;p&gt;
&lt;p&gt;Want to learn more? Check out and follow the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;&quot;&gt;Simple IoT project&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Ability to Improve</title>
        <published>2024-03-05T00:00:00+00:00</published>
        <updated>2024-03-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2267/the-ability-to-improve/"/>
        <id>https://bec-systems.com/2267/the-ability-to-improve/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2267/the-ability-to-improve/">&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-6.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;em&gt;(while this article contains many general ideas, it is written from the perspective of product development.)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;If you don’t continually improve, you soon lose the ability to do so …&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This thought came after an associate described a company that is struggling to manufacture one of their products:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;They have been making a product since way back in the last century. EOL (end-of-life) is catching up with them. The circuit is really hairy analog stuff with ridiculously high precision. Pots everywhere to get it dialed in. But their voltage regulator is drifting in value significantly, whereas the old parts are rock steady.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;How do we get into situations like this, and how can they be avoided?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-few-more-examples&quot;&gt;A few more examples&lt;&#x2F;h2&gt;
&lt;p&gt;Below are a few more examples of situations that are very difficult to deal with in the lifecycle of a product:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A part becomes obsolete in a printed circuit design, and no one knows how to use the CAD system it was designed in. Rather than updating to an &lt;a href=&quot;&#x2F;1670&#x2F;reflections-on-kicad-and-eda-tools&#x2F;&quot;&gt;open&#x2F;modern CAD system&lt;&#x2F;a&gt; years ago at a relaxed pace, exorbitant efforts are now spent trying to track down a few more parts or find a replacement. When this fails, it is now a frantic crash-and-burn project to revise the design with no time for testing and verification.&lt;&#x2F;li&gt;
&lt;li&gt;A serious security problem is found in a product, but the software build system has fallen into disrepair and no one knows how to set it up, and it will not run on current operating systems.&lt;&#x2F;li&gt;
&lt;li&gt;A new Linux kernel driver is needed to support a new USB peripheral, but the kernel we are shipping is 7 years old, and the SOC&#x2F;SOM vendor has not provided any updates. Updating to the latest kernel would take months. Backporting the new driver is nearly impossible due to the many changes in the kernel and its subsystems.&lt;&#x2F;li&gt;
&lt;li&gt;Manufacturing was outsourced to another country years ago. Then COVID happened and the manufacturer shut down for an extended time. No one knows where the design files are or how to build the product to move it to another manufacturer.&lt;&#x2F;li&gt;
&lt;li&gt;The manufacturing process for a complex product has been the same for years. No one knows why things are done the way they are, but are afraid to change anything for fear that problems may crop up.&lt;&#x2F;li&gt;
&lt;li&gt;A code base has not been refactored as it grew and no tests were written. Adding new functionality is very difficult and usually causes bugs in unrelated areas, requiring an exorbitant amount of manual testing with each release.&lt;&#x2F;li&gt;
&lt;li&gt;An application does not have a cohesive architecture. Global variables and unrestrained function calls between various subsystems are common. As time goes on, the application becomes less and less stable. Fixing one bug often causes another. All developer resources are consumed in a circle of support, continuous bug fixing, and damage control.&lt;&#x2F;li&gt;
&lt;li&gt;A new customer is interested in purchasing a product, but it is missing a critical feature. The original development was contracted to an outside development firm, and there is no knowledge in-house on how to modify the software. The managers at the company are scrambling to find someone who can figure out how to make the changes needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;Technical debt&lt;&#x2F;em&gt; is another term to describe systems that are not adequately maintained – eventually, it takes so much effort just to keep things going that no time is left for improvements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;maintaining-systems&quot;&gt;Maintaining Systems&lt;&#x2F;h2&gt;
&lt;p&gt;How do you maintain the ability to react to changes, security problems, part shortages, and feature requests? How can you add value to your products over time? Maintaining systems (both hardware and software) is what keeps them malleable and flexible. If you don’t maintain stuff, then it soon becomes brittle and harder and harder to change. Modern systems are not ship-it-and-you-’re-done, but rather more similar to a living organism. If it is not maintained, it is dying.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The only way to make sure you &lt;em&gt;can&lt;&#x2F;em&gt; maintain something is to maintain it.&lt;&#x2F;strong&gt; Make it better. Replace a part with a cheaper&#x2F;better one. Improve something. Add a feature. Make it faster. Streamline and simplify manufacturing. If we don’t continually improve, then it becomes difficult to do anything without starting over. It is much easier to absorb a series of small costs over time than a large expense all at once. Small changes over time allow us to improve our processes. If we are not under pressure and something goes wrong, then we simply revert to the previous version or write tests to keep it from happening again.&lt;&#x2F;p&gt;
&lt;p&gt;This does not have to be hard, but it does require an investment in methodology and workflow. It requires a commitment to open tools, automation, and testing. It requires process – not the type that results in stifling bureaucracy but rather improves efficiency through automation and transparency.&lt;&#x2F;p&gt;
&lt;p&gt;There are several concerns related to change including return on investment (ROI), quality, and efficiency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-roi-objection&quot;&gt;The ROI Objection&lt;&#x2F;h2&gt;
&lt;p&gt;There are two financial mindsets:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;View R&amp;amp;D as a one-time capital expense where you design something, lock it down, and then try to extract as much value as possible – the “minimizing costs” mindset.&lt;&#x2F;li&gt;
&lt;li&gt;View R&amp;amp;D as an ongoing operating expense, improve things over time, and continually increase value – the “maximizing value” mindset.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first is easier to measure and forecast. Financial people like and understand this model. The second requires intuition and vision. It involves some risk. As your processes become more efficient, the value you get from an improvement begins to outweigh the costs of making the change. Over time, these improvements have a compounding effect.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;01&#x2F;image-1.png&quot; alt=&quot;&quot; style=&quot;width:680px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;It depends if you are playing the short or long-term game …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-quality-objection&quot;&gt;The Quality Objection&lt;&#x2F;h2&gt;
&lt;p&gt;Stability and Quality is always a concern with any change in a system. With changes, mistakes will be made – especially early on. When this happens, there is an opportunity to learn and proactively improve the testing and verification process for next time, or reactively place blame, lock things down even harder, and remove responsibility. When someone introduces a bug, the question should be: “Did you create a test so it does not happen again?” If no mistakes are being made, not much is likely being done. The upside of growth and improvement should far exceed the costs associated with the occasional mistakes made in the course of changes. Done right, quality should follow the same value curve as the value shown in the graph above. The key is to not get discouraged by an initial drop in quality and focus on improving the processes, not minimizing or restricting change and responsibility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-efficiency-objection&quot;&gt;The Efficiency Objection&lt;&#x2F;h2&gt;
&lt;p&gt;Efficiency is always a concern, and again there are two schools of thought:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It is more efficient if we just do things the way we’ve always done them, not risk change, and get what we can out of our investment. Change brings risk.&lt;&#x2F;li&gt;
&lt;li&gt;Efficiency can always improve, bringing lower costs and more value.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Again, the key is to be patient with the initial declines and persevere until you get to the point where efficiency is increasing and the cost and value lines cross.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-studies&quot;&gt;Case Studies&lt;&#x2F;h2&gt;
&lt;p&gt;Tesla is an interesting case study on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;insideevs.com&#x2F;news&#x2F;631485&#x2F;tesla-model-s-constant-improvements-chief-designer-says&#x2F;&quot;&gt;continuous improvement&lt;&#x2F;a&gt;. From a design and manufacturing perspective, their accomplishments are notable. There is always a better way to design or manufacture something.&lt;&#x2F;p&gt;
&lt;p&gt;Google’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sre.google&#x2F;sre-book&#x2F;postmortem-culture&quot;&gt;blameless postmortem&lt;&#x2F;a&gt; practice enables proactive improvements for the future instead of reactively placing blame for the past.&lt;&#x2F;p&gt;
&lt;p&gt;Amazon’s &lt;em&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;blogs&#x2F;enterprise-strategy&#x2F;enterprise-devops-why-you-should-run-what-you-build&#x2F;&quot;&gt;“You build it, you run it”&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; philosophy allows people who know the most about the system to improve how it is run instead of going through endless rounds with gatekeepers who don’t understand the system.&lt;&#x2F;p&gt;
&lt;p&gt;Toyota’s implementation of “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&quot;&gt;kaizen&lt;&#x2F;a&gt;” has produced &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.topspeed.com&#x2F;the-secrets-behind-toyotas-bullet-proof-reliability&#x2F;&quot;&gt;excellent results&lt;&#x2F;a&gt;. Kaizen is a concept referring to business activities that continuously improve all functions and involve all employees from the CEO to the assembly line workers.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These practices are used at large successful companies, but in concept, they are simple and can be applied at any scale.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-irony-of-kaizen&quot;&gt;The Irony of Kaizen&lt;&#x2F;h2&gt;
&lt;p&gt;We can develop products with the thought – we are going to get this perfect and then go into production. Logically it would seem that if we expect to make improvements after it is in production, then we must be starting with an inferior product with flaws. However, Toyota has proved the opposite. Even when a model is first introduced, their quality is likely better than the average in the automobile industry. Kaizen does not mean we slop something together of inferior quality, but rather we do the best we can but have the humility to realize it can always be better. Kaizen is not limited to the assembly line, but all aspects including design, prototyping, quality control, testing, etc. If all of these processes are continually getting better, then the first item produced will also be better.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;requirements-for-improvement&quot;&gt;Requirements for Improvement&lt;&#x2F;h2&gt;
&lt;p&gt;Every person and every organization is different, so there is no one-size-fits-all recipe that will always work. But there are several ingredients that are generally beneficial including:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Metrics&lt;&#x2F;li&gt;
&lt;li&gt;Testing&lt;&#x2F;li&gt;
&lt;li&gt;Openness&lt;&#x2F;li&gt;
&lt;li&gt;Simplicity&lt;&#x2F;li&gt;
&lt;li&gt;Leveraging outside improvements&lt;&#x2F;li&gt;
&lt;li&gt;Iterate faster&lt;&#x2F;li&gt;
&lt;li&gt;Owning your platform&lt;&#x2F;li&gt;
&lt;li&gt;The right people&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;metrics&quot;&gt;Metrics&lt;&#x2F;h2&gt;
&lt;p&gt;Not all change is an improvement – change for the sake of change is just churn and generally negative. You have to be able to measure something to know if things are improving or not. Improvement is very difficult without some metrics, because we are then just guessing and going off our intuition, and human intuition is often distorted by emotion, social pressures, and a host of other distractions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h2&gt;
&lt;p&gt;Testing is trendy today and many talk about it, but fewer individuals and teams have the discipline to implement testing consistently. If you are not confident enough to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;discourse-living-on-the-edge&#x2F;1222&quot;&gt;deploy new software to production after your tests pass&lt;&#x2F;a&gt; without doing some manual checking, then you possibly need better tests. Automated end-to-end and performance testing is critical. Consider the following statement about SQLite:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reliability and robustness of SQLite is achieved in part by thorough and careful testing.&lt;&#x2F;p&gt;
&lt;p&gt;As of version 3.42.0 (2023-05-16), the SQLite library consists of approximately 155.8 KSLOC of C code. (KSLOC means thousands of “Source Lines Of Code” or, in other words, lines of code excluding blank lines and comments.) By comparison, the project has 590 times as much test code and test scripts - 92053.1 KSLOC.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;testing.html&quot;&gt;https:&#x2F;&#x2F;www.sqlite.org&#x2F;testing.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Most of SQLite’s tests are not open-source. This is the real IP of SQLite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openness&quot;&gt;Openness&lt;&#x2F;h2&gt;
&lt;p&gt;Openness is another necessary ingredient for improvement. This takes many forms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Open access to tools, design files, and source code. Open-source software and tools are preferred when available.&lt;&#x2F;li&gt;
&lt;li&gt;Good documentation is available to all involved.&lt;&#x2F;li&gt;
&lt;li&gt;Work being done is in the open and can be reviewed by anyone at any time. Pull requests are created when work starts to provide visibility into work being done rather than when the work is finished. Transparency is a powerful ingredient for quality.&lt;&#x2F;li&gt;
&lt;li&gt;Metrics, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ted.com&#x2F;talks&#x2F;ricardo_semler_how_to_run_a_company_with_almost_no_rules&quot;&gt;including financial information&lt;&#x2F;a&gt; and customer feedback, are accessible to the team.&lt;&#x2F;li&gt;
&lt;li&gt;Anyone on the team to allowed and encouraged to fix or improve anything. There are no “turf battles” where only certain people are allowed to do certain things. Within practical limits, anyone can do any work, but the process (transparency and testing) ensures that substandard work will not be automatically used.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above does not mean everything is open-source to the world, but rather those involved with the product – a team, organization, company, customers, partners, etc. We can learn a lot from the success of open-source projects and their associated culture and methodologies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simplicity&quot;&gt;Simplicity&lt;&#x2F;h2&gt;
&lt;p&gt;As the complexity of systems continues to increase, we need to also be aware that humans interacting with these systems are finite – we can only handle so much complexity. Thus, efforts need to be made to simplify where possible. We often hear the phrase: “keep it simple!” But, from whose perspective? Design, Manufacturing, Users, Service, Ops, Support, Sales, Financial, CEO, etc. If we look at how much time these various groups interact with the product, we can arrange them in an inverted pyramid:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-5.png&quot; alt=&quot;&quot; style=&quot;width:571px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The &lt;em&gt;CEO&lt;&#x2F;em&gt; is only one person and hopefully, there are many &lt;em&gt;Users&lt;&#x2F;em&gt;, so if we can simplify things for the &lt;em&gt;Users&lt;&#x2F;em&gt;, that will probably provide more benefits to the product than simplifying things for the &lt;em&gt;CEO&lt;&#x2F;em&gt;. Likewise, if &lt;em&gt;Design&lt;&#x2F;em&gt; can spend a little more time making &lt;em&gt;Manufacturing&lt;&#x2F;em&gt; and &lt;em&gt;Support&lt;&#x2F;em&gt; simpler, that is probably a good investment.&lt;&#x2F;p&gt;
&lt;p&gt;Simplifying a system’s architecture often provides the biggest wins. This can take the form of common data structures, how data is structured, how data is communicated and synchronized, lifecycle management, etc. A simplification at this level has the potential to improve the entire system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;faster-iterations&quot;&gt;Faster Iterations&lt;&#x2F;h2&gt;
&lt;p&gt;The most efficient way for humans to design complex systems is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bradfordembedded.com&#x2F;2012&#x2F;03&#x2F;iterate-hardware-like-software&quot;&gt;through iteration&lt;&#x2F;a&gt;. Some call this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;platform-takes-the-pain-corecursive-podcast&#x2F;1212&#x2F;3?u=cbrake&quot;&gt;failing fast&lt;&#x2F;a&gt;. The faster you can design&#x2F;develop, test, get feedback, and repeat, the more likely you will be successful.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-large is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-1.png&quot; alt=&quot;&quot; style=&quot;width:559px;height:auto&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There is certainly a place for some up-front planning, but you don’t want to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2001&#x2F;04&#x2F;21&#x2F;dont-let-architecture-astronauts-scare-you&#x2F;&quot;&gt;get stuck there&lt;&#x2F;a&gt;. Build a minimal &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;yagni-you-aint-gonna-need-it-and-cake-models&#x2F;1217&quot;&gt;slice of your product&lt;&#x2F;a&gt; as soon as possible, even if it only has a few features. This can even be done with hardware – put down only the bare minimum parts on the PCB and build something. The rest can be added later. If it takes too long to build a PCB prototype, find ways to speed it up, or switch to another vendor. Automation and process is very important for fast iterations. CI (continuous integration) tells you quickly if your code fails tests. CD (continuous delivery) continually builds and deploys your work so that it can be tested in the complete system and evaluated by others. CAD and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-plm&#x2F;gitplm&quot;&gt;PLM automation&lt;&#x2F;a&gt; allows you to quickly package, track, and build new versions of PCBs.&lt;&#x2F;p&gt;
&lt;p&gt;A focus on iteration compensates for our many human weaknesses. It reveals our blind spots. It improves teamwork and project transparency. It helps avoid the scenario where the lone genius works for three months behind closed doors while the rest of the team is largely stalled. It ensures we are building what the customer actually needs. It encourages automation to avoid the tedium of manual testing and releases. It accelerates learning. Above all, it improves the efficiency of the entire process. It ensures we can quickly make changes and release them when needed, with confidence.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;owning-your-platform&quot;&gt;Owning Your Platform&lt;&#x2F;h2&gt;
&lt;p&gt;Owning your platform means you “own” and take responsibility for key parts of whatever it takes to build and maintain your products. It might be a printed circuit design, a build system, an application architecture, automation, infrastructure, process, etc. Owning your platform likewise is an investment for the future. It gives you more control and the ability to improve things. You are not locked into what another company provides at one snapshot in time. Certainly, there are limits to this and we cannot create an entire system from scratch so we all must use software and components that other companies create. However, we can build a system that has flexibility so that we can easily swap out one component for another. We can understand it well enough to test it. We can manage the build systems so that if something needs to be fixed or updated, we can do that. We build our device software when possible instead of relying on binary images that we can’t control. We are not afraid of developing our own automation and process software instead of relying entirely on outside vendors. Perhaps the most important thing is to own the integration points. This might include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Top-level PCB (printed circuit board) designs (we can change electronic components and submodules as needed)&lt;&#x2F;li&gt;
&lt;li&gt;Software build systems (we can add, remove, and update software components)&lt;&#x2F;li&gt;
&lt;li&gt;PLM (project lifecycle management) (we write our own or use a system that can be easily extended through programming to meet our needs)&lt;&#x2F;li&gt;
&lt;li&gt;Core application architecture (can be adapted to specifically meet our needs)&lt;&#x2F;li&gt;
&lt;li&gt;Hosting (we can run our own servers or move applications between hosting providers as needs change)&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD (can be adapted to any task&#x2F;technology)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Integration is the most difficult (but also the most valuable) part of product development, so it is tempting to outsource integration. But this often locks you into one vendor and does not give you the flexibility to scale to higher volumes or additional products, as this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;why-were-leaving-the-cloud&#x2F;697&quot;&gt;running commentary&lt;&#x2F;a&gt; illustrates.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, you can reuse parts of your platform across many products, thus compounding your efforts over time. Even if your design files and source code are open-source, owning your platform (which includes so much more than design files) is what gives you the ability to efficiently design, test, maintain, and produce something. This is the hard part. If you are moving fast, a static snapshot of your product design at any point in time is of marginal value to competitors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leveraging-outside-improvements&quot;&gt;Leveraging Outside Improvements&lt;&#x2F;h2&gt;
&lt;p&gt;Leveraging outside improvements is another important activity. This can include upgrading to a new open-source software component, designing in a new integrated circuit, etc. It is easy to get stuck in the mindset that the “old” was “better.” In some aspects of life, this may be true, but with technology, things are generally getting better. Open-source software is generally more stable as time goes on due to better testing. Newer integrated circuits are more capable and lower cost. Many products today are largely an integration of many outside technologies, many of which are &lt;a href=&quot;&#x2F;2014&#x2F;why-open-source-for-product-development&#x2F;&quot;&gt;now open-source&lt;&#x2F;a&gt;. To improve, we must continually track and integrate these improvements. Developing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;024&#x2F;&quot;&gt;using the mainline&lt;&#x2F;a&gt; (upstream) branch of open-source projects is a good strategy that companies are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.toradex.com&#x2F;blog&#x2F;upstream-first-mainline-kernel-support-is-reality&quot;&gt;increasingly adopting&lt;&#x2F;a&gt;. Knowing &lt;a href=&quot;&#x2F;2084&#x2F;the-technology-trajectory&#x2F;&quot;&gt;when to adopt&lt;&#x2F;a&gt; new technology is a key skill.&lt;&#x2F;p&gt;
&lt;p&gt;If you use an outside development firm to develop parts of your product, it is critical that you receive a deliverable that is maintainable. Several suggestions for ensuring this include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;run the project like an open-source project. All activity is transparent and is committed to Git often.&lt;&#x2F;li&gt;
&lt;li&gt;own the integration points and testing.&lt;&#x2F;li&gt;
&lt;li&gt;use small iterations when possible. This ensures you are engaged and what is being built is what you need.&lt;&#x2F;li&gt;
&lt;li&gt;use &lt;a href=&quot;&#x2F;1670&#x2F;reflections-on-kicad-and-eda-tools&#x2F;&quot;&gt;open tools&lt;&#x2F;a&gt;&#x2F;technology that everyone has easy access to where possible. Ensure that you can build or generate usable outputs from the design&#x2F;source files. Even if you don’t have the expertise to use the tools, there is a better chance you can find someone else who can.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;the-right-people&quot;&gt;The Right People&lt;&#x2F;h2&gt;
&lt;p&gt;There is a saying often used by hikers: “Leave it better than you found it.” If we are working on a section of code that does not have tests, do we write them? If a manufacturing problem is found, do we improve the process to try to prevent the problem in the future, or just write it off? Do we give more responsibility and opportunity to everyone involved to improve things, or do we let a few mistakes restrict responsibility to only a few people?&lt;&#x2F;p&gt;
&lt;p&gt;For this to all work, you have to have people with integrity – who are genuinely interested in improvement and not just gaming the metrics. You have to have people with the discipline to write tests, which goes above and beyond just getting the job done and the ticket closed.&lt;&#x2F;p&gt;
&lt;p&gt;This all applies personally too … do you want to improve how you use your time? Then measure how you spend your time and share these measurements with someone. Use one of the many tools available to help track your time. Create your own tooling and process, and then improve it. Look for better ways to do all this.&lt;&#x2F;p&gt;
&lt;p&gt;Fundamentally, people don’t usually change much, so if someone is not interested in improving themselves, they likely will not be interested in improving the organizations they are a part of and be a drag on the process. So perhaps the most fundamental thing to learn in an interview is not only past accomplishments, but also if the candidate still has that burning desire to learn and improve themselves. It is a frustrating situation when a person who is wired for improvement is part of an organization that is not, or vice-versa. Both types of people and organizations exist.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-changes-vs-large-changes&quot;&gt;Small Changes vs Large Changes&lt;&#x2F;h2&gt;
&lt;p&gt;We can make small or large changes. This might be the difference between an improvement vs. a pivot, slow and steady vs drama. The drama captures attention in the news – the new charismatic CEO brought in from the outside to shake things up. You typically don’t see great companies in the news, but you do see them in investment portfolios. In his book &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&quot;&gt;“Good to Great,”&lt;&#x2F;a&gt; Jim Collins studied several companies that produced exceptional results and concluded the following:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;We keep looking for change in the wrong places, asking the wrong questions, and making the wrong assumptions. There’s even a tendency to blame Wall Street for the “instant results” approach to change. But the companies that made the jump from good to great did so using Wall Street’s own tough metric of success: a sustained leap in their stock-market performance. Wall Street turns out to be just another myth—an excuse for not doing what really works. The data doesn’t lie.&lt;&#x2F;p&gt;
&lt;p&gt;Now picture a huge, heavy flywheel. It’s a massive, metal disk mounted horizontally on an axle. It’s about 100 feet in diameter, 10 feet thick, and it weighs about 25 tons. That flywheel is your company. Your job is to get that flywheel to move as fast as possible, because momentum—mass times velocity—is what will generate superior economic results over time.&lt;&#x2F;p&gt;
&lt;p&gt;Right now, the flywheel is at a standstill. To get it moving, you make a tremendous effort. You push with all your might, and finally you get the flywheel to inch forward. After two or three days of sustained effort, you get the flywheel to complete one entire turn. You keep pushing, and the flywheel begins to move a bit faster. It takes a lot of work, but at last the flywheel makes a second rotation. You keep pushing steadily. It makes three turns, four turns, five, six. With each turn, it moves faster, and then—at some point, you can’’t say exactly when—you break through. The momentum of the heavy wheel kicks in your favor. It spins faster and faster, with its own weight propelling it. You aren’t pushing any harder, but the flywheel is accelerating, its momentum building, its speed increasing.&lt;&#x2F;p&gt;
&lt;p&gt;This is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;. It’s what it feels like when you’re inside a company that makes the transition from good to great. Take Kroger, for example. How do you get a company with more than 50,000 people to embrace a new strategy that will eventually change every aspect of every grocery store? You don’t. At least not with one big change program.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, you put your shoulder to the flywheel. That’s what Jim Herring, the leader who initiated the transformation of Kroger, told us. He stayed away from change programs and motivational stunts. He and his team began turning the flywheel gradually, consistently—building tangible evidence that their plans made sense and would deliver results.&lt;&#x2F;p&gt;
&lt;p&gt;“We presented what we were doing in such a way that people saw our accomplishments,”Herring says. “We tried to bring our plans to successful conclusions step by step, so that the mass of people would gain confidence from the successes, not just the words.”&lt;&#x2F;p&gt;
&lt;p&gt;Think about it for one minute. Why do most overhyped change programs ultimately fail? Because they lack accountability, they fail to achieve credibility, and they have no authenticity. It’s the opposite of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;; it’s the Doom Loop.&lt;&#x2F;p&gt;
&lt;p&gt;Companies that fall into the Doom Loop genuinely want to effect change—but they lack the quiet discipline that produces the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;concepts&#x2F;the-flywheel.html&quot;&gt;Flywheel Effect&lt;&#x2F;a&gt;. Instead, they launch change programs with huge fanfare, hoping to “enlist the troops.” They start down one path, only to change direction. After years of lurching back and forth, these companies discover that they’ve failed to build any sustained momentum. Instead of turning the flywheel, they’ve fallen into a Doom Loop: Disappointing results lead to reaction without understanding, which leads to a new direction—a new leader, a new program—which leads to no momentum, which leads to disappointing results. It’s a steady, downward spiral. Those who have experienced a Doom Loop know how it drains the spirit right out of a company.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&quot;&gt;https:&#x2F;&#x2F;www.jimcollins.com&#x2F;article_topics&#x2F;articles&#x2F;good-to-great.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Change is easiest to implement and absorb if it is incremental and not a drastic overhaul. Incremental change allows you to measure, adjust, and backtrack if needed. Incremental improvements can be implemented by anyone without permission and can then be evaluated and improved by others.&lt;&#x2F;p&gt;
&lt;p&gt;It is also important to understand the difference between foundational truths&#x2F;values (things you should not quickly change) and inefficiencies that and ripe for improvement. The foundational principles of your business provide stability and need to be understood and valued.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Do you want to be able to respond quickly to unexpected opportunities or issues that come up? The solution is simple – practice doing so now. If you regularly practice on the little things that by themselves may not really be worth the time to do, several things will happen:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;you will be ready and practiced to make critical changes that will make a big difference such as fixing a critical security problem, responding to supply chain shortages, or making a change necessary to land a big sale.&lt;&#x2F;li&gt;
&lt;li&gt;the compounding effect of small improvements will eventually provide a sizable return in the future.&lt;&#x2F;li&gt;
&lt;li&gt;each small improvement is a small push on the flywheel of momentum. This adds positive energy to your organization and this momentum helps carry you through difficult times.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A culture of improvement is a long-term game. There will be some up-front pain as you develop your processes, but this is much easier than the long-term pain of accumulated technical debt which cripples your ability to do anything. You can compound the value from improvements or the cost of technical debt – take your choice.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Think Horses, not Zebras (Part 2)</title>
        <published>2024-03-01T00:00:00+00:00</published>
        <updated>2024-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2233/think-horses-not-zebras-part-2/"/>
        <id>https://bec-systems.com/2233/think-horses-not-zebras-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2233/think-horses-not-zebras-part-2/">&lt;p&gt;There is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;popular quote&lt;&#x2F;a&gt; in medical circles:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you hear hoofbeats, think of horses, not zebras. — Dr. Theodore Woodward&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I recently &lt;a href=&quot;&#x2F;2138&#x2F;think-horses-not-zebras&#x2F;&quot;&gt;posted several debugging experiences&lt;&#x2F;a&gt; where it was beneficial to examine simple scenarios before complex ones. Below are a few more …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nvme-slot-not-working&quot;&gt;NVMe slot not working&lt;&#x2F;h2&gt;
&lt;p&gt;An NVMe slot is fairly simple – it has a clock and one to four PCIe lanes. However, in a recent new hardware design, the slot was not working. We reviewed the kernel boot logs, scoped the clock signals, etc. We did notice the clock amplitude was lower than other designs (see below). The initial suspect was signal integrity as the PCIe data lines run at very high speeds, so we reviewed the routing, board stackup, impedance calculations, etc. Eventually, I compared the PCIe connector pinout to another design and it appeared that the RX and TX data signals were swapped. Sometimes RX vs TX (receive vs transmit) can be a little confusing based on which perspective the signals are referenced to (the host system or the target device). In the case of PCIe, it appears the signals are all named from the perspective of the host. After modifying to swap the RX and TX signals, the NVMe slot worked fine, even though the modification wires drastically violated signal integrity and impedance requirements. PCIe must be a fairly robust transport!&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-10.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-11.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;pcie-clock-amplitude&quot;&gt;PCIe clock amplitude&lt;&#x2F;h2&gt;
&lt;p&gt;While verifying the hardware of a design, we noticed that the PCIe clock was at a lower amplitude than the specification required:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-7.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;What we were measuring:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-8.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The Vcross was about 170mV, and the spec required it to be between 250 and 500mV. To verify our measurement technique, we measured the PCIe clock on another system and it it looked correct. The default output of the clock chip should have given us the correct amplitude. The clock chip was connected via an I2C bus, so we read back the registers to make sure they were set to the defaults. We then set the amplitude to the maximum the chip would output, and it still was not within range. Finally, we noticed the following in the datasheet:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2024&#x2F;02&#x2F;image-9.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Sure enough, we had terminations resistors for these signals on the PCB. After the resistors were removed, the clock amplitude was correct.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cellular-connection-problems&quot;&gt;Cellular connection problems&lt;&#x2F;h2&gt;
&lt;p&gt;Cellular IoT systems can be tricky to troubleshoot. They are often installed in harsh environments (rain, cold, hot, damp, caustic sewer gasses, etc.). Occasionally a modem goes bad and connections fail. In one recent case, we replaced a modem and it still would not connect. The antenna, cable, and connections were the next suspect. After spending considerable time swapping components and not making any progress, I reviewed the configuration and noticed the APN was not set. After setting the cellular APN, it worked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zephyr-nanopb-build-error&quot;&gt;Zephyr Nanopb build error&lt;&#x2F;h2&gt;
&lt;p&gt;We recently updated the version of Zephyr we were using in a project. In the process, a protobuf generation process broke and another developer found a solution – nanopb was now an optional dependency that needed to be activated. However, the build still failed in my workspace. We discussed diffing our build workspace, but in the back of my mind, I was thinking – there has to be a simple reason. While reading the documentation, it occurred to me to check the &lt;code&gt;west&lt;&#x2F;code&gt; version – sure enough, I was running 1.0 and the latest was 1.2. After updating, it worked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-can-we-learn&quot;&gt;What can we learn?&lt;&#x2F;h2&gt;
&lt;p&gt;Again, in the above cases, the initial assumptions were more complex than the actual problem. Suggestions from the &lt;a href=&quot;&#x2F;2138&#x2F;think-horses-not-zebras&#x2F;&quot;&gt;previous article&lt;&#x2F;a&gt; are relevant here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Double-check connector and component pinouts.&lt;&#x2F;li&gt;
&lt;li&gt;Compare to working designs.&lt;&#x2F;li&gt;
&lt;li&gt;Re-read the entire datasheet carefully.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additional suggestions learned from these examples include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Verify the configuration of the system is correct, never assume it is.&lt;&#x2F;li&gt;
&lt;li&gt;Make sure you have the correct version of the tools installed (ideally your build system would check this for you).&lt;&#x2F;li&gt;
&lt;li&gt;Re-read documentation for tools and software components. This will often spark ideas on where to look for problems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why Open Source for Product Development</title>
        <published>2023-12-01T00:00:00+00:00</published>
        <updated>2023-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2014/why-open-source-for-product-development/"/>
        <id>https://bec-systems.com/2014/why-open-source-for-product-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2014/why-open-source-for-product-development/">&lt;p&gt;(this topic is also discussed in a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;026&#x2F;&quot;&gt;podcast episode&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;One of the paradoxes in product development is Open Source. How can you personally or as a company benefit from participating in Open Source projects? Why should you share your great ideas and code? How can you build a business or a career by giving things away? How can an open-source project be a reliable supplier without contractual guarantees? Most successful technology companies today participate in open-source projects. Why do they do this?&lt;&#x2F;p&gt;
&lt;p&gt;Open source is difficult to fully understand and much has been said about it. There are many approaches to licensing and funding. Many question the equity and sustainability. Many get bogged down in ethical, moral, and political arguments. There are messy problems that don’t seem to have good answers. But we need to go deeper and examine the core issues of why companies are turning to open-source.&lt;&#x2F;p&gt;
&lt;p&gt;We will consider several product development perspectives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Our motivation is to produce something of &lt;strong&gt;value&lt;&#x2F;strong&gt; that society can use and benefit from.&lt;&#x2F;li&gt;
&lt;li&gt;Software technology is advancing at a rapid rate of &lt;strong&gt;change&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Technology in modern systems is increasingly &lt;strong&gt;complex&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;How can we maintain some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; over the resources we use to ensure they will meet our needs?&lt;&#x2F;li&gt;
&lt;li&gt;And how does organizational &lt;strong&gt;culture&lt;&#x2F;strong&gt; impact our ability to deal with these issues and build modern systems?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;image.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;value&quot;&gt;Value&lt;&#x2F;h2&gt;
&lt;p&gt;The value of software is hard to quantify, and breakthroughs are difficult to predict. New software algorithms, methods, languages, and structures are sometimes much more effective than previous ones. It is these non-linear breakthroughs that we must leverage. Software is an unbounded sphere of opportunity, free from the constraints of physical locality, physical devices, duplication costs, and, in many cases, computing resources. Modern computers, even those we hold in our hands, are capable of running more software than we can write in multiple lifetimes and storing a lot of information. Systems that improve human efficiency and capability potentially add value and wealth to society. The best software can do more with simpler expressions and less effort. The best software can scale to larger problems. The best software is easier to maintain and thus the rate at which value is added over the long term increases. The best software is more reliable and can be easily deployed without worrying about it crashing or malfunctioning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complexity&quot;&gt;Complexity&lt;&#x2F;h2&gt;
&lt;p&gt;We should clarify our use of the term complexity – we are talking about inherent and necessary complexity, not artificial, human-created complexity (some call this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;No_Silver_Bullet&quot;&gt;accidental complexity&lt;&#x2F;a&gt;). The human body is incredibly complex, but this is necessary for it to do all the things it does. Modern microprocessors are complex, but they need to be in order to do the amount of processing they do. The Linux kernel is complex, but only because this is required. In modern systems, software is potentially orders of magnitude more complex than hardware. We might spend X hours designing the hardware and XY hours writing and maintaining the software over the lifecycle of the product. This is hard to comprehend because the hardware can be seen, but the software is largely invisible. Software is increasingly the driver of value in modern systems, whether the systems are products or processes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;change&quot;&gt;Change&lt;&#x2F;h2&gt;
&lt;p&gt;The development of hardware versus software requires a different mindset and process. With hardware, the effort is mostly in the initial development as we design, specify, and integrate the components needed. Once designed or qualified, a hardware component can be used for 5 or 10 years with very few changes. Its value is driven by minimizing variance (change), which is how we define hardware quality. Software systems are completely different – &lt;strong&gt;the inherent value in software is that it can be changed&lt;&#x2F;strong&gt; over a product lifecycle and its value subsequently increases, so the value in software comes from maximizing (instead of minimizing) changes. Software in a product may be updated hundreds or even thousands of times over its life. This is why it is so difficult for a company that is really good at hardware to also be good at software, or vice versa – a different culture and mindset are required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control&quot;&gt;Control&lt;&#x2F;h2&gt;
&lt;p&gt;How can we secure and have some level of control over the critical software components we need to build products? First, we should clarify the scope of the problem. Modern systems are increasingly assembled from hardware and software components we did not create ourselves. In a Linux-based system, there are many millions of lines of source code. The few thousands of lines of custom application code we might write for a product, which may represent many man-years of effort, are only a drop in the bucket compared to the rest of the software running in the system. However, it is easy to ignore the “rest” of the software, as it is largely invisible. How you manage the “rest” is critically important and perhaps the hardest part. And this “rest” is increasingly being supplied by open-source projects. Many engineers are good at creating things from scratch, but fewer are good at understanding, modifying, debugging, and managing software technology that others create. This skill is increasingly valuable.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, we would create everything we need and not be dependent on anyone else. However, we won’t get very far on our own if we need to create our own microprocessors, operating systems, programming languages, databases, and the myriad of other components needed to build systems. Likewise, these components by themselves are of little value unless they are combined into a larger system to do something useful. No one person, company, or even nation can build and maintain all the technology building blocks required to build modern systems. Human success is largely dependent on the degree to which we are able to work with others. The scope of the Linux kernel is beyond even the largest companies or governments. Even if an organization had the manpower, it would likely not have the culture required to pull off a project like the Linux kernel, the PostgreSQL database, or many other useful OSS projects. For smaller organizations, the capability to build even the most basic building blocks is often beyond our reach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;culture&quot;&gt;Culture&lt;&#x2F;h2&gt;
&lt;p&gt;Thus far we have established that to create &lt;strong&gt;value&lt;&#x2F;strong&gt; with modern systems, we must be able to build &lt;strong&gt;complex&lt;&#x2F;strong&gt; systems using software technology, much of which we did not create, and be able to &lt;strong&gt;change&lt;&#x2F;strong&gt; this software over time to deliver more value. In all this, we must have some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; over this software. If there are problems, can we fix them? Can improvements be implemented and new features added? Secondly, can we influence development over time if we are not doing it ourselves? When we source software technology, there are many options, but let’s reduce it to two for the purpose of discussion:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Find a vendor with a proprietary software product. Initially, it fits our requirements – at least during the sales cycle. As changes&#x2F;fixes are needed in the future, this vendor is hired to provide these updates or we work around them.&lt;&#x2F;li&gt;
&lt;li&gt;Find an open-source software project. We may purchase support from a company supporting this project or we may make needed changes ourselves.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are no doubt times when #1 is the best solution, but increasingly #2 is being chosen. Why is this?&lt;&#x2F;p&gt;
&lt;p&gt;Let’s again review the challenges with software development:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Obtaining the software we need (&lt;strong&gt;value&lt;&#x2F;strong&gt;), as we only have the resources to write a tiny fraction of it.&lt;&#x2F;li&gt;
&lt;li&gt;Making &lt;strong&gt;changes&lt;&#x2F;strong&gt; over the product lifecycle, as this is where value is added.&lt;&#x2F;li&gt;
&lt;li&gt;Having some level of &lt;strong&gt;control&lt;&#x2F;strong&gt; and influence over the software we use.&lt;&#x2F;li&gt;
&lt;li&gt;Managing the extreme &lt;strong&gt;complexity&lt;&#x2F;strong&gt; of modern systems.&lt;&#x2F;li&gt;
&lt;li&gt;Providing an environment and finding the people where software innovation can happen (&lt;strong&gt;culture&lt;&#x2F;strong&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As we review these challenges, we start to realize that the primary benefits of open-source software are cultural. Software innovation is not created with a manufacturing-type mentality but is more art than science – a process of discovery, experimentation, collaboration, inspiration, and simplification.  Developing great algorithms and code is a creative process that cannot be easily planned or scheduled, other than allocating the resources and time to work on it. The development of software innovations is not always predictable and cannot be forced. It requires the rare combination of the right people, the right environment, the right level of collaboration, and the freedom to experiment and innovate. All these conditions rarely exist inside corporations. Companies are realizing they cannot always hire the people needed or provide the environment for the level of innovation required. So the next best thing is to support open source projects where this innovation is happening. There are two ways to do this: time and funding.&lt;&#x2F;p&gt;
&lt;p&gt;Many authors of innovative software projects are driven by the craft itself, not wealth. Funding is necessary, but they are not working on a project to become rich – there are much easier ways to make money. They are driven by the intrinsic challenge, the joy of discovery, and the reward of building something useful. The first step in making sure an open-source project will be maintained and available in the future is to ensure that the authors have the funding they need. There will never be perfect equity in that authors will receive exact compensation proportional to the value they create, but this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;world.hey.com&#x2F;dhh&#x2F;i-won-t-let-you-pay-me-for-my-open-source-d7cf4568&quot;&gt;matters little to most OSS authors&lt;&#x2F;a&gt;, and in reality, this is also the case with most developers employed by companies. Many developers are more than satisfied with earning a good living and having the freedom to work on whatever they choose. Most are generous and glad to see their work being used. However, there are cases where OSS authors do not receive funding comparable to what they could earn working elsewhere, so it would be&lt;strong&gt;wise for companies to audit all the OSS components they are dependent on and ensure that these projects are adequately funded&lt;&#x2F;strong&gt;. Contributing financially also makes it more likely the authors of the project will respond to the company’s needs, but we need to be careful that this process does not become restrictive to the point where the environment for innovation is destroyed.&lt;&#x2F;p&gt;
&lt;p&gt;Contributing time (code, documentation, support, feedback, etc.) to open-source projects is another way to help ensure a project will be useful and available to companies needing it. Contributing to the community around an open-source project is critical for the project’s health and is part of the flywheel of innovation. If someone is a valuable contributor, then they will also have some influence on the direction and priorities of the project. They will become skilled at understanding and using the project. They will also become better programmers, as they work with some of the best in the world, and are exposed to well-written software. Open source projects provide an environment for innovation that is often not possible inside a company, so having your engineers do some work in OSS projects provides them with an alternative environment to do software development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-open-source-works&quot;&gt;Why Open-Source Works&lt;&#x2F;h2&gt;
&lt;p&gt;It is somewhat of a puzzle why the open-source environment works so well for software innovation. Transparency is a powerful tool for great work. When you do things in public, you do them better. In OSS projects, there are no barriers to working with the best people in the world. Freedom is likely another ingredient. When there is the latitude to experiment, it is more likely that new and better methods will be discovered. Formal software development methodologies are good at managing more predictable efforts to solve business problems, but they seem to be of less value in OSS projects at driving innovation. Each successful OSS project is different than the previous one and is a unique combination of various factors that cannot be easily replicated.&lt;&#x2F;p&gt;
&lt;p&gt;Many people still stumble at the fact that if my company contributes to an open-source project, we are helping our competitors. This is true. However, if we don’t participate in open-source projects, we likely won’t get to where we need to go. It may no longer be optional. Open source is not like walking into a discount store and picking something off the shelf at a tremendously good deal. It is not a one-time decision where we select something and are done. It is an ongoing process of continual change and improvement. And the better we are integrated into this process, the more we can leverage and use open source. Economic opportunity is not a fixed-sized pie, where we are all competing for the largest slice. With software, the duplication costs are near zero, so this is a perfect opportunity for economic growth or an overall increase in society’s wealth. We can work to grow the size of the pie, so everyone can have a larger slice.&lt;&#x2F;p&gt;
&lt;p&gt;Often in writing, the author learns and understands things he did not know before, and this essay is no exception. **The benefits of open source are not primarily in getting stuff for free or pooling resources in a socialist sense for the greater common good, but rather in providing an environment and connecting the right people for innovation to happen.**This dynamic has happened occasionally in the past inside companies such as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;brian-kernighan-unix-c-awk-ampl-go-bell-labs-etc&#x2F;284&#x2F;7&quot;&gt;Bell Labs&lt;&#x2F;a&gt; and Lockheed Martin’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;lockheed-martin-skunkworks&#x2F;309&quot;&gt;Skunk Works&lt;&#x2F;a&gt;. But this environment is obviously difficult to replicate or more companies would do so. Even the largest and most successful technology companies, such as Google and Facebook, aggressively support and promote open source. At the time of this writing, Google employs over 27,000 engineers – why would they need open-source projects? With that number of developers, why can’t they create anything they would ever need? Google’s support for OSS projects is not an altruistic gesture, but rather a calculated business decision – they are supporting the processes and people that will produce the software technology they need. This is a long-term game that requires experience, skill, understanding, and patience. It is an example of humility, which is the source of all true greatness – the realization that there are some things I cannot do, even if I have huge financial resources. It is the realization that there are people out there who are much better at certain tasks than anyone in my company or anyone I can hire. It is the realization that my company organization is not the perfect environment for the development of needed software breakthroughs and highly refined building blocks, so we need to support projects that are. Because it is counterintuitive, many companies will not make this leap, especially those who have been successful in the past without it, or those building products that in the past did not require advanced software systems. Ironically, it is often the smaller companies that need OSS components the most that are resistant to adopting and contributing to OSS projects. However, the opportunity is available for anyone to participate, support, influence, and use the most advanced software innovations available today. And these innovations are largely happening in OSS projects. Your engineers can work with some of the most gifted developers in the world and learn skills that will greatly enhance their careers and benefit your organization. You will be plugged into an engine of innovation that produces value. You will have more control over the needed building blocks. You can be part of the process that produces the valuable software you need, rather than just a consumer.&lt;&#x2F;p&gt;
&lt;p&gt;Open-source projects are far from perfect. They are messy at times, as human efforts tend to be. Their future is not guaranteed, but nothing in this world is guaranteed. The lack of formal business contracts&#x2F;methods is perplexing to most business people. However, open source appears to be the best model we’ve discovered thus far for software innovation, and the results are amazing. Open source is the only supply chain that can deliver the needed &lt;strong&gt;value&lt;&#x2F;strong&gt;, innovate and &lt;strong&gt;change&lt;&#x2F;strong&gt;, manage the increasing &lt;strong&gt;complexity&lt;&#x2F;strong&gt;, give you some amount of &lt;strong&gt;control&lt;&#x2F;strong&gt;, and provide the &lt;strong&gt;culture&lt;&#x2F;strong&gt; necessary for innovation. Will you be a part of it?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Think Horses, not Zebras</title>
        <published>2023-09-22T00:00:00+00:00</published>
        <updated>2023-09-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2138/think-horses-not-zebras/"/>
        <id>https://bec-systems.com/2138/think-horses-not-zebras/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2138/think-horses-not-zebras/">&lt;p&gt;There is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;popular quote&lt;&#x2F;a&gt; in medical circles:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you hear hoofbeats, think of horses, not zebras. – Dr. Theodore Woodward&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;“Zebra” is the American medical slang for arriving at a surprising, often exotic, medical diagnosis when a more commonplace explanation is more likely.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; What does this have to do with product development? Like the medical profession, we often diagnose problems – we call it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Debugging&quot;&gt;debugging&lt;&#x2F;a&gt;. Below are three recent cases where I would have been helped by applying this approach a little more rigorously.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simple-iot-startup&quot;&gt;Simple IoT Startup&lt;&#x2F;h2&gt;
&lt;p&gt;I recently &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;simpleiot&#x2F;simpleiot&#x2F;issues&#x2F;598&quot;&gt;encountered a bug&lt;&#x2F;a&gt; where the compiled version of Simple IoT would not work on one of my computers. Interestingly, &lt;code&gt;go run&lt;&#x2F;code&gt; worked fine. What was the difference?&lt;&#x2F;p&gt;
&lt;p&gt;At first, it seemed that a race condition was at play – the compiled version was faster, did not have the race detector enabled, and would likely have different characteristics. SIOT is a highly concurrent application with many clients running in parallel. However, after spending some time debugging, I could not find any issues with startup, rather the NATS client in SIOT could not get data from the embedded NATS server. Again, race conditions were assumed, so I tried an external vs. embedded NATS server – no difference.&lt;&#x2F;p&gt;
&lt;p&gt;I finally observed the network traffic with Wireshark and could not observe any NATS traffic in the failing version. The NATS client was not even sending any requests. I then looked at &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; and there was no localhost entry. After adding this, everything worked properly. See &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;community.tmpdir.org&#x2F;t&#x2F;dont-use-localhost&#x2F;1137&quot;&gt;this discussion&lt;&#x2F;a&gt; for more analysis of this issue.&lt;&#x2F;p&gt;
&lt;p&gt;In this case, a race condition was the zebra and the missing entry in &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-mx8-stability&quot;&gt;i.MX8 Stability&lt;&#x2F;h2&gt;
&lt;p&gt;We recently ran into a problem with a new product that uses a Variscite &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.variscite.com&#x2F;product&#x2F;system-on-module-som&#x2F;cortex-a72&#x2F;var-som-mx8-nxp-freescale-i-mx8&#x2F;&quot;&gt;VAR-SOM-MX8&lt;&#x2F;a&gt; in a custom baseboard. The software was stable on the Variscite development baseboard, but the same SOM (System on Module) would crash in the custom hardware. The system would never crash until after the Yoe updater initramfs ran and the main rootfs was loaded. Hardware was the immediate suspect – the power supply is probably not able to handle the dynamic load when multiple cores spin up, etc. However, the power looked stable and we could not find any hardware issues. In the end, we found a missing device tree line &lt;code&gt;(&quot;fsl,imx8qm&quot;)&lt;&#x2F;code&gt; in the Linux kernel DTS file for the new design. This missing construct caused some critical kernel initialization code not to run.&lt;&#x2F;p&gt;
&lt;p&gt;In this instance, a subtle power problem was the zebra and a missing line in the DTS file was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stm32h7-usb-instability&quot;&gt;STM32H7 USB Instability&lt;&#x2F;h2&gt;
&lt;p&gt;In a recent STM32H7 design, we wanted to use a High-speed USB Phy with the STM32H7 and Zephyr. This is not supported by Zephyr yet, but with a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zephyrproject-rtos&#x2F;zephyr&#x2F;issues&#x2F;57499&quot;&gt;few hacks&lt;&#x2F;a&gt;, we got it working. We are trying to push a fair amount of data over this link (10’s Mb&#x2F;sec) so some optimization and performance work was required on both the sending and receiving end. In the mix of all this, we got a new revision of the target hardware, and at some point started seeing an increase in error rates and the target not enumerating and connecting properly to the host. With a lot of moving parts and a lot of data flowing through the system, it is sometimes hard to pinpoint the problem. In this situation, we tried to narrow the scope by testing older&#x2F;newer versions of Zephyr and comparing STM32H7 reference designs to the customer hardware. We found the reference designs performed much better. We also learned that a previous version of the custom hardware also performed like the reference designs, so it appeared there was a hardware problem with the latest custom hardware.&lt;&#x2F;p&gt;
&lt;p&gt;When something worked before, and now is experiencing high levels of communication errors, the first thought was signal integrity. On the PCB design, there is a fairly long trace from the USB Phy to the connector, so this was an obvious suspect. Although we were careful to design the PCB such that the impedance of these traces was controlled, there is always the possibility that the PCB vendor did not implement the board stack-up correctly or some other strange issue. One of the engineers analyzed the trace impedance on the old and new boards with a network analyzer. This is a fairly involved test procedure that requires cutting traces, soldering coax cable to the PCB, and a fair amount of expertise. The USB traces between the two revisions looked equivalent and the impedance measured was correct. The next suspect was the high-speed signals between the MCU and Phy – we had changed some of the length matching between the two versions, so perhaps we messed something up. In the process of looking at these signals, the following was observed when scoping the data line:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2023&#x2F;09&#x2F;image.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The data line was running at two different voltage levels. The problem ended up being the power to the VDDIO pin on the phy was floating, so the signals from the phy to the MCU were not being driven at the right voltage levels. Simply scoping all the power pins on the Phy would have found this problem in a few minutes.&lt;&#x2F;p&gt;
&lt;p&gt;In this instance, signal integrity was the zebra, and a floating power pin was the horse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-can-we-learn&quot;&gt;What can we learn?&lt;&#x2F;h2&gt;
&lt;p&gt;In all of the above cases, the initial assumptions about the cause of the problem were considerably more complex than the actual problem turned out to be.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-table&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Problem&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Zebra (complex)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Horse (simple)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;SIOT Startup&lt;&#x2F;td&gt;&lt;td&gt;Race conditions&lt;&#x2F;td&gt;&lt;td&gt;Host networking config&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;i.MX8 Stability&lt;&#x2F;td&gt;&lt;td&gt;Dynamic power supply problem&lt;&#x2F;td&gt;&lt;td&gt;Missing line in device tree file&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;SMT32H7 USB errors&lt;&#x2F;td&gt;&lt;td&gt;Signal integrity&lt;&#x2F;td&gt;&lt;td&gt;Floating Phy IO power&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Hindsight is always 20&#x2F;20, so it’s easy to say we should have solved all these problems more quickly than we did. But there is always something to be learned, and I think as humans, our minds generally go to the more exotic scenario. Part of this may be overconfidence in our ability to get the simple things right, like copying a DTS file from a reference design, or supplying power to a chip. How can we possibly mess up something so simple? So we tend to overlook the simple and obvious and jump to the obscure and exotic, which exercises our most advanced abilities and knowledge. The more experienced we are, the more likely we may be to think this way. To overcome these human tendencies, it is helpful to acknowledge first that they exist (humility), and then put in place a process for future endeavors to help guide us in our debugging efforts. Consider the following maxim:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When debugging a problem, always verify and eliminate the simple&#x2F;obvious possibilities first. Work from simple to complex.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a pragmatic approach because verifying the simple possibilities usually does not take much time, so little is lost in starting there. It may be boring or tedious, which is why we subconsciously tend to avoid these, but we can save a lot of time if we just follow this simple rule. A general process might be:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;isolate the problem as much as possible (remove unused functionality, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;write down everything you know, possibilities (all of them), and ideas of what you might try.&lt;&#x2F;li&gt;
&lt;li&gt;sort your ideas from simple to complex and work on the simple ones first.&lt;&#x2F;li&gt;
&lt;li&gt;document all tests and results.&lt;&#x2F;li&gt;
&lt;li&gt;meet as a team regularly to discuss results and brainstorm the next steps.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some specific ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;verify basic network connectivity any time a network is involved, even if on the same machine.&lt;&#x2F;li&gt;
&lt;li&gt;don’t ignore any problem in the system. Often problems are related, and solving one problem sometimes solves another.&lt;&#x2F;li&gt;
&lt;li&gt;check that all components involved have good power.&lt;&#x2F;li&gt;
&lt;li&gt;compare to a known working reference design (both operation and design).&lt;&#x2F;li&gt;
&lt;li&gt;ask for help in relevant communities.&lt;&#x2F;li&gt;
&lt;li&gt;review and verify component pin-outs.&lt;&#x2F;li&gt;
&lt;li&gt;read the datasheets of the components involved.&lt;&#x2F;li&gt;
&lt;li&gt;read the errata for components.&lt;&#x2F;li&gt;
&lt;li&gt;work backward from a known working setup.&lt;&#x2F;li&gt;
&lt;li&gt;with web apps, open the console, and look for errors.&lt;&#x2F;li&gt;
&lt;li&gt;carefully review boot and build logs and diff with logs from working systems.&lt;&#x2F;li&gt;
&lt;li&gt;narrow the scope of the problem wherever possible.&lt;&#x2F;li&gt;
&lt;li&gt;try multiple systems.&lt;&#x2F;li&gt;
&lt;li&gt;carefully review any changes between working and non-working versions. Verify the operation of any new circuits or code.&lt;&#x2F;li&gt;
&lt;li&gt;don’t keep doing the same thing and expect different results.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Debugging is an art and a part of the development of any complex system. We must realize that our intuition often fails us in these situations and, with any human weakness, we must have a process to compensate. This debugging process can turn what is often a frustrating and scattered experience into something much more enjoyable and productive. Think horses first, and then zebras!&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zebra_(medicine)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Technology Trajectory</title>
        <published>2023-01-03T00:00:00+00:00</published>
        <updated>2023-01-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2084/the-technology-trajectory/"/>
        <id>https://bec-systems.com/2084/the-technology-trajectory/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2084/the-technology-trajectory/">&lt;p&gt;&lt;em&gt;See also a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmpdir.org&#x2F;017&#x2F;&quot;&gt;podcast episode&lt;&#x2F;a&gt; where we discuss this topic.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Modern systems require the integration of technology, often from many sources. This can come in the form of processors, integrated circuits, operating systems, open-source software components, databases, messaging systems, cloud infrastructure, programming languages, build systems, frameworks, etc. All technology follows a trajectory – an example is shown below. The timeline may be short or long. Your usability threshold may be low or high, sloped right or left, etc. But the fact remains that most technology will eventually be replaced by something newer. We can debate whether or not newer is better, but the fact remains that time marches on.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;12&#x2F;image-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Why can’t we use a particular technology forever? With hardware, components may not be available. With software, we potentially have a little more control, but if we want to use a software component beyond the above cycle, then we have to commit to taking over maintenance. This means:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if there are bugs, we will fix them&lt;&#x2F;li&gt;
&lt;li&gt;if there are security problems, we will fix them&lt;&#x2F;li&gt;
&lt;li&gt;if there are build problems with new versions of compilers and other libs, we will fix them&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For complex, networked projects, this can be a significant undertaking.&lt;&#x2F;p&gt;
&lt;p&gt;But a far bigger issue is that of value. Open source software and corresponding ecosystems are continually improved over their life and value is added. If you use projects in your development that are being improved, then value is being added to your product. The rate at which value is being added correlates to the slope of the curve above.&lt;&#x2F;p&gt;
&lt;p&gt;To extract the most value from technology, it is generally best to adopt technology when the trajectory is rising and there is project momentum, not when everyone else has moved on. There are several reasons for this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the rate at which value is being added is greatest during this period. This makes what we are building better.&lt;&#x2F;li&gt;
&lt;li&gt;you have an opportunity to participate in and influence the development&lt;&#x2F;li&gt;
&lt;li&gt;you have more time to benefit from the technology&lt;&#x2F;li&gt;
&lt;li&gt;more support is available as there are more people participating in the project&lt;&#x2F;li&gt;
&lt;li&gt;in programming languages, there are more maintained 3rd party packages available&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We also need to select technologies that have a reasonably long life cycle as switching out a complex component can be a lot of work.&lt;&#x2F;p&gt;
&lt;p&gt;There are many other perspectives by which to evaluate technology – this is just one of them. Technology follows a trajectory from inception, growth, maturity, decline, and finally obsolescence. How do you know where a particular technology is on the curve? It is probably partly gut feeling, part experience, part asking others, and perhaps there are analytical ways to approach this as well (search engine ranking, etc). But the most important thing is to use this concept as a framework for objective thinking and evaluation. Effective technology selection is a long-term effort. We need to have a process. We may have to watch a project for a year or more to get a good feel for it. Most of us can’t significantly change the trajectory of most technologies, but we can choose where on the curve we will participate. Inefficiencies occur early and late on the curve. If we are always too early, we likely won’t get much done. If we are always too late, then our products will be a few steps behind everyone else’s.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go for IIoT Systems</title>
        <published>2022-12-09T00:00:00+00:00</published>
        <updated>2022-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/2048/go-for-iiot-systems/"/>
        <id>https://bec-systems.com/2048/go-for-iiot-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/2048/go-for-iiot-systems/">&lt;p&gt;As developers, we have many options for programming languages. On one hand, it is great to have choices. On the other hand, it can be a little overwhelming. Many times in life, we need to make decisions before we have the experience to know the best answer. There are many opinions as to what is best, and this article is just another one. There is no one-size-fits-all – a lot depends on your team and the task. In this article, we will examine the challenges we face in developing industrial IoT (IIoT) systems, review desirable attributes in a programming language, and discuss how Go meets these needs.&lt;&#x2F;p&gt;
&lt;p&gt;Peter Bourgon defines the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;peter.bourgon.org&#x2F;go-for-industrial-programming&#x2F;&quot;&gt;industrial programming context&lt;&#x2F;a&gt; as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;in a startup or corporate environment;&lt;&#x2F;li&gt;
&lt;li&gt;within a team where engineers come and go;&lt;&#x2F;li&gt;
&lt;li&gt;on code that outlives any single engineer; and&lt;&#x2F;li&gt;
&lt;li&gt;serving highly mutable business requirements.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Additionally, an industrial IoT system can be thought of as a system that gives users access and control of remote systems. There are many variations of this, but let’s focus on a simple case that is typically composed of the following pieces: Edge device (remote equipment, sensors, etc), Cloud, and Browser.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-1-1.png&quot; alt=&quot;&quot; style=&quot;width:412px;height:238px&quot;&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;IoT Components&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;All of these pieces must be dealt with at some level and will require some programming. The fundamental requirement of this system is networking – data must be moved between the above three instances. IIoT systems are inherently distributed systems. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fallacies_of_distributed_computing&quot;&gt;Distributed systems are hard&lt;&#x2F;a&gt;, thus the distributed problem needs to be solved well if you want to have a scalable, reliable IIoT system. It is natural to focus on the end application at the edge and add IIoT as an afterthought. However, this rarely works very well.&lt;&#x2F;p&gt;
&lt;p&gt;The context of this article is that of an average programmer working in small teams where engineers do a lot of different things. Many of us are not full-time programmers doing deep theoretical work, but find ourselves building these complex systems. Some of the challenges&#x2F;requirements we face include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;resources are constrained at the edge (CPU, Disk space, etc)&lt;&#x2F;li&gt;
&lt;li&gt;networks can be unreliable&lt;&#x2F;li&gt;
&lt;li&gt;config&#x2F;state needs to exist in multiple places (edge &amp;amp; cloud)&lt;&#x2F;li&gt;
&lt;li&gt;software updates need to be deployed to remote places (edge &amp;amp; cloud)&lt;&#x2F;li&gt;
&lt;li&gt;end-to-end (edge &amp;lt;-&amp;gt; browser) real-time response is often desired&lt;&#x2F;li&gt;
&lt;li&gt;many parallel operations are happening (collecting data, running rules, managing the system, etc)&lt;&#x2F;li&gt;
&lt;li&gt;physical access to edge systems so debugging problems can be difficult&lt;&#x2F;li&gt;
&lt;li&gt;edge systems typically use Embedded Linux, which can be a challenge to develop and maintain&lt;&#x2F;li&gt;
&lt;li&gt;IoT systems are inherently concurrent and distributed&lt;&#x2F;li&gt;
&lt;li&gt;many of us are doing this part-time, are not computer science gurus, and need pragmatic solutions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;attributes-of-go&quot;&gt;Attributes of Go&lt;&#x2F;h2&gt;
&lt;p&gt;Go has several attributes that make it a good fit for this problem:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;excellent reliability. I’ve &lt;a href=&quot;&#x2F;1625&#x2F;why-are-go-applications-so-reliable&#x2F;&quot;&gt;written about this before&lt;&#x2F;a&gt;. &lt;em&gt;(our systems are not crashing in the field)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;it is a compiled language &lt;em&gt;(reasonably fast and small)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;runtime is small, embedded, and efficient &lt;em&gt;(this means there is very little overhead to distributing the entire runtime with each binary. This makes deployment easy.)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;statically linked &lt;em&gt;(this makes it much easier to deploy updates as everything you need is embedded in one binary file)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;easy to embed assets &lt;em&gt;(again, this makes it easy to deploy in one file without containers)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;is garbage collected, so we don’t have to worry about managing memory &lt;em&gt;(we don’t have memory leaks, invalid pointers, and other problems that can cause field failures)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;typed language &lt;em&gt;(compiler catches more problems early instead of having crashes in the field)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;popular and well-supported &lt;em&gt;(will continue to improve and be around for a long time)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;excellent concurrency support &lt;em&gt;(a lot is going on in these systems, so this helps)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;popular in cloud and distributed systems &lt;em&gt;(there are plenty of stdlib features and 3rd party packages – metrics, monitoring, logging, communication, etc to help us build an IoT system)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;language is simple &lt;em&gt;(easy to learn, read, and maintain)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;tooling is excellent, compile is blazing fast, no Makefiles, etc, built-in support for profiling, and easy to cross-compile for other systems &lt;em&gt;(we spend less time messing around and more time deploying value to our customers)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Go is not the best solution in every case, but if your situation matches what is described above, it might be a good fit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-removes-a-lot-of-complexity&quot;&gt;Go removes a lot of complexity&lt;&#x2F;h2&gt;
&lt;p&gt;Cloud and edge systems typically run Linux. You may outsource parts of the cloud portion and perhaps even parts of the edge device, but you are generally responsible for the edge device. It must run 24&#x2F;7. You likely need to deploy updates, maintain security, and add functionality over the product lifecycle to meet customer needs. You will run into issues and need to be able to debug them. You can’t walk over to an edge or cloud system and press the reset button or hook up your JTAG debugger. Most embedded software in the past has been developed for MCUs (microcontrollers) and written in C&#x2F;C++. This is a fine solution for disconnected control-focused products, but a Linux MPU (microprocessor) solution provides you with more flexibility and functionality for data-focused connected devices that process&#x2F;store a lot of data and have complex user interfaces. Linux provides unparalleled support for a large number of devices, USB and networking functionality is reliable and mature, and it scales to processing and storing large amounts of data. In an MCU platform, you may write most of the software in the system. In some cases, you may use an RTOS (Real-time operating system), but even these are relatively small as resources are limited. In a Linux system, you are running millions of lines of code you did not write. We can use the iceberg analogy – the part underwater includes Linux and system libraries which you don’t see most of the time. The part you see above water is your application, which is a tiny portion of the total software in the system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-3-1.png&quot; alt=&quot;&quot; style=&quot;width:387px;height:377px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Part of the value of modern systems is the huge number of software components you can reuse in your system as there are software libraries&#x2F;packages for many tasks. Building modern systems is partly the creative combination of existing&#x2F;reusable technology and the creation of new technology (the code you write).&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-7-1.png&quot; alt=&quot;&quot; style=&quot;width:400px;height:362px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;So the question arises: &lt;strong&gt;How am I going to get up to speed on all this?&lt;&#x2F;strong&gt; One solution is to minimize the amount you need to interact with the stuff underwater. If you build applications with C++, the compiler does not give you a lot of help in linking to libraries and cross-compiling to edge system architectures. (Cross compiling is compiling native code on one architecture for another – typically developing on an x86 workstation and then running on an ARM Linux target system). Thus, you need to rely on complex build systems (CMake, Yocto, Buildroot, etc). Every time you add&#x2F;update a library&#x2F;package, you are faced with the following questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How do I integrate this library into my app build?&lt;&#x2F;li&gt;
&lt;li&gt;How do I cross-compile to my edge system?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It’s not easy, thus projects such as Yocto and Buildroot exist. All developers need to have a cross tool-chain (compiler and libraries) installed on their development computer that matches the libraries in the edge system. Deploying an application update often means deploying additional libraries, or library updates. So we add container technology to try to manage all this, which is another layer of complexity.&lt;&#x2F;p&gt;
&lt;p&gt;Some solutions (like Raspbian for the Raspberry PI) advocate developing directly on the target device to avoid the complexity of cross-compiling. This works fine for small one-off maker projects, but for the development of large industrial programs, it is a poor solution as it is like developing on a PC from the 90s. Sure, cross-compiling is easier, but everything else is much harder.&lt;&#x2F;p&gt;
&lt;p&gt;Python or Node.js may look attractive in that they are easier to program than C++ and the program is interpreted on the target device, but many of the underlying packages for these languages depend on C++ code, as interpreted languages are slow, as a result the build problem is worse because it is even more difficult to cross-compile this code in the Python and Node.js build systems. Additionally, a separate run-time is required on the edge system which is relatively large and must be kept in sync with the application.&lt;&#x2F;p&gt;
&lt;p&gt;Go sidesteps most of this because it is a mostly pure ecosystem. There are no host library dependencies in a pure Go application – everything it needs is embedded in a single binary file (typically 2-10MB compressed). The Go standard library is rich and has many needed functions. Additionally, there is a rich selection of pure Go &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;&quot;&gt;3rd party packages&lt;&#x2F;a&gt; that cover most other needs. Adding packages to a Go application is as simple as &lt;code&gt;go get some&#x2F;package&#x2F;name&lt;&#x2F;code&gt;. There are no development tool requirements other than a standard Go installation and an editor. No complex build tools are required to add 3rd party packages or to cross-compile to different target systems (macOS, Windows, Linux). It has built-in support for profiling. If it crashes, you always get a stack trace. It’s so easy, and the learning curve is small.&lt;&#x2F;p&gt;
&lt;p&gt;Many software tools today add layer upon layer to solve the problems with the underlying technology. While this helps in some cases, it often adds additional complexity. You can’t gloss over complexity – when things go wrong, you still need to understand the entire stack anyway. Abstraction has its place but can only take you so far. If there are problems in one technology layer, adding additional layers sometimes just makes it worse. Go &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;npf.io&#x2F;2014&#x2F;10&#x2F;why-everyone-hates-go&#x2F;&quot;&gt;threw everything out and started over&lt;&#x2F;a&gt;. Simplicity is the only sustainable approach to technology.&lt;&#x2F;p&gt;
&lt;p&gt;Go is a relatively new language (released in 2009), so many people have not heard of it. Learning a new language does take some time*.* Go has a small learning curve, but that is nothing compared to the learning curve of building, deploying, and maintaining C++ code in edge systems. Go allows you to quickly become productive and spend very little time fighting tools over the product lifecycle. Moving your Go application forward over time often does not require any changes to the base Linux system because they are decoupled.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-is-familiar-and-simple&quot;&gt;Go is familiar and simple&lt;&#x2F;h2&gt;
&lt;p&gt;Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;commandcenter.blogspot.com&#x2F;2012&#x2F;06&#x2F;less-is-exponentially-more.html&quot;&gt;originally developed Go&lt;&#x2F;a&gt; as a solution to the pain they were experiencing with C++, and they are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;blog&#x2F;13years&quot;&gt;still investing in it&lt;&#x2F;a&gt;. Go syntax is similar to C and was developed by some of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Go_(programming_language)&quot;&gt;same people&lt;&#x2F;a&gt; who were involved in the development of the C language and Unix back in the 1970s. Thus, it feels very familiar to those of us who have spent time developing in C, Java, C#, etc. Go eschews the complexity that has overtaken C++. Language features are added slowly and carefully. Compile errors are generally easy to understand and debug. Backward compatibility has been excellent. Since 2014, I’ve implemented several systems in Go and have not had any significant issues after updating the Go or 3rd party package versions. Go developers take API compatibility seriously, so this helps.&lt;&#x2F;p&gt;
&lt;p&gt;Go is a simple language but does not force you to do things correctly (as a language like Rust does). You can still make a concurrency mess with channels. Go has &lt;code&gt;nil&lt;&#x2F;code&gt; values, so you can still crash your program if you try to reference a &lt;code&gt;nil&lt;&#x2F;code&gt;. If you don’t check returned error values, you’ll probably run into problems. But, if you follow a few simple best practices and idioms, it works well and is a nice experience. Simple programming languages are much easier to read and maintain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-concurrency-support&quot;&gt;Go Concurrency Support&lt;&#x2F;h2&gt;
&lt;p&gt;IIoT systems have a lot going on, so you need good support for concurrency. Interpreted languages like Python and Node.js are weak in these areas. Go has excellent support for concurrency by providing channels and the &lt;code&gt;go&lt;&#x2F;code&gt; keyword as language features. This allows for running concurrent tasks and communication between them with very little overhead. Go channels are easy to misuse, so it requires a little effort and practice to learn how to use them correctly, but once understood, it is a very simple and reliable way to manage concurrency in a system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-is-an-internet-language&quot;&gt;Go is an Internet language&lt;&#x2F;h2&gt;
&lt;p&gt;While older languages like C&#x2F;C++ and Python have been excellent tools for solving programming problems in the past (and are still the best in some domains like MCU development, machine learning, etc), the problems we are solving in IIoT systems are different today in several ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we are dependent on large ecosystems of 3rd party packages to implement all the functionality we need&lt;&#x2F;li&gt;
&lt;li&gt;we need better tools for concurrency and distributed systems&lt;&#x2F;li&gt;
&lt;li&gt;we need simpler models for network programming&lt;&#x2F;li&gt;
&lt;li&gt;we need software that is easier to build and deploy&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Communication between systems is the fundamental problem IoT systems solve and Go is good at this. Go is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;drewdevault.com&#x2F;2021&#x2F;04&#x2F;02&#x2F;Go-is-a-great-language.html&quot;&gt;best-in-class for a new breed of software: an Internet programming language&lt;&#x2F;a&gt;. As evidence of this, most cloud and distributed software infrastructure is written in Go these days (Kubernetes, Docker, NATS, etc). Cloud companies that scale to thousands of systems are very sensitive to cost, thus they need efficient platforms. This efficiency in Go also benefits us at the edge where resources are constrained. An added benefit is that you can write your edge and cloud applications in the same programming language.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-go-has-no-gui-support&quot;&gt;But Go has no GUI support …&lt;&#x2F;h2&gt;
&lt;p&gt;Although there have been many excellent efforts to develop a native GUI library for Go, none of them have emerged as the standard. There is a good reason for this … &lt;strong&gt;the browser is the standard UI platform these days&lt;&#x2F;strong&gt;. Nothing else can come close to touching its capabilities. It is cross-platform, reasonably performant, and very well-supported. The browser has so many options for programming, packages, etc. The browser has built-in support for video and other forms of media and is highly optimized. Developing applications in the browser is more difficult to get started than in a C++ GUI toolkit. But there is a much richer ecosystem of packages and functionality available in the browser platform. The browser platform is stable and you are ensured of backward compatibility – it will be around and well-supported for a long time. The web platform is built on solid engineering principles that have proven to scale. Many UI technologies designed to replace the browser programming model have come and gone: Java, Macromedia Flash, and Microsoft .net – yet the standard browser programming model of HTML5 + Javascript has displaced all of these and is growing at an astounding rate. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;flutter.dev&#x2F;&quot;&gt;Google Flutter&lt;&#x2F;a&gt; is the latest attempt to displace the web platform, but it remains to be seen yet if it will be successful. Most C++ GUI toolkits are highly dependent on a single company that may be here today and gone tomorrow (look at the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Qt_(software)&quot;&gt;history of Qt&lt;&#x2F;a&gt; for an example), or licensing requirements &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=25344826&quot;&gt;may change&lt;&#x2F;a&gt; at any time – there are a lot of unknowns. Plus, with the web platform, you can view the UI remotely just as well as locally. You can also use the same UI building blocks in the cloud as in the edge device. If designed correctly, web applications also function very well on mobile devices, eliminating the need to develop separate mobile apps. With the web platform you can address all of the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;on-device LCD UI (runs a browser full screen)&lt;&#x2F;li&gt;
&lt;li&gt;remote access to the device using a browser&lt;&#x2F;li&gt;
&lt;li&gt;cloud application UI&lt;&#x2F;li&gt;
&lt;li&gt;mobile device access (browser, PWA, Cordova, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The experience of a native phone app might be slightly better than a web application on mobile devices, but how many of us can afford to develop 4 different UI applications for a product (native, web, Android, iOS) when one will do in most cases? The question is not what is possible or technically best, but what is practical with the limited resources we have.&lt;&#x2F;p&gt;
&lt;p&gt;Languages like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt; simplify front-end (web) development in many of the same ways that Go has simplified back-end development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-go-is-not-the-best-at&quot;&gt;But Go is not the best at …&lt;&#x2F;h2&gt;
&lt;p&gt;Very true – Go is not as easy as Python, as widespread as C++, as popular as Javascript, as safe as Rust, or as good at concurrency as Elixir. But, Go is almost as good as the best at everything and its tooling is much better than any other language ecosystem – especially for distributed applications that need to be deployed to remote and different architectures. It does not have any of the significant drawbacks other languages have. And especially for networked IoT systems, it is an excellent choice. The below decision matrix likely reflects my biases, but illustrates this point (green is best, red is worst):&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image size-full&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;but-what-if-i-need-to-use-c&quot;&gt;But what if I need to use C++ …&lt;&#x2F;h2&gt;
&lt;p&gt;There are certainly cases where you may need to use C++ or some other language. You may choose to implement a native UI using Qt or LVGL. Machine learning code is often written in C++. There is no reason your system needs to be written in one language – Go can be used in combination with other languages. There are several ways this can be implemented:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;call the C++ code directly from Go (CGO)&lt;&#x2F;li&gt;
&lt;li&gt;run the C++ and Go code as separate applications and communicate between them using a message bus&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Method #2 is preferred in many cases as it keeps your Go code clean, and the C++ code can be built using standard C++ build systems instead of trying to force the Go build system to build C++. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;&quot;&gt;Simple IoT&lt;&#x2F;a&gt; is one framework that is designed for exactly this scenario:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-5-1.png&quot; alt=&quot;&quot; style=&quot;width:588px;height:329px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;This architecture keeps your Go code easy to build&#x2F;develop&#x2F;deploy. Your core logic, which manages config&#x2F;state and communicates with other systems, can be written in Go. This core logic must be reliable and easy to maintain. Specialty code like machine learning models can be dedicated C++ applications. NATS is a modern message bus written in Go that is easy to embed in any Go program and is a great way to connect different applications.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter size-full is-resized&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2022&#x2F;11&#x2F;image-6-1.png&quot; alt=&quot;&quot; style=&quot;width:495px;height:297px&quot;&gt;&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;optimize-for-where-you-will-spend-most-of-your-time&quot;&gt;Optimize for where you will spend most of your time&lt;&#x2F;h2&gt;
&lt;p&gt;Linux-based IoT edge systems have plenty of memory, storage, and processing power. Thus, features are continually added over the product lifecycle, which can be 5-10 years in an industrial system. The time spent maintaining and improving a product often swamps the initial development. Therefore, it makes sense to optimize for the long term – adding features and deploying updates over the next ten years. Go makes it easy to build and deploy updates with the latest Go and package versions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;friction&quot;&gt;Friction&lt;&#x2F;h2&gt;
&lt;p&gt;Developer productivity is difficult to fully understand. We often think of the features we need in our languages&#x2F;tools. Commercial software vendors focus on features. Development methodologies are designed to increase productivity by better organizing what needs to be done. But another aspect that is easy to overlook is the amount of time we spend messing around working on stuff that does not directly add value to our product. I call this “friction.” This friction can manifest itself in unforeseen problems that are more common in complex systems: learning curves, build issues, issues with libraries&#x2F;packages, lack of flexibility, security problems, deployment problems, bugs, race conditions, stability problems, technical debt, lack of control over parts of the system, etc. Go does an excellent job of reducing friction in the development process. You focus on what needs to be done, and the rest is mostly invisible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;In this article, we explored many of the attributes of Go that make it ideal for implementing IoT systems. Go provides a modern programming ecosystem where the build tools are first class, the language is simple, and there is little friction to get things done. Go also provides features such as garbage collection and concurrency support in the language which are very helpful in IoT systems where data is distributed and a lot is going on. Go is an Internet language that is increasingly used to develop distributed systems, which includes IoT systems. It is a stable (almost boring in many respects) technology and is a great option for developers who are familiar with C&#x2F;C++ and want to expand into Embedded Linux&#x2F;IoT – the skills you have are very applicable in Go.&lt;&#x2F;p&gt;
&lt;p&gt;What is the main constraint in your projects?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Application performance?&lt;&#x2F;li&gt;
&lt;li&gt;Getting things done and shipped?&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If #1, then perhaps C++ or Rust is a good choice. If #2, then take a look at Go.&lt;&#x2F;p&gt;
&lt;p&gt;Go is not the best solution for every team&#x2F;project, but for the scenario described in this article, it has worked incredibly well. With Go, we can develop and deploy remote systems with confidence.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Layered, Event, and Data-Centric Architectures in Distributed IoT Systems</title>
        <published>2022-06-14T00:00:00+00:00</published>
        <updated>2022-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/"/>
        <id>https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1884/layered-event-and-data-centric-architectures-in-distributed-iot-systems/">&lt;p&gt;With the advent of the browser, cloud, embedded Linux systems, and networked microcontrollers, distributed systems are everywhere. There are many models for communication in distributed systems – we will look at the tradeoffs between three of them. There are many perspectives to consider – initial implementation, client libraries, maintenance, adding features now and in the future, client compute and storage requirements, network bandwidth,  data structure, etc. This article will discuss a number of these concerns and present several options.&lt;&#x2F;p&gt;
&lt;p&gt;The motivation for this discussion is synchronizing data in IoT systems where we have the following requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Data (state or configuration) can be changed anywhere, at edge devices or in the cloud, and this data needs to be synchronized seamlessly between instances. Sensors, users, rules, etc. can all change data. Some edge systems have a local display where users can modify the configuration locally as well as in the cloud. Rules can also run in the cloud or on edge devices and modify state.&lt;&#x2F;li&gt;
&lt;li&gt;Data bandwidth and allowance is limited in some IoT systems (example Cat-M modems (&amp;lt; 100kb&#x2F;s) and cellular IoT plans (&amp;lt; 50MB&#x2F;month)). Additionally, connectivity is not always reliable, and systems need to continue operating if not connected.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first is the &lt;em&gt;&lt;strong&gt;Layered&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; model. In this model, various instances talk directly to other instances. If any information needs to be shared, it is sent directly through an API (application programming interface) call using REST, CoAP, and other protocols – sometimes traveling through multiple layers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The layered, or API model’s advantage is simplicity – almost anything can connect to a REST endpoint. Most networked devices have built-in support for HTTP. Many companies provide services through REST APIs. Polling is typically used in the layered model to determine when things change, which limits the response time to the polling frequency. There are mechanisms that can be used in a layered architecture to obtain real-time response such as HTTP long polling, WebSockets, Server SIde Events (SSE), callbacks&#x2F;webhooks, CoAP subscribe&#x2F;notify, etc. However, an event bus is generally a much cleaner implementation if real-time response is needed. Firewall and security concerns can also make callbacks impractical on edge devices. If a device at the end of a layered architecture needs new information, often multiple layers need to be modified to handle this new information, which can make changes expensive.&lt;&#x2F;p&gt;
&lt;p&gt;A second model is the &lt;strong&gt;&lt;em&gt;Event&lt;&#x2F;em&gt; or &lt;em&gt;Message Bus&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; model. Implementations include NATS, MQTT, Kafka, and many others. In this model, every instance in the system is connected to a message bus. All data communication is routed through the bus. Clients can post or subscribe to topics of interest so that updates happen in real-time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some advantages of the event bus include real-time response and streaming workflows. All communication and information is on the bus, so if an instance needs to send or receive some information, it simply subscribes or publishes it. Event buses often leverage one connection to the message server so that each message does not need to establish a new connection, which can &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hivemq.com&#x2F;blog&#x2F;mqtt-vs-http-protocols-in-iot-iiot&#x2F;&quot;&gt;bring some efficiencies and reduce needed resources&lt;&#x2F;a&gt; (such as number of TCP connections). However, the event bus protocol is considerably more complicated than REST, so a message bus library is typically required to implement the client application.&lt;&#x2F;p&gt;
&lt;p&gt;The third model is the &lt;em&gt;&lt;strong&gt;Data-Centric&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; model. In this model, each client instance contains a set of data it is interested in. In the below example, the cloud system has an aggregate of all the data in a system, and the browser and edge instances are subscribed to a subset of the data they are interested in or have access to, represented by the different colored blocks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-3.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The data models the entire system, so if an action (setting an output, sending a notification, etc) is required, a bit of data is changed, and then the system takes action based on this data. The needed data is replicated to each instance in the system and is automatically synchronized in any direction when it changes.&lt;&#x2F;p&gt;
&lt;p&gt;To all you Go programmers out there, this may immediately raise a big red flag. What? Communicate by sharing common data?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don’t communicate by sharing memory; share memory by communicating.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;R. Pike&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Pike’s comment is typically used in the context of an application where multiple threads (goroutines) share data in memory, and locks are used to keep multiple threads from writing to it at the same time. This model can be hard to reason about due to race conditions. An analogous model in distributed systems may be a common database that all instances use and all config&#x2F;state is stored in this remote database. Locks may be analogous to database transactions. A common database is a good solution for many cloud based distributed systems where everything is always connected and, and this model allows data to be modified from multiple locations. However, with IoT systems, we have the following constraints that make it impractical to use a single remote database as our primary configuration&#x2F;state data store for everything in the system:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;We often don’t have the network bandwidth or data allowance (ex: LoRaWAN or Cat-M modems and low cost cellular IoT plans)&lt;&#x2F;li&gt;
&lt;li&gt;Network connections are unreliable, and edge instances need to continue working (collect data, run rules, etc.), even if the network is down.&lt;&#x2F;li&gt;
&lt;li&gt;Network latency can be long – especially with low bandwidth connections.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This leads us to a &lt;strong&gt;“local first”&lt;&#x2F;strong&gt; data model, where all configuration and state needs to be stored local to an edge device. However, this data is often viewed or edited in the cloud, so it also needs to be present there. We could craft new data structures and messages for every new bit of data and send custom messages over a REST API or event bus every time anything on either end changes. However, a simpler approach is to design a generic data model that can hold any kind of data, and then a mechanism to synchronize this generic data model. Then, adding functionality is much simpler as we can write&#x2F;read data wherever needed, and synchronization between instances happens automatically with no extra effort. However, we have to learn to work within the constraints of the data model. A new feature might involve tweaking the UI and writing some code on the edge instance. Often, nothing in the middle needs to change:&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image aligncenter&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;images&#x2F;constant-vs-varying-system-parts.png&quot; alt=&quot;Constant vs Varying parts of System&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Each instance has its own local copy of whatever data it needs. But instead of the developer needing to manually manage the synchronization of data between systems using custom messages, changes to the data are automatically synchronized in any direction.&lt;&#x2F;p&gt;
&lt;p&gt;The data-centric architecture requires more computing resources and storage to run it – typically an embedded Linux system. The below chart illustrates the trade-offs between client complexity and programming simplicity.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;inline&#x2F;1884-4.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For less capable networked devices such as microcontrollers (ex: Arduino), you may be limited to a layered approach, as HTTP may be the only supported protocol. However, as microcontrollers advance, many of them are now supporting event buses such as MQTT. The cost of a data-centric architecture is an up-front cost when building the base system. As time goes on, the incremental costs of adding features is much lower. Since adding features is typically a continuous, long term exercise, the initial cost is paid back many times over. A data-centric architecture also introduces some discipline in how data is structured, stored, and synchronized. This helps avoid the technical debt that rapidly accrues in less structured approaches.&lt;&#x2F;p&gt;
&lt;p&gt;All architectures have their place. If the application is fixed in functionality, and you only need to send a temperature reading to the cloud once per hour and this is never going to change, then a microcontroller with a layered architecture is fine. If you need to send data in both directions and real-time response is needed, then moving up to an event bus makes sense. If you have devices that have a decent amount of configuration that can be modified at the device and in the cloud, runs rules locally, and features will continually be added to the system, then a data-centric architecture is beneficial. The data-centric architecture requires a more complex system to start with, but the incremental effort to add features down the road is drastically reduced because the developer does not need to worry about the data storage&#x2F;synchronization problem. Additionally, the data model is available at each instance, so programming is simpler.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to support multiple architectures in one system. For example, in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;architecture.html&quot;&gt;Simple IoT&lt;&#x2F;a&gt; all data modifications are sent over an event bus which is the primary &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;ref&#x2F;api.html#nats&quot;&gt;programming API&lt;&#x2F;a&gt;. A client can connect to the event bus of a local or remote Simple IoT instance. If the local and remote instances are connected using an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.simpleiot.org&#x2F;docs&#x2F;user&#x2F;sync.html&quot;&gt;upstream sync connection&lt;&#x2F;a&gt;, then writes to the common data-set of either instance are automatically synchronized to the other. If a client does not want to implement a local data store, they can connect to a remote instance’s event bus. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;nats-concepts&#x2F;jetstream&quot;&gt;NATS JetStream&lt;&#x2F;a&gt; is another example of a store built on top of an event bus. Some event bus implementations like NATS allow for easy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nats.io&#x2F;nats-concepts&#x2F;core-nats&#x2F;reqreply&quot;&gt;request&#x2F;response transactions&lt;&#x2F;a&gt;, which is similar to a layered REST&#x2F;RPC type interface. Thus clients in a system like Simple IoT can range from simple HTTP clients, to mid-range event-bus clients, to advanced Linux based, data-centric clients with a local data store.&lt;&#x2F;p&gt;
&lt;p&gt;In computer science, focusing on data is typically the right approach.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I will, in fact, claim that the difference between a bad programmer and a good one is whether he considers his code or his data structures more important. Bad programmers worry about the code. Good programmers worry about data structures and their relationships.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Linus Torvalds&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Fred Brooks&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Distributed systems are no different – the focus needs to be on the data. Synchronizing data efficiently and reliably between distributed instances is a hard problem to solve, and the focus of much research and development effort today (example: the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;riffle.systems&#x2F;&quot;&gt;Riffle project&lt;&#x2F;a&gt;). This requires some up-front thought, planning, and constraints, but the payoff is simpler data models that result in systems that are more reliable and cost effective over the product life-cycle. Data-centric architectures free developers from the tedium of synchronizing data and allows focus on the application problem at hand. Data-centric architectures also provide discipline and structure around the data synchronization problem that helps avoid technical dept build-up which is a great impediment in the flow of value to end users.&lt;&#x2F;p&gt;
&lt;p&gt;Each distributed system architecture has its place, and with a correct implementation, we can support multiple architectures in one system. This gives us the option to support simple as well as advanced clients, depending on the need. However, as the cost of advanced MPUs systems running Linux such as the Raspberry PI continue to fall, deploying advanced IoT clients to the edge makes a lot of sense.&lt;&#x2F;p&gt;
&lt;p&gt;In future articles, we’ll examine in more depth the techniques used to store and synchronize data in data-centric architectures.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;em&gt;Khem Raj&lt;&#x2F;em&gt;&lt;&#x2F;em&gt;, &lt;em&gt;Bruce Stansell, Gina Brake, and Collin Brake for reading drafts of this.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Business Contracts</title>
        <published>2022-03-21T00:00:00+00:00</published>
        <updated>2022-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1563/business-contracts/"/>
        <id>https://bec-systems.com/1563/business-contracts/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1563/business-contracts/">&lt;p&gt;Business contracts are often executed when two companies work together. At the most basic level, a contract should describe a common understanding between the two parties. The contract should assist and aid the relationship. However, many contracts are written by lawyers with the primary goal of covering every legal loophole and taking every legal advantage possible for their clients. This often results in contracts that are very long, filled with legal jargon, benefiting only one party, and in general, a burden to process.&lt;&#x2F;p&gt;
&lt;p&gt;For a business relationship to be successful and sustainable, there has to be &lt;strong&gt;value&lt;&#x2F;strong&gt; for both parties and there has to be &lt;strong&gt;trust&lt;&#x2F;strong&gt;. If these two key ingredients are lacking, there is little motivation to continue the relationship.&lt;&#x2F;p&gt;
&lt;p&gt;We can look at business relationships as a positive-sum game, or a zero-sum game. A positive-sum game is where the relationship is structured as a win-win – both parties find good value in the relationship and are motivated to continue it. There is a belief that the “pie” of opportunity will grow through their combined efforts. The engagement is voluntary and not constrained by force or compulsion. Zero-sum thinking is where one party is always trying to gain the maximum advantage over the other party. This is the “fixed pie” mentality where we think the resources in business are fixed, and if anyone else gains something, it is my loss. This attitude is often found in purchasing departments where they are trying to obtain the lowest possible price for a good or service, net 60 payment terms, etc. I recall in one case a manager of a company exclaiming, as we went into a meeting with a vendor, “Let’s go beat ’em up!”&lt;&#x2F;p&gt;
&lt;p&gt;Business relationships are more complex than getting the lowest price or the greatest legal advantage. The people&#x2F;companies you want to do business with are likely already busy. They likely have plenty of opportunities. They will seek engagements with those who play the positive-sum game. If a company plays the zero-sum game, they will end up doing business with second rate companies who don’t have any other choice. They won’t get good service, and trust in the relationship will be lacking. They will be forced to hop from one vendor or customer to other. There will be few long term relationships. As Bob Metcalfe &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&quot;&gt;once wrote&lt;&#x2F;a&gt;, &lt;em&gt;“First, don’t “hire” anyone.  B people hire C people – they collect resumes and choose the person they want to honor with a job. A people recruit A people.“&lt;&#x2F;em&gt; The same applies to business relationships.&lt;&#x2F;p&gt;
&lt;p&gt;With this background, let’s examine the topic of contracts a company may present to an independent contractor or consultant providing services to the company.&lt;&#x2F;p&gt;
&lt;p&gt;Again, the best developers (the ones you want) are successful and busy. They will not mess around in business relationships where people are playing the zero-sum game. They are successful because they are trustworthy and expect the same in return. They are generous with their time and knowledge because they understand the universal law that &lt;strong&gt;the more you give, the more comes back to you.&lt;&#x2F;strong&gt; But they also expect the same in return. They are confident in their abilities and do not take measures that lock their customers into their services, but on the contrary, make themselves “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;easy to fire&lt;&#x2F;a&gt;.”&lt;&#x2F;p&gt;
&lt;p&gt;A fundamental problem with trust is that people generally don’t tell you when they don’t trust you. Actions that damage trust are likely unintentional (otherwise you would not do them), but you never get feedback on this. So, I’m giving you a hint now – an onerous contract, with one-sided indemnification clauses, damages trust. It tells the other party that “I might take advantage of you.” It implies that if bad things happen due to a product flaw, “you could be on the hook.” It sows seeds of doubt. Most often, this is likely not the thought of the company presenting the contract, and the contract language is just the result of lawyers trying to do an exceptional job of protecting their client from any possible liability. However, a contract is still a contract. If disaster strikes, the contract will be used in court by various parties trying to recoup damages. Products are often sold over a long time (5-10 years or more). Companies often change owners. Therefore, it is very important that a contract be fair and just. When a developer is presented with an onerous contract, immediately the question arises – can I trust this company? Is it worth it? Even if the project goes forward, it will be with some reserve and guard. It will not be with the wholehearted attitude that is an ingredient for success.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider indemnification phrases in a contract, we need to establish who should assume liability for a product: 1) a consultant&#x2F;contractor who is billing by the hour, or 2) the company selling the product over a span of many years? Risk should be proportional to reward. A hourly contract developer has no reward for a product’s success, other than the baseline costs of doing the development. The company selling the product is the one who will potentially reap the multiplying rewards of a successful product. Therefore, they should be the ones who bear the risk as well. It is not just to expect otherwise. In the situation where a developer is providing consulting or contracting services to a larger company developing a product, it is important that the contract clearly state that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The Company assumes sole responsibility for all testing of the Work, including but not limited to software and hardware, and also assumes sole liability for any use or misuse of the Work developed by Contractor for the Company.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An argument may be made to the developer – you are not a lawsuit target because you are not a large company with deep pockets – so just sign the contract. This may be true, but what if the consultant does grow the business to the point where there are more assets? Products live a long time – a lot can change. As mentioned before, a company can change hands. If there is a lawsuit, then anything is possible.&lt;&#x2F;p&gt;
&lt;p&gt;An individual developer has limited control of the development of a complex project and the resulting product. (We are not talking about fixed-bid turnkey product design where a larger company designs the entire product, but rather hourly development services). Typically, there is extensive involvement from other developers. The contract developer does not control how the product is manufactured, marketed, sold, supported, or even how other parts of the system are developed. In complex systems there will be bugs, and often there are time to market pressures that prevent extensive testing and verification. These are all factors that are out of the developer’s control and are choices made by the product owner. Again, this further illustrates that those who are ultimately in control of a product (the owner) should be responsible for any liability the product might bring.&lt;&#x2F;p&gt;
&lt;p&gt;This brings us to a common concern of the company – they want to be sure the product is developed to professional standards.  A contract phrase might be: &lt;em&gt;“Contractor hereby warrants that its work shall be of professional quality and performed consistent with generally accepted industry standards”&lt;&#x2F;em&gt; Who defines these standards? How will they be defined in court? The reality is that few developers have the time and resources to really do the job they want to do. Schedules are always pressing, forcing compromises. Ultimately the product owner makes the decisions concerning these trade-offs – not the developer. Time to market is critical. Therefore it is difficult for a developer to warrant any work will be at any particular industry standard – as the product owner is ultimately in control. The universal laws of reality apply: “Good-Fast-Cheap” – pick two – all three do not exist. In any product development effort, there are compromises.&lt;&#x2F;p&gt;
&lt;p&gt;There is a very practical way to handle the concern that a company’s product is being developed to their standards, and that is to encourage collaboration and openness between all developers on the project. Make sure all source code and design files are shared in Git repositories that are easily accessible to all developers – both employees and contractors. Encourage all developers to work on any part of the system needed to get their job done. Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&quot;&gt;does&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&quot;&gt;it&lt;&#x2F;a&gt; – maybe you should, too. Discourage engineering “turf” where developers feel they “own” something in the sense that no-one else should mess with it. This is essentially the process used in Open Source Software, and successful companies have adopted these practices – the results speak for themselves. If this works in a large company, is there any excuse for not doing this in a small company? Open source projects don’t have contracts that specify all contributors have to do a good job, yet open source projects contain some of the highest quality code available. Peer review and doing your work in public (even if only within a company) is a powerful motivator. Because the development is in an open environment, it is quickly evident who is going a good job and who is not. The same dynamic can happen in a company. If there is open collaboration, frequent integration, and early testing, you will soon get a good feel if developers are efficient and are generating work that is of “professional quality.” Share weekly reports with the entire team of what each developer did and how much time they spent on the project. This will produce a level of accountability among peers that will far exceed what any manager can force. If someone is spending excessive amounts of time and not getting anything done, other developers will start to question it. And you will know of problems early in the project at a time when you can do something about it, rather than after a product has been sold in quantity and some horrible defect arises that results in lawsuits. Which is the better option? To summarize:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;If a company wants to ensure quality work is being done by their developers, then they must foster a collaborative, transparent development environment where:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;All development is done in the “open” in Git repositories that the entire team has access to.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Any developer can contribute to any part of the system required to do their job.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Integration is done often.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Product testing, by the owner, is started early in the development cycle.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;No amount of contract legalese can come close to being as effective as the above.&lt;&#x2F;p&gt;
&lt;p&gt;Whether you intend it or not, your legal contracts are both a reflection and driver of your company culture, and its resulting success. They impact the people you will attract – both employees and contractors.  Do your contracts reflect a fair and generous mindset where you are willing to take responsibility for the things you should take responsibility for?  Do they turn away or create reserve in people you need the most? This is a serious issue because the best people often come through referrals. Will a developer recommend their talented and busy friends if they are required to sign uncomfortable contracts that must be negotiated to even approach an acceptable level? Any friction in this process is slowing you down. Yes, a one-sided legal contract that takes everything you can get may save you some liability in the unlikely event of a product lawsuit. But it also has the effect of introducing friction in relationships that are key to your product being completed in the first place. Which is more important? Which should have priority? In summary, a contract should:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;clearly represent the concerns of both parties&lt;&#x2F;li&gt;
&lt;li&gt;document what is expected&lt;&#x2F;li&gt;
&lt;li&gt;not be one-sided&lt;&#x2F;li&gt;
&lt;li&gt;be fair&lt;&#x2F;li&gt;
&lt;li&gt;avoid complex legal jargon as much as possible&lt;&#x2F;li&gt;
&lt;li&gt;aid, not hinder the business relationship&lt;&#x2F;li&gt;
&lt;li&gt;include provisions for how the relationship will be terminated, if needed&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ve been working as a consultant for 20 years. My most successful and longest relationships have been with companies where I have never executed a single contract. Is this a coincidence? Is it cause or effect? I don’t claim to know, but my experiences resonate with the words of Seth Godin:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A handshake deal, on the other hand, is about the future. Either side can claim loopholes or wriggle out of a commitment, but the consequence is clear—if you disappoint us, we won’t be back for more. The participant in a handshake deal is investing in the future, doing more now in exchange for the benefits that trust and delight and consistency bring going forward.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;from: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seths.blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past&#x2F;&quot;&gt;https:&#x2F;&#x2F;seths.blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Somehow an essay about contracts has morphed into a discourse on company culture, development practices, and ultimately success. This is the power of writing – it helps you connect concepts that you did not previously realize were connected. In the end, everything is connected. Your contracts, your company culture, the type of people you attract, etc. It all matters.&lt;&#x2F;p&gt;
&lt;p&gt;References:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.technologyreview.com&#x2F;s&#x2F;400489&#x2F;invention-is-a-flower-innovation-is-a-weed&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past.html&quot;&gt;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2014&#x2F;10&#x2F;handshakes-and-contracts-the-future-and-the-past.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;badsoftware.com&#x2F;contract1.htm&quot;&gt;http:&#x2F;&#x2F;badsoftware.com&#x2F;contract1.htm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&quot;&gt;https:&#x2F;&#x2F;cacm.acm.org&#x2F;magazines&#x2F;2016&#x2F;7&#x2F;204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository&#x2F;fulltext&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;@Jakeherringbone&#x2F;you-too-can-love-the-monorepo-d95d1d6fcebe&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.clearviewlegal.co.uk&#x2F;ohlawdy&#x2F;contracts-are-communication&quot;&gt;https:&#x2F;&#x2F;www.clearviewlegal.co.uk&#x2F;ohlawdy&#x2F;contracts-are-communication&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Technology</title>
        <published>2020-11-27T00:00:00+00:00</published>
        <updated>2020-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1841/technology/"/>
        <id>https://bec-systems.com/1841/technology/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1841/technology/">&lt;p&gt;The fire of information technology – will you use it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;to &lt;strong&gt;create&lt;&#x2F;strong&gt; or consume?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;comfort&lt;&#x2F;strong&gt; or torment?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;education&lt;&#x2F;strong&gt; or entertainment?&lt;&#x2F;li&gt;
&lt;li&gt;as a &lt;strong&gt;tool&lt;&#x2F;strong&gt; or weapon?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;temper&lt;&#x2F;strong&gt; or incite?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;community&lt;&#x2F;strong&gt; or faction?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;harmony&lt;&#x2F;strong&gt; or rebellion?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;encourage&lt;&#x2F;strong&gt; or discourage?&lt;&#x2F;li&gt;
&lt;li&gt;to spread &lt;strong&gt;light&lt;&#x2F;strong&gt; or darkness?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;bless&lt;&#x2F;strong&gt; or curse?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;compliment&lt;&#x2F;strong&gt; or ridicule?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;save time&lt;&#x2F;strong&gt; or waste time?&lt;&#x2F;li&gt;
&lt;li&gt;to be &lt;strong&gt;generous&lt;&#x2F;strong&gt; or selfish?&lt;&#x2F;li&gt;
&lt;li&gt;to &lt;strong&gt;heal&lt;&#x2F;strong&gt; or hurt?&lt;&#x2F;li&gt;
&lt;li&gt;to share &lt;strong&gt;ideas&lt;&#x2F;strong&gt; or focus on self?&lt;&#x2F;li&gt;
&lt;li&gt;to be &lt;strong&gt;open and direct&lt;&#x2F;strong&gt; or talk behind backs?&lt;&#x2F;li&gt;
&lt;li&gt;to focus on things we &lt;strong&gt;can do&lt;&#x2F;strong&gt; or complain about things we have no control over?&lt;&#x2F;li&gt;
&lt;li&gt;to spread &lt;strong&gt;truth&lt;&#x2F;strong&gt; or falsehoods?&lt;&#x2F;li&gt;
&lt;li&gt;to express &lt;strong&gt;thankfulness&lt;&#x2F;strong&gt; or discontent?&lt;&#x2F;li&gt;
&lt;li&gt;to preserve our &lt;strong&gt;autonomy&lt;&#x2F;strong&gt; or be manipulated and exploited by others?&lt;&#x2F;li&gt;
&lt;li&gt;for &lt;strong&gt;productive&lt;&#x2F;strong&gt; pursuits or indulgence in vanity?&lt;&#x2F;li&gt;
&lt;li&gt;to engage in &lt;strong&gt;real life&lt;&#x2F;strong&gt; or escape into some virtual universe?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Do we have integrity such that our digital communications match what we would do in person? We live on a great sea of information, and the default path is to be tossed about on the waves of unverifiable communication that wash over our society, and in the end have little to show but discontent and unhappiness. Technology is an excellent tool, but a poor friend, a useful servant, but an oppressive master. Technology is no substitute for the things that bring true joy and satisfaction in life – family, friends, giving, companionship, creativity, craftsmanship, mastery, accomplishment, nature, and faith. Like fire, information technology is only useful when used intentionally and constrained to some useful purpose. Otherwise, it will rob us of our time, relationships, humanity, skills, potential, and ultimately our soul.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adventures with a ATSAMA5D27 board</title>
        <published>2020-01-29T00:00:00+00:00</published>
        <updated>2020-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/"/>
        <id>https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1531/adventures-with-a-atsama5d27-board/">&lt;p&gt;Recently, we brought up a new PCB (printed circuit board) a customer had designed based on the Microchip &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;wwwproducts&#x2F;en&#x2F;ATSAMA5D27C-D1G&quot;&gt;ATSAMA5D27C-D1G&lt;&#x2F;a&gt; processor. We encountered several interesting challenges.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;trello-attachments.s3.amazonaws.com&#x2F;5c19724d638a035cd3906a52&#x2F;5c6cc390f02bf02ea599cc26&#x2F;309279cce3cf77b7fc5ee79ced947b20&#x2F;image.png&quot; alt=&quot;image.png&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The first issue was that the design only had serial ports (and possibly a USB Host port that could be used in device mode) for bootstrapping the system. Microchip provides a tool named SAM-BA to do this. There are two implementations of SAM-BA. The older implementation does not support this CPU. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atmelcorp&#x2F;sam-ba&quot;&gt;newer implementation&lt;&#x2F;a&gt; does support this CPU, but the documentation and examples are sparse (at least when we were using it). The standard way to use SAM-BA is to directly program the bootstrap and bootloader into SPI flash. However, this design only has eMMC flash. So we came up with a way to bootstrap at91bootstrap and u-boot over the serial port, and then load a Linux kernel with an embedded initramfs from a USB flash disk. This initramfs contains an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;meta-yoe&#x2F;tree&#x2F;master&#x2F;recipes-support&#x2F;updater&#x2F;files&#x2F;sama5d27-som1-ek-sd&quot;&gt;updater&lt;&#x2F;a&gt; that is used to program the eMMC flash. After the updater runs the first time, the system will then boot from eMMC. We developed and verified this process on a development board, and it is documented in a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atmelcorp&#x2F;sam-ba&#x2F;issues&#x2F;39&quot;&gt;Github issue&lt;&#x2F;a&gt; (&lt;em&gt;The SAM-BA team has since disabled Github issues on this repository)&lt;&#x2F;em&gt;, and as part of the Yoe Distro &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;sama5d27.md&quot;&gt;sama5d27 support&lt;&#x2F;a&gt;. Microchip has also since provided us with a procedure to program eMMC using SAM-BA, but the procedure is complex and we never had a need for it once we figured out the above method.&lt;&#x2F;p&gt;
&lt;p&gt;After receiving 10 prototypes of the new board, we learned pretty quickly that VCCBU must have voltage for the CPU to start. After that, the first board loaded u-boot and everything looked good, but things went south from there. U-boot would only load perhaps one out of twenty times. Basic checks of power supply voltage levels all looked good. The custom board used a 12MHz crystal for the main clock, where Microchip’s SOM1 module uses a 24MHz crystal. We decided to try a 24MHz crystal, and after that change, u-boot would reliably load over SAM-BA. We’re not sure why (12MHz is slower than 24MHz, so things should run better), but initializing a clock tree is complex and there is likely something that was not configured correctly in software. &lt;strong&gt;Lesson #1: Unless you want to spend a lot of time writing chip initialization software and debugging strange problems, follow a reference design as closely as possible.&lt;&#x2F;strong&gt; Working at the level of chip initialization often requires intimate knowledge of the MPU and likely the support of those who designed the chip. This is much more effort than most teams have time for and is best left to the MPU vendor.&lt;&#x2F;p&gt;
&lt;p&gt;Now that u-boot was loading reliably, we could turn our attention to the kernel. At this point, a couple boards would start the kernel, but most failed with no kernel messages after the “Starting kernel …” message on the serial console. The boards that would start the kernel would crash partway through the boot process. We started looking at power supplies and observed a 100mV sawtooth on the core power supply.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;scope_7-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The SAMA5D27 datasheet specifies a maximum of 15mV of ripple for the core supply.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;core-ripple-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The ADP5023 power supply used for the core voltage had a mode pin that can be used to force it into PWM-only mode, instead of PWS&#x2F;PWM mode. After forcing the supply into PWM-only mode, some boards would start Linux. However, there were still stability problems later in the boot cycle.&lt;&#x2F;p&gt;
&lt;p&gt;After trying many other things, we finally raised the voltage of the core supply slightly by changing one of the feedback resistors. Presto! &lt;strong&gt;Lesson #2: If a CPU has stability problems and everything else looks OK, trying raising the core voltage.&lt;&#x2F;strong&gt; The system was now stable. After communicating with Microchip, we learned that the CPU actually required a higher voltage than the documentation specified. Microchip provides a power supply that is designed to be used with the SAMA5D27 – if this supply would have been used, then we would have gotten the right voltage.&lt;&#x2F;p&gt;
&lt;p&gt;This bringup experience was harder and longer than most – especially for a board of this complexity. But, it illustrates an important point – full custom MPU design is hard – even with a part like the SAMA5D27-D1G which integrates SDRAM in the CPU package. It can require a significant amount of time. This design was done by a competent designer and was extensively reviewed, but it still contained serious problems that took weeks to resolve. In the end, we were still able to make the first PCB revision work with minor modifications. However, it is very possible that the first revision of a PCB like this might need to be scrapped and chalked up to a learning experience leading to months of project delays.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lesson #3: Use a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;System_on_module&quot;&gt;SOM&lt;&#x2F;a&gt; (System on Module) unless you have a good reason to do a full custom design, and you have the time and resources to pull it off.&lt;&#x2F;strong&gt;  You are likely &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.bradfieldcs.com&#x2F;you-are-not-google-84912cf44afb&quot;&gt;not Google or Apple&lt;&#x2F;a&gt;. Yes, you will pay slightly more for a SOM than the raw MPU system components, but the SOM cost may be offset by a lower cost baseboard. A full custom MPU design may require 8 layers and very small routing features where a baseboard for a SOM may only require 4 layers and use larger features, resulting in a less costly PCB. Additionally, a baseboard for a SOM may have a lot less parts on it, and requires less effort to set up for assembly – simpler ones can even be hand built to bypass weeks of assembly lead-time.&lt;&#x2F;p&gt;
&lt;p&gt;There are dozens of SOM vendors offering products today that fit about any price&#x2F;quality&#x2F;certification price point. Some SOMs contain pre-certified WiFi and Bluetooth radios. Others meet various mil-spec requirements. This situation today is much different than 10 years ago when there were only a few expensive SOM models available. SOM modules allow us to bring advanced technology to a problem, and implement a solution with a small team in a reasonable amount of time. Implementing a SOM based MPU design still requires a fair amount of knowledge, but the unknowns are drastically reduced, and chances of success are far better. Much of the design complexity is already handled, freeing you up to work on the value a product provides. Any time we can simplify our development effort, our chances of success are much greater.&lt;&#x2F;p&gt;
&lt;p&gt;Working with Microchip on this project was a good experience. Without their support, we would not likely have resolved the issues we faced in a timely fashion. This brings us to &lt;strong&gt;Lesson #4: When developing complex system, you are likely going to need some level of support.&lt;&#x2F;strong&gt; This may come from IC vendors, open source communities, consultants, etc. In this case, the MPU documentation was not up to date, and the chip designers were able to point out the problem. We could be critical of Microchip for this oversight, but with a 3000+ pages datasheet, this is a lot of detail, and there will be mistakes and oversights. The fact that most of the datasheet is available and accurate is a commendable accomplishment. Getting this level of documentation from some vendors is like pulling teeth. Before any of us cast the first stone, we must ask the question – is everything we do completely and accurately documented? Overall, the SAMA5D27 documentation is pretty good.&lt;&#x2F;p&gt;
&lt;p&gt;The support provided on the SAM-BA Github issues was also essential for us to figure out a way to program the device. The procedure we found for programming this system using only a serial port is relatively simple and easy to implement. Though it may violate some SDRAM refresh timing specs, in practice it works very well – and that is what matters – getting things done. It is unfortunate that Microchip has since closed the Github issues for the SAM-BA project, indicating they are not really interested in building a community around the project, but rather Github is only a way to distribute the tool that is developed in-house. As systems get more complex, Open Source communities are proving to be the only viable mechanism to develop and support all the various needs users might have. Large companies readily acknowledge this as many core technologies are now Open Source, and much effort is put into building communities around them. But, lack of Open Source vision aside, Microchip is a reliable partner – especially for smaller companies wanting to use advanced technology and needing support.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Drone for Continuous Integration</title>
        <published>2019-11-26T00:00:00+00:00</published>
        <updated>2019-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1595/drone-for-continuous-integration/"/>
        <id>https://bec-systems.com/1595/drone-for-continuous-integration/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1595/drone-for-continuous-integration/">&lt;p&gt;Recently, we have been evaluating &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuous_integration&quot;&gt;Continuous Integration&lt;&#x2F;a&gt; (CI) systems for a variety of projects (both OSS and customer). There are many OSS &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&#x2F;ci-cd-tools-comparison-jenkins-gitlab-ci-buildbot-drone-and-concourse&quot;&gt;options to chose from&lt;&#x2F;a&gt;. Because we already &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;docker.md&quot;&gt;use Docker containers for Yocto&#x2F;OE builds&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;concourse-ci.org&#x2F;&quot;&gt;Concourse&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;drone.io&#x2F;&quot;&gt;Drone&lt;&#x2F;a&gt; made the short list. Both communities seem &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discourse.drone.io&#x2F;t&#x2F;large-20-60gb-cache&#x2F;4676&#x2F;5&quot;&gt;responsive&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.concourse-ci.org&#x2F;t&#x2F;pipeline-for-yocto-bitbake-builds&#x2F;1131&#x2F;8&quot;&gt;helpful&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;figure class=&quot;aligncenter&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;11&#x2F;image-1.png&quot; alt=&quot;&quot;&gt;&lt;figcaption&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&lt;&#x2F;a&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;docs&#x2F;docker.md&quot;&gt;Building OE in a container&lt;&#x2F;a&gt; is important, so naturally Drone and Concourse seem like good options as they are focused on containers. Containers make sense for most CI tasks as they allow you to easily control the environment without getting bogged down in setting up the host. Because Concourse does not seem to easily &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.concourse-ci.org&#x2F;t&#x2F;pipeline-for-yocto-bitbake-builds&#x2F;1131&#x2F;5&quot;&gt;support bind mounting volumes&lt;&#x2F;a&gt; on the host system, we ended up implementing a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;feature-drone&#x2F;.drone.yml&quot;&gt;prototype in Drone&lt;&#x2F;a&gt;. This was improved and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&#x2F;blob&#x2F;master&#x2F;.drone.yml&quot;&gt;merged&lt;&#x2F;a&gt; into the yoedistro master. Ironically, we are not currently building in a container, as the yoedistro CI machine is a 64-core ARM system and we had some problems with the container support. Hopefully we can get containers working again at some point. Since the initial evaluation, Drone has added an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;exec-runner.docs.drone.io&#x2F;configuration&#x2F;&quot;&gt;exec runner&lt;&#x2F;a&gt;, which allows us to execute a pipeline directly on a machine without a container.&lt;&#x2F;p&gt;
&lt;p&gt;Drone is an excellent fit for most of our projects. There are more capable systems (like Concourse, Jenkins, etc), but the simplicity of Drone is a big advantage in that it will more likely be used by developers. A tool is only useful if it gets used. With Drone, a developer can simply cd to a Git workspace that has a &lt;code&gt;.drone.yml&lt;&#x2F;code&gt; file, and then run &lt;code&gt;drone exec&lt;&#x2F;code&gt; and it will run the entire pipeline locally. Because drone typically does everything in containers, this works fairly well – it does not really matter what the host system is. This is powerful because developers can test the entire pipeline on their local machine before enabling it in the drone server&#x2F;agents for automated testing&#x2F;deployment. If there are problems, they can be debugged locally rather than the tedious process of commit, run the pipeline on the server, view the logs, repeat. Solutions that are simple to use make a big difference in productivity.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a quote from a Drone user:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Today we have over 60 engineers interacting with Drone daily, and they really like it, due to its simplicity. We’ve always had a small DevOps team, so we tend to heavily favor solutions that don’t require a lot of maintenance overhead, and Drone fit the bill. Since most developers have at least a basic understanding of Docker, they hardly need any help maintaining their pipelines, and there have been a couple of instances of developers creating their own plugins! This way our team can focus on exciting upgrades to our infrastructure, even as teams regularly update their deployment pipelines and new projects are created every month.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.drone.io&#x2F;why-quinto-andar-chose-drone&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.drone.io&#x2F;why-quinto-andar-chose-drone&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Drone makes some interesting trade-offs in that it trades some flexibility for simplicity and developer ease of use. Initially, Concourse was my first choice as it is a more powerful tool, but because it does not support bind mounting host volumes or exec runners, we ended up using Drone. This tool makes sense for many teams because it is more likely to be used by the average developer without having a dedicated CI&#x2F;Operations team.&lt;&#x2F;p&gt;
&lt;p&gt;This is a trend we are seeing at successful companies where developers are more responsible for everything related to their project, including testing, continuous integration, deployment, and operations. The quote below gives us some insight into how things are done at Amazon:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is another lesson here: Giving developers operational responsibilities has greatly enhanced the quality of the services, both from a customer and a technology point of view. The traditional model is that you take your software to the wall that separates development and operations, and throw it over and then forget about it. Not at Amazon. You build it, you run it. This brings developers into contact with the day-to-day operation of their software. It also brings them into day-to-day contact with the customer. This customer feedback loop is essential for improving the quality of the service.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;— Werner Vogels (CTO @ Amazon)&lt;&#x2F;strong&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;queue.acm.org&#x2F;detail.cfm?id=1142065&quot;&gt;https:&#x2F;&#x2F;queue.acm.org&#x2F;detail.cfm?id=1142065&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Drone fits into this model well because it enables developers to become engaged in CI and deployment.&lt;&#x2F;p&gt;
&lt;p&gt;One potential problem with drone is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discourse.drone.io&#x2F;t&#x2F;assembla-git-support&#x2F;4694&quot;&gt;lack of support&lt;&#x2F;a&gt; for some Git systems like Assembla. One workaround would be to store pipelines in Github&#x2F;Gitlab&#x2F;Gitea, etc, and then fetch code from other repos. But it would quickly make sense to add auth&#x2F;webhook support for whatever Git system is used if it does not already exist.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reflections on KiCad and EDA Tools</title>
        <published>2019-11-12T00:00:00+00:00</published>
        <updated>2019-11-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/"/>
        <id>https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1670/reflections-on-kicad-and-eda-tools/">&lt;p&gt;A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.snapeda.com&#x2F;2019&#x2F;10&#x2F;28&#x2F;an-interview-with-wayne-stambaugh-of-kicad&#x2F;&quot;&gt;recent interview&lt;&#x2F;a&gt; with a KiCad developer prompted some reflection on KiCad and EDA (electronic design automation) tools in general. Below are samples of several PCB (printed circuit board) designs, created with KiCAD, and implemented as part of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;simpleiot.org&#x2F;&quot;&gt;SimpleIoT project&lt;&#x2F;a&gt; in the last couple months.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-6.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;The experience has been excellent. Above all, the tool is very fast, efficient to use, and stable. Schematic and PCB integration works well enough, and routing and copper pours are easy. Switching between inches and millimeters can be done on the fly. The KiCad library has many parts in it, and other organizations, such as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Digi-Key&#x2F;digikey-kicad-library&quot;&gt;DigiKey&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Seeed-Studio&#x2F;OPL_Kicad_Library&quot;&gt;Seeed&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.snapeda.com&#x2F;&quot;&gt;SnapEDA&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ultralibrarian.com&#x2F;&quot;&gt;Ultra Librarian&lt;&#x2F;a&gt; are also providing libraries. If a KiCad symbol&#x2F;footprint for a part is not already available, it is relatively easy to create new symbols and footprints as needed. There is a good KiCad &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;forum.kicad.info&#x2F;&quot;&gt;support forum&lt;&#x2F;a&gt;. KiCad is a pleasure to use and production-ready for standard PCB designs.&lt;&#x2F;p&gt;
&lt;p&gt;Choosing an EDA tool is an investment. There are several aspects to consider:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;purchase&#x2F;licensing cost of the tool&lt;&#x2F;li&gt;
&lt;li&gt;time invested in learning the tool&lt;&#x2F;li&gt;
&lt;li&gt;time spent implementing designs&lt;&#x2F;li&gt;
&lt;li&gt;time spent maintaining designs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;#2, #3, and #4 swamp #1 for many projects – at least when low end EDA tools are used. Thus we want to be confident that the tool we choose will be around for a while and will be well maintained. With all the churn in the EDA industry in the last 10 years, it is hard to have a lot of confidence in the long term prospects of many tools. For KiCad, however, the development statistics indicate that momentum around the project is increasing and that this tool will likely be around for awhile.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;image-5-1.png&quot; alt=&quot;&quot;&gt;&lt;figcaption&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;KiCad&#x2F;kicad-source-mirror&#x2F;graphs&#x2F;contributors&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;KiCad&#x2F;kicad-source-mirror&#x2F;graphs&#x2F;contributors&lt;&#x2F;a&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;With 183 contributors, the KiCad project appears to be healthy – it is doing something right.&lt;&#x2F;p&gt;
&lt;p&gt;Some may fear that open source projects (like KiCad) are taking away the opportunity for companies to make money and are not sustainable. Has the advent of Linux decreased the amount of money being spent on operating systems? On the contrary, Linux has greatly increased the operating system ecosystem – much more so than if proprietary Unix were the only option. Redhat, Ubuntu, and many other companies seem to be doing well. Linux is used in everything from watches to supercomputers. Unix would never have enabled this breadth of products – it is simply too large a task for any one company or team. Collaboration is the only way to accomplish a project of this magnitude. When the commodity layers are taken care of, then people are free to work on higher level problems. If a commercial EDA tool does about what KiCad does, that product is likely not going to fare well long term. But there is plenty of space to add value higher up the stack. Examples might include tools that work with KiCad such as auto routers, advanced placement tools, library management tools, RF design, SI&#x2F;EMC simulation, high voltage design rules, etc. There is endless opportunity. The “pie” of opportunity is not fixed – it can grow. Contribute code to KiCad that will enable proprietary tools to run in tandem. If companies build on top of KiCad, then they will not have to duplicate the task of building a basic schematic and PCB layout editor and can instead focus on other features, and as a result, there will overall be more value for society. Companies will already have a large market of people who are more likely to spend incremental amounts of money to add functionality as needed. The alternative is for every company to try to provide the entire EDA stack, which can be a tough sell, as it is expensive and customers will need to change everything they are currently doing. There is no reason EDA software cannot become modular like the software development ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;KiCad may displace a few commercial EDA products, but the value and opportunity KiCad will help create will far outweigh this loss. More companies will build more stuff, with less friction and effort. There will be more innovation. More problems will be solved (and likely a few created). There will be more collaboration. Even now, it is practical for developers, who only design PCBs occasionally, to use production grade tools.&lt;&#x2F;p&gt;
&lt;p&gt;EDA tools should not be evaluated merely on technical features and price, but also on the hassle factor, the capability to facilitate collaboration, and the ease of long term product maintenance. Who will maintain your product in two years when a part goes obsolete, the design needs tweaked, and the designer and the obscure tool used on the original design is long gone? If you contract out a PCB design, why not require that the design be implemented using a tool that anyone can use in the future? Part of the value of a product is its maintainability. Companies who can quickly adapt as things change will have an edge. The costs of not being able to quickly respond to some product need, or of having to learn new tools and re-implement a design are significant. Over the life of some products, maintenance costs may be much larger than the initial development costs.&lt;&#x2F;p&gt;
&lt;p&gt;In years past, I’ve used a number of different PCB design tools (Mentor Board Station, OrCad, P-Cad, gEDA, Eagle, etc). Some have been good experiences, others not so much. While there are no doubt EDA tools that have more features and are better than KiCad in some ways, KiCad is the low friction solution for your standard PCB design. It can be used easily by any one at any time on any computer. This flexibility is a big part of KiCad’s value. EDA tools are the “build system” for your hardware. They work best if they are open and easy to use by anyone on the team. There are many “free” PCB design tools available, but few of these are open. Some are cloud based, are very convenient to use, and technically a marvel that we can run a PCB design tool in a browser..  But the design is still locked up in a proprietary format. It is not easy to customize or extend these tools. And the sheer number of these commercial options available today suggests that long term they probably won’t all be around. “Open” is more important than “Free” in my opinion – especially for the long term.&lt;&#x2F;p&gt;
&lt;p&gt;KiCad is certainly a noteworthy project in the technology landscape, and deserves consideration. The availability of such a tool will change the world. The open source hardware movement will grow. Companies who learn to leverage this movement will benefit in the same way that most companies now benefit from the use of open source software. More wealth will be created for society. The traditional barriers between hardware engineers, software developers, and PCB designers will be reduced. Just as hardware engineers have had access to about any software development tool they want to use, now software developers have access to tools to develop and tweak hardware. The small amount of time required to learn KiCad is a worthwhile investment.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Humble Programmer</title>
        <published>2019-10-31T00:00:00+00:00</published>
        <updated>2019-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1646/the-humble-programmer/"/>
        <id>https://bec-systems.com/1646/the-humble-programmer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1646/the-humble-programmer/">&lt;p&gt;In 1972, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Edsger_W._Dijkstra&quot;&gt;Edsger W. Dijkstra&lt;&#x2F;a&gt; published a paper titled &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;~EWD&#x2F;transcriptions&#x2F;EWD03xx&#x2F;EWD340.html&quot;&gt;&lt;em&gt;The Humble Programmer&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. Dijkstra was trained in math and physics and was a university professor for much of his life. This paper is an interesting reflection on the history of computers and contains thoughts for the future. A few quotes are included below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result the programming process will become cheaper. If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with. In other words: both goals point to the same change.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;To put it in another way: as long as machines were the largest item on the budget, the programming profession could get away with its clumsy techniques, but that umbrella will fold rapidly.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Another lesson we should have learned from the recent past is that the development of “richer” or “more powerful” programming languages was a mistake in the sense that these baroque monstrosities, these conglomerations of idiosyncrasies, are really unmanageable, both mechanically and mentally. I see a great future for very systematic and very modest programming languages.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;The best way to learn to live with our limitations is to know them. By the time that we are sufficiently modest to try factored solutions only, because the other efforts escape our intellectual grip, we shall do our utmost best to avoid all those interfaces impairing our ability to factor the system in a helpful way.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Dijkstra was 42 years old when we wrote &lt;em&gt;The Humble Programmer&lt;&#x2F;em&gt;. At a similar age of 47 years, I too have come to appreciate the value of simple programming languages and a careful approach to writing software. Two modern languages that embody some of these principles are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;elm-lang.org&#x2F;&quot;&gt;Elm&lt;&#x2F;a&gt;. While on the surface these languages may seem very different (one is procedural and one is functional), the values of the languages are similar. Both are designed with a great respect for the finite capability of the human brain. Both strive for simplicity first, and features are only added to the language after careful consideration. Both have excellent tooling that helps ensure consistency and correctness. Both are not just a syntax, but rather a culture and mindset. Experience on recent projects indicates that Go and Elm are effective languages, especially when I compare to previous experiences on C++&#x2F;Javascript projects. There are rarely run-time exceptions. Compiler errors are relatively easy to understand and fix. Tooling is simple and almost invisible. Program maintenance and refactoring is enjoyable.  The combined cognitive load of the language and the tooling is small freeing up resources for solving the problem at hand.&lt;&#x2F;p&gt;
&lt;p&gt;Today, there is a huge amount of churn in the software development world. Especially in front-end development, new frameworks are being released at an astounding rate. Many have their place, and perhaps each addresses some need. But it seems there is something fundamentally wrong with so many solutions for the same problems. Thus, it is encouraging to see new approaches where the authors have carefully studied the past, tried to learn from everything that has been done, and have created solutions where simplicity is valued. This is key to developer effectiveness, and really to life in general.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why are Go applications so reliable?</title>
        <published>2019-10-10T00:00:00+00:00</published>
        <updated>2019-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1625/why-are-go-applications-so-reliable/"/>
        <id>https://bec-systems.com/1625/why-are-go-applications-so-reliable/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1625/why-are-go-applications-so-reliable/">&lt;p&gt;Go does a lot of things well (good performance, easy to learn, very productive, extensive stdlib, excellent tooling, etc), but after programming with Go for three years (both embedded Linux and cloud applications), stability is the characteristic that really stands out.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;10&#x2F;go-reliability-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In the past, I’ve observed the development of several fairly large C++ applications. Stability problems were more common than they should have been. Memory leaks, null pointers, crashes, etc. On one project (over 500,000 &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Source_lines_of_code&quot;&gt;SLOC&lt;&#x2F;a&gt;) we built elaborate mechanisms to capture core dumps when things crashed, at times needed to run Gdb on the target system, and spent a fair amount of time in Valgrind tracking down memory leaks. The worst problems were the rare, intermittent ones which only happened in the field and were very difficult to instrument. It is possible to write reliable C&#x2F;C++ code (one example is the Linux kernel), but it takes focused effort (code review, testing, coding standards, etc).  My experience with Javascript has been similar. What if there was a programming language where basic program stability did not have to be a primary concern?&lt;&#x2F;p&gt;
&lt;p&gt;I’ve now participated in four decent-sized Go projects and stability problems are a thing of the past. I only recall one memory leak. Crashes are rare. Several attributes of Go contribute to this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The pattern for returning multiple variables (including error) and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@matryer&#x2F;line-of-sight-in-code-186dd7cdea88&quot;&gt;aligning the happy path to the left&lt;&#x2F;a&gt; encourages error checking before doing anything with the data a function returns. Therefore you don’t end up trying to do things with nil variables. It is a little verbose, but it works and is a small price to pay for the problems it solves.&lt;&#x2F;li&gt;
&lt;li&gt;Garbage collection takes care of memory leaks.&lt;&#x2F;li&gt;
&lt;li&gt;The language encourages simplicity, and simple things are generally more reliable.&lt;&#x2F;li&gt;
&lt;li&gt;The type system catches many errors during compile time.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I’m sure there are others, but these are the ones that stand out to me. Go strikes a nice balance between safety and simplicity. There are safer languages (Rust, Haskell, etc), but they require more effort to learn, and probably require more coding effort (I don’t have a lot of experience, so I could be wrong about this). Every tool has its use and place. If I was developing an application on a space craft going to Mars, I’d probably use Rust. If I am writing a quick script to process some test data, I typically use Python. When writing MCU code, I still use C&#x2F;C++, but someday may use Rust. But when I’m writing a reasonably complex cloud or edge (embedded Linux) application, I use Go. In Go, you can get things done quickly, and be reasonably confident that the application you deploy will not crash or leak memory.&lt;&#x2F;p&gt;
&lt;p&gt;Go’s type system and simplicity require a little more typing than Python, but likely less effort than more complex languages like Rust or Haskell. Go is a pragmatic language that gets you 98% there without a lot of overhead. In business, you generally don’t want to add a lot of process overhead on the entire company for the 2% of people who may be causing problems, as it imposes drag on the other 98% trying to get things done. Rather, it makes sense to address the 2% at a personal level. Likewise, with Go, the 2% of the time you have to fix a nil bug, or a unhandled case the type system did not catch, is acceptable as 98% of the time you are working in a language that is very productive with very little overhead. Go is ideal for many applications.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Auto-formatting&#x2F;linting Go code</title>
        <published>2019-04-22T00:00:00+00:00</published>
        <updated>2019-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1581/auto-formatting-linting-go-code/"/>
        <id>https://bec-systems.com/1581/auto-formatting-linting-go-code/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1581/auto-formatting-linting-go-code/">&lt;p&gt;Some things in life you just have to experience to truly appreciate the value. One of these is auto-formatting&#x2F;linting source code. When I started programming in Go in Vim, I naturally looked for editor support, and found the excellent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fatih&#x2F;vim-go&quot;&gt;vim-go&lt;&#x2F;a&gt; project. Through this, I learned about &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;cmd&#x2F;gofmt&#x2F;&quot;&gt;gofmt&lt;&#x2F;a&gt;and then &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;godoc.org&#x2F;golang.org&#x2F;x&#x2F;tools&#x2F;cmd&#x2F;goimports&quot;&gt;goimports&lt;&#x2F;a&gt;. These tools can be configured in your editor to automatically format your code when you save. goimports goes a step beyond and adds missing imports and removes unused ones.&lt;&#x2F;p&gt;
&lt;p&gt;Auto-formatting is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@ryconoclast&#x2F;why-you-should-use-a-code-formatter-4f02dd40db14&quot;&gt;quickly&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@jtomaszewski&#x2F;keep-your-code-clean-forever-65c71f7f2df&quot;&gt;becoming&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;why-robots-should-format-our-code-159fd06d17f7&quot;&gt;the&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a&quot;&gt;norm&lt;&#x2F;a&gt;. The Javascript world also has an excellent formatter available named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;prettier.io&#x2F;&quot;&gt;Prettier&lt;&#x2F;a&gt;. There are formatters for many other languages as well including &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;clang.llvm.org&#x2F;docs&#x2F;ClangFormat.html&quot;&gt;C&#x2F;C++&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mvdan&#x2F;sh&quot;&gt;shell&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;avh4&#x2F;elm-format&quot;&gt;Elm&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rustfmt&quot;&gt;Rust&lt;&#x2F;a&gt;, etc. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sbdchd&#x2F;neoformat&quot;&gt;neoformat&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;w0rp&#x2F;ale&quot;&gt;ALE&lt;&#x2F;a&gt; plugins add auto-formatting functionality to Vim&#x2F;Neovim. An example of how to enable these plugins in Neovim is included in my &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;dotfiles&#x2F;blob&#x2F;master&#x2F;nvim&#x2F;.config&#x2F;nvim&#x2F;init.vim&quot;&gt;dotfiles&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below are instructions on how to set up &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;&quot;&gt;Visual Studio Code&lt;&#x2F;a&gt; to auto-format code. Even though I use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;neovim.io&#x2F;&quot;&gt;Neovim&lt;&#x2F;a&gt; for most of my code editing, I still try out VS code and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;idea&#x2F;&quot;&gt;IntelliJ IDEA&lt;&#x2F;a&gt; from time to time to learn what’s new in cutting-edge editors. I also recommend VS Code for most new Go developers – especially those coming from embedded systems development where an IDE is traditionally used. Give it a try – it will only take you a few minutes.&lt;&#x2F;p&gt;
&lt;p&gt;The instructions below should work with most systems (Windows, Linux,  Mac). First, make sure Go and VS code are installed. Then install the Go VS code extension.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-1-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Next, type Ctrl-Shift-P to bring up the command palette and run Go:  Install&#x2F;Update Tools.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-2-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;This will display a list of tools – select them all.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-3-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Next, configure VS Code to format on save. Open the settings by selecting File-&amp;gt;Preferences-&amp;gt;Settings from the menu. Select the “Format on Save” option and set the timeout to something larger than the default, like 5000ms.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-4-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Last, select goimports as the code formatting tool – this will automatically manage the imports in your file, as well as formatting the code.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;04&#x2F;vscode-go-5-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Now, open a Go source file. Mess up the formatting of some code and then save – the code should be automatically formatted. Similarly, if you remove one of the import statements that is being used, and save, the imports will be corrected. Unused imports will be removed.&lt;&#x2F;p&gt;
&lt;p&gt;These tools allow you to focus on writing software and let the tools worry about formatting and imports. Prettier code with less effort – why not?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Microcontroller (MCU) or Microprocessor (MPU)?</title>
        <published>2019-04-09T00:00:00+00:00</published>
        <updated>2019-04-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/"/>
        <id>https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1540/microcontroller-mcu-or-microprocessor-mpu/">&lt;p&gt;As technology advances, there are two basic processing platforms for implementing &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Embedded_system&quot;&gt;embedded systems&lt;&#x2F;a&gt;. The first is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Microcontroller&quot;&gt;Microcontroller Unit&lt;&#x2F;a&gt; (MCU). These devices have varying amounts of integrated Flash (&amp;lt;= 2MB) and RAM (&amp;lt;= 1MB), and are designed to run bare-metal code or a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Real-time_operating_system&quot;&gt;real-time operating system&lt;&#x2F;a&gt; (RTOS), like FreeRTOS. The second is the Linux-capable &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;w&#x2F;index.php?title=Microprocessor_unit&amp;amp;redirect=no&quot;&gt;Microprocessor Unit&lt;&#x2F;a&gt; (MPU).  An example of an MCU based system is most Arduinos, and an example of an MPU based system is the Raspberry PI. An MPU typically does not have embedded Flash and RAM – at least on the same die. The fundamental difference between MCU&#x2F;RTOS and MPU&#x2F;Linux systems is the memory architecture and the amount of memory in the system.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;mcu-vs-mpu-3-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;There are other differences as well, summarized in the table below.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table aligncenter has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Feature&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;MCU&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;MPU&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;# power supplies&lt;&#x2F;td&gt;&lt;td&gt; 3.3V&lt;&#x2F;td&gt;&lt;td&gt;VCORE, VIO, VDDR, etc.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;USB Host&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;Full support &lt;br&gt;many drivers&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Networking&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;Options for GB and&lt;br&gt;multiple interfaces&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Cost&lt;&#x2F;td&gt;&lt;td&gt;lower&lt;br&gt;$1-$20&lt;&#x2F;td&gt;&lt;td&gt;higher, starts at&lt;br&gt;$10 (cpu + power&#x2F;mem)&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Programming&lt;br&gt;Languages&lt;&#x2F;td&gt;&lt;td&gt;C&#x2F;C++&lt;br&gt;Micropython&lt;br&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;C&#x2F;C++, Go, Python, Nodejs, &lt;br&gt;Java, Erlang, Rust,&lt;br&gt;about anything&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Realtime&lt;&#x2F;td&gt;&lt;td&gt;hard&lt;&#x2F;td&gt;&lt;td&gt;soft&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Data processing&lt;&#x2F;td&gt;&lt;td&gt;limited&lt;&#x2F;td&gt;&lt;td&gt;excellent&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Processing power&lt;&#x2F;td&gt;&lt;td&gt;less&lt;&#x2F;td&gt;&lt;td&gt;more&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Display size&lt;&#x2F;td&gt;&lt;td&gt;small&lt;&#x2F;td&gt;&lt;td&gt;any size&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Startup time&lt;&#x2F;td&gt;&lt;td&gt;fast&lt;&#x2F;td&gt;&lt;td&gt;slow&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Expandable over&lt;br&gt;time&lt;&#x2F;td&gt;&lt;td&gt;less so&lt;&#x2F;td&gt;&lt;td&gt;more so&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;On-chip&lt;br&gt;Peripherals&lt;&#x2F;td&gt;&lt;td&gt;more&lt;br&gt;&lt;&#x2F;td&gt;&lt;td&gt;less&lt;br&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;PCB real-estate&lt;&#x2F;td&gt;&lt;td&gt;less&lt;&#x2F;td&gt;&lt;td&gt;more (external flash&#x2F;RAM)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Performance is related to memory architecture. In most MCUs, the memory architecture is fairly simple. Code is executed directly from flash, and on-chip SRAM is accessed directly. Programs do not need to be loaded from flash into RAM before running them. This architecture is very simple, leading to predictable real-time response and code execution. It takes a consistent amount of time to load code from flash into the processor for execution, so the timing for every instruction is fairly predictable. However, with this architecture, clock rate is typically limited to around 190MHz (example STM32F4). Some of the newer STM32 parts, such as the STM32F7 and STM32H7, add a L1 cache, which allows the CPU to run at 216MHz and 400MHz respectively.&lt;&#x2F;p&gt;
&lt;p&gt;MPUs have a more complex memory architecture in that they page code from Flash into SDRAM (both external to the MPU), and then from SDRAM into two or more levels of cache memory located on the MPU. The local cache memory is very fast, allowing these processors to run at high clock rates (1GHz or more in some cases). A &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Memory_management_unit&quot;&gt;memory management unit&lt;&#x2F;a&gt; (MMU) implements a virtual memory system in which physical pages from RAM are mapped into a virtual address space. This is very efficient as physical pages are only mapped in as needed and can be discarded if RAM is needed elsewhere. But this memory management introduces delays that are relatively long for some hard real-time systems. The first access to a block of code that has not been run recently takes time, as code needs to be paged from a file in flash into SDRAM and then loaded into the respective caches. But subsequent accesses from cache are blazing fast. An MMU also provides protection against one user space process corrupting memory of another process, or corrupting kernel memory. For complex systems (server&#x2F;desktop) running multiple processes, this protection increases the system reliability. For many Embedded systems, there is only one main application, and protecting processes from each other is less of a concern. However, this memory protection is still useful in that a bug in the application does not crash the system, and recovery mechanisms can be built in to restart the app, or debug it during development.&lt;&#x2F;p&gt;
&lt;p&gt;In an MCU, program flow is controlled through simple loops and state machines (no operating system) or a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Real-time_operating_system&quot;&gt;real-time operating system&lt;&#x2F;a&gt; (RTOS). In an MPU system, a fairly complex operating system like Linux is typically required to manage the multiple levels of memory and storage, schedule the multiple processes that are running, and provide drivers for the complex hardware systems found in an MPU (USB, large displays, networking, etc). There is a great gulf between these two systems. Even though a RTOS may run on an MPU, there are much longer delays in execution due to the memory architecture. You still have to load code from flash to SDRAM and then through several layers of cache memory before the CPU can execute it. Once it is in cache, the code executes much faster and can do more work overall, but the occasional delays are still there. You might be able to play tricks by locking lines of code in cache or by using the small amount of on chip SRAM that may be present, but by the time you do this, you are now back to the smaller memory sizes on an MCU, and may as well just use an MCU.&lt;&#x2F;p&gt;
&lt;p&gt;After understanding the differences in memory architectures, we can understand that MCUs and MPUs are optimized for different things. An MCU is optimized for simplicity, cost, and predictable (real-time) response times. An MPU is optimized for getting the maximum amount of work done over time. Cost and real-time response is a secondary concern. There is not really a lot of middle ground between an MCU and MPU, evidenced by the large gap in memory sizes. You can’t fit standard Linux in an MCU, as there is only so much NOR Flash and SRAM that will fit on an MCU die. Once you move to more dense memory technologies such as NAND Flash and SDRAM, these must be implemented as separate dies and typically separate integrated circuit packages. These technologies are so efficient at storing large amounts of data, that you see a huge jump in memory capacity once you switch to the off-chip memories.&lt;&#x2F;p&gt;
&lt;p&gt;MCUs and MPUs also have different origins. Today’s 32-bit MCUs have descended from simpler 8-bit MCUs and are scaled-up embedded controller technologies. MPUs have descended from desktop and server computer systems and are scaled-down technologies. The differing priorities of these two paradigms reflect their different uses.&lt;&#x2F;p&gt;
&lt;p&gt;Keeping these differences in mind, the most fundamental question to ask in selecting an MCU or an MPU is whether hard real-time performance and reliability is most critical (&lt;strong&gt;control-centric application&lt;&#x2F;strong&gt;), or whether data processing performance and connectivity is most important (&lt;strong&gt;data-centric application&lt;&#x2F;strong&gt;). If both of these are important in your application, you should consider having both an MCU and MPU in the system, saving yourself untold pain.&lt;&#x2F;p&gt;
&lt;p&gt;Reliability is an interesting topic. I have seen MPU&#x2F;Linux systems operate very reliably, and have also experienced issues that were very difficult to solve. MPU systems are many times more complex and have more unknowns, which translates into more risk. There are many more physical components and solder connections required to implement the system, all of which can fail over time with environmental stress. There are many millions of lines of code in an MPU system that you did not write, but you are still responsible for all of it – it all has to work for the system to function. Although an MPU system can be made fairly reliable, simple statistics tell us that MCUs will generally be more reliable than an MPU because there is less hardware that can fail and less lines of code running that may contain bugs.&lt;&#x2F;p&gt;
&lt;p&gt;One example of a problem we experienced when implementing control in an MPU system is a product where we were collecting data, and the data was being transferred back to a cloud server over a cellular modem. Unfortunately, the cellular modem in the system was not 100% reliable, and the only way to recover in some instances was to reboot the system when we detected a network failure, which cycled power to the modem (this modem module itself ran Linux). At one point, we added some basic control functionality to the system to control plant blowers based on a schedule. The control worked fine until the system had to restart due to modem connectivity issues, then the blower control was inactive during the reboot cycle (perhaps 30s or so). This was not a fatal problem in this application but also not ideal. The obvious solution is to get a more reliable modem or develop a better recovery method, but with units in the field and other development priorities, it is not always so simple. This is a classic example of the tension between complex data&#x2F;connectivity systems and reliable control.&lt;&#x2F;p&gt;
&lt;p&gt;In an MCU system, the hardware system is relatively simple, and you are using a relatively small RTOS, or none at all. You write a greater percentage of the code in the system yourself, so if you have a simple task to do, and write reliable code, there is a potential to have a more reliable system than a comparable MPU system. However, if you are trying to do complex data processing and connectivity tasks on an MCU (such as writing your own database, network, or USB stack), chances are there will be bugs in your code and you will have a less reliable system than if you would have chosen an MPU using proven technologies. If your application is large and complex, then writing it in a safer language like Go or Rust on an MPU may provide a more reliable and maintainable product than trying to implement the same functionality in C++. Again, if you need both reliable real-time control and advanced data processing, then put both an MPU and MCU in the system.&lt;&#x2F;p&gt;
&lt;p&gt;Another advantage of an MPU system is they tend to be more general purpose and more functionality can be added over time. There is little danger of running out of code space, which often happens in MCU environments. With interfaces like USB, additional peripherals can be added in the future as requirements change, and with Linux, drivers for a vast array of hardware are available.&lt;&#x2F;p&gt;
&lt;p&gt;In some cases these lines between MCUs and MPUs are blurred by technologies like Linux RT extensions, or uCLinux, but you still must keep the above principles in mind when selecting the building blocks for your product. MCUs and MPUs are very different devices designed to handle different tasks. Before choosing, you should understand what you are trying to do, and what is important for your product.&lt;&#x2F;p&gt;
&lt;p&gt;Reference:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ww1.microchip.com&#x2F;downloads&#x2F;en&#x2F;DeviceDoc&#x2F;MCU_vs_MPU_Article.pdf&quot;&gt;Atmel MCU vs MPU paper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.st.com&#x2F;b&#x2F;en&#x2F;microcontrollers-microprocessors.html&quot;&gt;ST page referencing both MCU and MPU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Accepting Constraints in Build Systems</title>
        <published>2019-04-01T00:00:00+00:00</published>
        <updated>2019-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1462/accepting-constraints-in-build-systems/"/>
        <id>https://bec-systems.com/1462/accepting-constraints-in-build-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1462/accepting-constraints-in-build-systems/">&lt;p&gt;As Embedded Systems become more complex, the complexity of the process to build the software for these systems also increases. As humans, our ability to deal with complexity is limited, so we develop &lt;strong&gt;tools and processes&lt;&#x2F;strong&gt; to manage the complexity. In the end, these tools and processes are about &lt;strong&gt;constraints and patterns&lt;&#x2F;strong&gt;. A well-designed tool or process encourages you to do things in a way that is &lt;strong&gt;consistent and maintainable&lt;&#x2F;strong&gt;, which leads to &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt; results.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;reliable-and-predictable-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As an example, consider using CMake vs standard Makefiles for a C++ application build system. This is a trade-off I often encounter, as my customers are using Linux to build products, and they need to develop a relatively complex software application to implement the product functionality. There are usually a handful of library dependencies as well (such as Qt, OpenCV, etc) – after all, the reason you use Linux is it provides a large amount of advanced functionality that you cannot afford to write yourself.&lt;&#x2F;p&gt;
&lt;p&gt;For a simple application, CMake is somewhat constraining and annoying. Its syntax is a little clumsy, and it is definitely less flexible than a Makefile. Thus some developers conclude that a Makefile is a better choice for Linux application builds. As the application grows, the Makefile also grows, and the number of dependencies increases. Then comes the time to cross compile the application so it will run on the target system. With a little work, we can convince the Makefile to accomplish this. Tool-chain file names and paths are often hard-coded in the Makefile. As the variations of systems the application needs to build on increase, all these variations are coded in the Makefile.&lt;&#x2F;p&gt;
&lt;p&gt;Five years down the road, something major changes. The application developers need some new features in a new version of OpenCV, or the System on Module (SOM) the target system is using just went obsolete. The developer who wrote the original Makefiles is gone. The Linux host distributions have changed. At this point the application build system collapses. So much has changed, and so much is hard coded in the Makefiles that getting them working again is a painful and tedious process. With some effort, they are finally building on one developer’s machine. But on the next developer’s machine, they fail with a different error.&lt;&#x2F;p&gt;
&lt;p&gt;The same dynamic happens when developers hack together tools to build an operating system image for an embedded device. This typically involves things like building the application or Linux kernel manually outside the build system, then writing a script to unpack an image file, insert the new binary, then pack the image file back up. The application build process is heavily dependent on the configuration of the developer’s workstation.&lt;&#x2F;p&gt;
&lt;p&gt;There is a better way. Use tools like Yocto&#x2F;OpenEmbedded and CMake as they are were meant to be used. These tools do have a learning curve, and require some investment to learn, but in the end they are well worth it. The reason tools like OpenEmbedded and CMake work is that they are consistent, and use the same patterns over and over. We can illustrate the basic architecture of OpenEmbedded in a simple sketch, as shown below. OpenEmbedded is made up of a relatively small number of primitives:&lt;em&gt;layers, recipes, packages, classes,&lt;&#x2F;em&gt; &lt;em&gt;conf files, and tasks&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;oe-architecture-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Dependencies can be specified at the layer, recipe, package, and task level. Once these basic concepts are understood, then it is easy to find things in the build system and make necessary modifications. The boundaries are precise and well-defined. These patterns are not as flexible as a Makefile or Bash script, but they abstract huge amounts of complexity. This allows our mind to see the big picture and not get bogged down in thousands of details and to reliably execute extremely complex tasks. The same patterns are used over and over and are easy to recognize. Dependencies are well-controlled. The cost is to understand and use the established &lt;strong&gt;patterns&lt;&#x2F;strong&gt; and to accept the &lt;strong&gt;constraints&lt;&#x2F;strong&gt;. These constraints may be a little inconvenient at times. But when you compare this to the work these tools do for you, these inconveniences are relatively minor.&lt;&#x2F;p&gt;
&lt;p&gt;If you are going to build complex products using complex technologies like Linux, then you need powerful tools to manage this complexity. There is a learning curve. You may need to invest in training or hire someone to help you get started. Most other industries recognize this. Car mechanics undergo continuous training to learn how to work on new vehicles&#x2F;systems. Nurses and other professionals receive training on new techniques and equipment.  Build systems also require a significant investment in learning. We routinely hire experts (doctors, dentists, plumbers, carpenters, etc) in our personal lives to do things we don’t know how or have time to do. But somehow many developers think the build system and associated infrastructure should not need attention, can be ignored, or is trivial and can be implemented from scratch. Never mind the fact that the underlying software in the system (bootloader, kernel, and libraries) are many times more complex than the custom application software written for the system. You must be able to &lt;strong&gt;maintain&lt;&#x2F;strong&gt; it all. You can’t ignore the stuff you did not write – it all has to work. It has to be &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt;.  A build system is largely invisible until it starts causing problems.&lt;&#x2F;p&gt;
&lt;p&gt;Getting something working initially is relatively easy; keeping it working for years is another matter. It is similar to product development – building the first prototype that somewhat works often goes fairly quick. Getting something into production is a long, arduous slog. The build system is the foundation of your software project. It must be &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt; because you can’t do much without it. A build system must do its part well without a lot of fuss, so we can focus on the problem being solved. A well implemented build system produces an image ready for installation with a single command and no manual steps. You check source code into git, run the build command, and out pops an image ready to deploy. There is no copying around binaries, etc. The efficiency gained by the effort to implement such a system pays itself back many times over the life of a project – especially those that are produced for 5-10 years.&lt;&#x2F;p&gt;
&lt;p&gt;Yocto and CMake are only used as examples in this article and may not be the best solution for every project. If you have something that is working well, keep doing what you are doing. But if what you are doing is not working, then ask yourself some  questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Is my current system the best way to build complex software?&lt;&#x2F;li&gt;
&lt;li&gt;Is the &lt;strong&gt;process&lt;&#x2F;strong&gt; to build your project’s software simple and easy to reproduce by any developer on any machine?&lt;&#x2F;li&gt;
&lt;li&gt;Is it well documented?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;maintainable&lt;&#x2F;strong&gt;?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;consistent&lt;&#x2F;strong&gt; across all your products?&lt;&#x2F;li&gt;
&lt;li&gt;Is it &lt;strong&gt;reliable and predictable&lt;&#x2F;strong&gt;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SD Card Write Speed Tests</title>
        <published>2019-03-13T00:00:00+00:00</published>
        <updated>2019-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1465/sd-card-write-speed-tests/"/>
        <id>https://bec-systems.com/1465/sd-card-write-speed-tests/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1465/sd-card-write-speed-tests/">&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;IMG_20190313_084412667-1.jpg&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;During Embedded Linux development, we often need to write large operating system images to SD cards for testing. Recently, I purchased a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;plugable.com&#x2F;products&#x2F;usb3-flash3&#x2F;&quot;&gt;USB 3.0 SD card reader&lt;&#x2F;a&gt; from Plugable. Before that, I used a USB 2.0 SD card reader from IOGear.&lt;&#x2F;p&gt;
&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2019&#x2F;03&#x2F;IMG_20190313_084233773-1.jpg&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;How much better does a USB 3.0 card reader perform compared to a 2.0 card reader? To test, I wrote a large (2.2GB) image to a Transcend v30 card using both readers.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;IO Gear USB 2.0 Reader&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Plugable USB 3.0 Reader&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15.3 MB&#x2F;s&lt;&#x2F;td&gt;&lt;td&gt;33.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The USB 3.0 reader is over twice as fast with this same card!&lt;&#x2F;p&gt;
&lt;p&gt;I then used the USB 3.0 reader to compare a number of cards.&lt;&#x2F;p&gt;
&lt;table class=&quot;wp-block-table has-fixed-layout is-style-stripes&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SD Card Brand&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Size&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Grade&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Tested&lt;br&gt;Speed&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Transcend&lt;&#x2F;td&gt;&lt;td&gt;8GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC&lt;&#x2F;td&gt;&lt;td&gt;8.8 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Sandisk&lt;&#x2F;td&gt;&lt;td&gt;32GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC I&lt;&#x2F;td&gt;&lt;td&gt;16.8 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Transcend&lt;&#x2F;td&gt;&lt;td&gt;16GB&lt;&#x2F;td&gt;&lt;td&gt;C10 HC I V30&lt;&#x2F;td&gt;&lt;td&gt;33.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;Sandisk&lt;&#x2F;td&gt;&lt;td&gt;64GB&lt;&#x2F;td&gt;&lt;td&gt;XC I V30 A1&lt;&#x2F;td&gt;&lt;td&gt;44.5 MB&#x2F;s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The markings on the cards mean various things. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SD_card&quot;&gt;Wikipedia SD Card page&lt;&#x2F;a&gt; provides a nice overview. A few details are summarized below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bus interface&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I: 50MB&#x2F;s Half&#x2F;Full duplex, 104MB&#x2F;s Half Duplex&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Capacity&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;HC: Secure Digital High Capacity (SDHC) format – supports cards 2GB to 32GB in size&lt;&#x2F;li&gt;
&lt;li&gt;XC: Secure Digital eXtended Capacity (SDXC) format – supports cards 32GB to 2TB in size&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Speed&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;10 with C around it: Minimal sequential writing speed is 10 MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;3 with U around it: UHS Speed Class: 30MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;V30: Video Speed Class: 30MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;A1: Application Performance Class 1: Read 1500 IOPS, Write 500 IOPS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you have not upgraded to a USB 3.0 card reader, it is probably worth your time to do so.&lt;&#x2F;p&gt;
&lt;p&gt;One note of caution – there are counterfeit cards for sale that look like SanDisk or Transcend cards.  They are not manufactured by these companies, and use lower quality components. If the price seems too good to be true, it probably is. Always buy from a reputable supplier.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting started with Embedded Linux</title>
        <published>2018-10-04T00:00:00+00:00</published>
        <updated>2018-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1154/getting-started-with-embedded-linux/"/>
        <id>https://bec-systems.com/1154/getting-started-with-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1154/getting-started-with-embedded-linux/">&lt;figure class=&quot;wp-block-image&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2018&#x2F;09&#x2F;embedded-linux-2.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;Recently I was asked by a developer, who has done windows development for 10 years, how to get started with Embedded Linux. Embedded Linux covers a lot of ground and includes a broad range of components&#x2F;skills to put together an entire system. Below are a few suggestions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;do-i-have-the-right-mindset&quot;&gt;Do I have the right Mindset?&lt;&#x2F;h3&gt;
&lt;p&gt;There are many different types of people; there are those who are who are a good fit for Linux, and those who are not. There are those who think Open Source Software (OSS) and Linux are the craziest thing they ever heard of, and those who think it’s a great idea. There are those who thrive on openness and collaboration, and those who feel threatened by it. A few specific aspects of this mindset are described below.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;code-gardening&quot;&gt;Code Gardening&lt;&#x2F;h4&gt;
&lt;p&gt;Much of your time as an embedded Linux developer is spent figuring stuff out (vs writing new code). Figuring out stuff is harder than writing new code (at least initially). It is similar to weeding the garden – often not something you are raring to do, but after you are finished, it feels really good. Much of the truly valuable work in life is like this. It initially appears kind of boring, but once you get started there are many interesting and rewarding aspects.&lt;&#x2F;p&gt;
&lt;p&gt;You have to like build systems and automation. Linux systems are complex. You can’t throw millions of lines of kernel and user space code together with a simple Makefile or a fancy IDE. Proficiency with command line tools is required. Builds must be clean and completely automated if you want to keep your sanity. Once you allow one manual step in the build, the floodgate has been opened, and these manual steps will start to accumulate at a frightening pace until you have an unmaintainable mess.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;collaboration&quot;&gt;Collaboration&lt;&#x2F;h4&gt;
&lt;p&gt;Because of the complexity, you have to be able to collaborate with others. This requires a generous mindset. How can I make this easy for someone else to pick up once I am gone? Most likely this someone will be you in a couple months or years when you have forgotten many of the project details. The same really applies to coding. Do I write my code to be clever, do I hack it together, or do I focus on making it maintainable and easily understand by others? Automation and simplicity reduce cognitive load, freeing up resources to think about the problems that actually need solved, and allow multiple people to work on a project without a lot of friction.&lt;&#x2F;p&gt;
&lt;p&gt;The flip side of this is humility. With a complex system like Linux, there will be a lot of things you don’t know, and some difficult problems to solve. There is no one “manual” for Linux where you can go look up an answer. So we rely on open source communities for help. There are many people willing to help, so the key is to have the wisdom to know where and when to ask for help, and then the humility to ask. In Linux communities (and OSS in general), you will be surrounded by developers who are much smarter and more knowledgeable than you. At the very least, there will always be someone who knows something you don’t. If you don’t have the humility to acknowledge this and be willing to learn, then you will likely never be comfortable or effective working in an OSS environment.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;nih&quot;&gt;NiH&lt;&#x2F;h4&gt;
&lt;p&gt;This can all be a challenge for developers who are endowed with a healthy dose of NiH (Not Invented Here Syndrome). These are people who imagine themselves happiest writing and maintaining their own code, and who are not inclined to share it with others. Some imagine themselves as great software architects and coders (very few of us really are) who can make something better. They don’t want to spend long, arduous hours learning and debugging a complex system written by someone else. If this describes you, then perhaps Embedded Linux is not for you.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;learning&quot;&gt;Learning&lt;&#x2F;h4&gt;
&lt;p&gt;Are you a learner? Do you enjoy learning about new technology, tools, techniques, etc? Everything is always changing in the Linux world. New and compelling solutions are coming out every year. The real power of Linux and Open Source is knowing when and how to leverage these new technologies to solve real problems. If you are more comfortable doing things the way they have always been done, then perhaps you should just keep doing what you are doing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-problem-of-abundance&quot;&gt;The Problem of Abundance&lt;&#x2F;h4&gt;
&lt;p&gt;Can you deal with a lot of choices? With Embedded Linux, there are many options for about every aspect of the system. There are multiple init systems. There are many programming languages. There are many libraries available for various tasks. There is no one, true way to implement Embedded Linux – you will have to make a lot of choices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ideas-for-learning-embedded-linux&quot;&gt;Ideas for Learning Embedded Linux&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;books-presentations-documentation-blogs&quot;&gt;Books&#x2F;Presentations&#x2F;Documentation&#x2F;Blogs&lt;&#x2F;h4&gt;
&lt;p&gt;There are many books published on Linux, Embedded Linux, Yocto, etc. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;&quot;&gt;Yocto documentation&lt;&#x2F;a&gt; is pretty good. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLbzoR-pLrL6qAnHzPdrTxwCUWPja5KnOq&quot;&gt;Videos from the Embedded Linux Conference&lt;&#x2F;a&gt; are freely available. There are many blogs that cover Embedded Linux topics (such as this one). Subscribing to blog RSS feeds in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;feedly.com&quot;&gt;feedly&lt;&#x2F;a&gt; is a good way to keep up with recent developments.&lt;&#x2F;p&gt;
&lt;p&gt;The list of learning resources is endless, but perhaps the key thing to remember is there is no one place you can go to learn everything you need to know, like you might for a commercial RTOS. The good news is there is information available in many different formats, so you can choose what best fits your learning style.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;run-linux-on-your-computers&quot;&gt;Run Linux on your computers&lt;&#x2F;h4&gt;
&lt;p&gt;One of the best ways to learn a lot about Linux is to simply use it for your personal and work computers. Ubuntu is very easy to get started with. If you go with something like Arch Linux, the install process will teach you a lot. I am very pleased with the combination of Arch Linux plus the XFCE desktop environment. This is a no-nonsense setup that does its job well, is very customizable, and stays out of my way. Any distribution will work – just pick something.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded Linux aside, there is little to lose, and a lot to gain from running Linux. Linux systems are naturally much more immune to viruses, malware, and various other attacks than Windows. Linux systems are much more flexible than Apple computers. Some things might not look as pretty, or might take a little more work to set up. But the stability, flexibility, and consistency of a Linux system will save you time in the long run. As a software developer, most of our time is spent in an editor and browser – these work very well in Linux. Additionally, the terminal is a first class citizen in Linux rather than an afterthought.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;learn-git&quot;&gt;Learn Git&lt;&#x2F;h4&gt;
&lt;p&gt;Git is used in almost all open source projects these days, and enables new levels of collaboration. You &lt;a href=&quot;&#x2F;723&#x2F;why-git&#x2F;&quot;&gt;need to know Git&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;do-small-projects-with-raspberry-pi-etc&quot;&gt;Do small projects with Raspberry PI, etc.&lt;&#x2F;h4&gt;
&lt;p&gt;There are a number of embedded computer boards out there that are very well supported and quite cheap such as the Raspberry PI. Find something in your home that you want to automate – there’s nothing like a real project to motivate learning. With Linux, you learn best by doing. This will also give you an opportunity to learn application programming under Linux.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;build-and-install-openembedded-yocto-or-buildroot&quot;&gt;Build and install OpenEmbedded&#x2F;Yocto or Buildroot&lt;&#x2F;h4&gt;
&lt;p&gt;Take the previously discussed home automation project and create a custom build for the board using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.yoctoproject.org&#x2F;&quot;&gt;Yocto&#x2F;OE&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;buildroot.org&#x2F;&quot;&gt;Buildroot&lt;&#x2F;a&gt;. This will give you practice learning how to put together a custom embedded Linux distribution. Create recipes to package, and include your custom applications in the image at build time (instead of installing them afterwards).&lt;&#x2F;p&gt;
&lt;p&gt;These tools have a learning curve and may seem intimidating initially, but Linux is a complex system, and you need powerful tools.&lt;&#x2F;p&gt;
&lt;p&gt;We think the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OE template&lt;&#x2F;a&gt; (now &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;yoe-distro&lt;&#x2F;a&gt;) is a good way to set up Yocto&#x2F;OE for a project.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;modify-the-linux-kernel&quot;&gt;Modify the Linux Kernel&lt;&#x2F;h4&gt;
&lt;p&gt;Most embedded Linux projects require a small amount of kernel modification. This can be something as simple as changing the GPIO configuration on an ARM SOC (System on chip), or writing a driver for some custom hardware. There are many resources available for learning Linux kernel programming. Perhaps try creating a custom driver for your PC or embedded Linux board. This driver could do something trivial, like monitor several GPIOs, etc.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;modify-and-install-u-boot&quot;&gt;Modify and install U-boot&lt;&#x2F;h4&gt;
&lt;p&gt;U-boot is a common bootloader for Embedded Linux systems (but not the only one). Locate the source code for your embedded board and learn how to build, modify, and install a custom version of U-boot.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;explore-the-many-application-programming-options&quot;&gt;Explore the many Application Programming Options&lt;&#x2F;h4&gt;
&lt;p&gt;There are so many interesting application programming options with Linux. Of course you can stick with traditional C&#x2F;C++. But today, there are many other languages and environments that may be better for various applications (Python, NodeJS, Golang, Qt&#x2F;QML, etc).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;find-something-that-is-broken-and-fix-it&quot;&gt;Find something that is broken and fix it&lt;&#x2F;h4&gt;
&lt;p&gt;There are many opportunities to improve open source code. Find something that does not work quite right, fix it, and get the changes accepted in the upstream project. This will provide valuable experience working with OSS communities. When working with complex systems like Linux, you will run into problems that are very hard to solve. Being comfortable with asking, and getting help from various OSS communities will be key to your success. Again, your mindset is key here. People who don’t have the right mindset will create fake names and email aliases to hide their true identity when asking questions. People with the right mindset are willing to be up front and admit there is something they don’t know.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;helping-others&quot;&gt;Helping Others&lt;&#x2F;h4&gt;
&lt;p&gt;One of the best ways to really learn something is to teach it or help others. Once you reach a certain level of proficiency, there are many opportunities in open source communities (stack overflow, mail lists, IRC, etc) to help others. In doing so, we usually receive back much more than we give.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;maintain-yocto-or-buildroot-support-for-an-embedded-board&quot;&gt;Maintain Yocto or Buildroot support for an embedded board&lt;&#x2F;h4&gt;
&lt;p&gt;There are many embedded Linux platforms out there that are not actively maintained or tested in Yocto or Buildroot. Get involved and help keep the platform current and working in the build system.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;set-up-a-server-in-the-cloud&quot;&gt;Set up a server in the cloud&lt;&#x2F;h4&gt;
&lt;p&gt;It is very cheap (less than $10&#x2F;mo) to set up a server in Amazon AWS, Digital Ocean, Linode, Vultr, or one of the many other cloud providers. Although this is technically not embedded Linux, the skills required are very similar. It will also open up interesting possibilities of creating systems that are a combination of Embedded Linux devices and cloud servers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;publish-an-open-source-project-on-github&quot;&gt;Publish an Open Source project on Github&lt;&#x2F;h4&gt;
&lt;p&gt;Publishing an open source project is a good experience as it helps you learn to create something that is generally useful. For example, I wrote a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;linux-serial-test&quot;&gt;little app&lt;&#x2F;a&gt; to test serial ports and published it on Github. Over the past few years, other people have provided nice contributions to the application, making it much more useful, with little effort on my part. However, I had to spend a little more time up front making the app generally useful and documenting how to use it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Embedded Linux brings a level of functionality to systems that is unmatched by anything else out there, thus its popularity. With this broad scope of functionality comes complexity. Linux has a learning curve, and using it successfully requires some amount of discipline and interaction with various OSS communities. The resources are endless – time and motivation are the only limitations. In life, the rewards are proportional to the effort put forth. If you are committed, working with Embedded Linux is very rewarding, and brings a new level of functionality to products.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git, Versioning, and Branching for Embedded Linux Development</title>
        <published>2018-02-14T00:00:00+00:00</published>
        <updated>2018-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/"/>
        <id>https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1412/git-versioning-and-branching-for-embedded-linux-development/">&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2018&#x2F;02&#x2F;versions-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When building a product using Linux, versioning and branching of your software is an important consideration. Everyone’s needs are different depending on the size of the team, culture, and testing requirements, so there is no one size that fits all. However, after working on a number of different projects for a dozen or so different companies, there are several practices that are often used.&lt;&#x2F;p&gt;
&lt;p&gt;The most fundamental is to use Git to manage your software development. It is surprising the number of small companies developing software who do not use Git, or any version control system yet. The many &lt;a href=&quot;&#x2F;723&#x2F;why-git&#x2F;&quot;&gt;benefits of Git stand alone&lt;&#x2F;a&gt;, but the minute you enter into the Linux world (or the Open Source Software (OSS) world in general), there are thousands of projects available, and 99.9% of them are developed in Git. Having a good understanding of Git is essential in using OSS. This is not really specific to Linux development, but rather any modern software development (cloud, web, mobile, etc). Most foundational software technologies today are open source. There is no other development methodology that scales to the complexity of modern software systems, and no one company contains the resources needed to create and maintain these systems. Git does have a steep learning curve and usually requires 2-3 weeks of committed use for new users to become comfortable with it. However, it is well worth it.&lt;&#x2F;p&gt;
&lt;p&gt;An extension of using Git is to consider hosting your Git repositories in the cloud. There are many companies who provide this service at a reasonable cost (some like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.gitlab.com&#x2F;&quot;&gt;Gitlab&lt;&#x2F;a&gt; are free), or it is relatively simple to host your own git server (can be done for $2.50&#x2F;mo at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.vultr.com&#x2F;&quot;&gt;Vultr&lt;&#x2F;a&gt; using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitea.io&quot;&gt;Gitea&lt;&#x2F;a&gt;). Some may balk at putting a company’s valuable IP (intellectual property) assets in the cloud (where hackers might have an easier time getting to them) vs behind the secure company firewall. However, which of the following is the main impediment to your business?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The danger of competitors hacking into your cloud server, stealing your IP, and then implementing a product with it.&lt;&#x2F;li&gt;
&lt;li&gt;Shipping products in a timely fashion, and then maintaining them.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In my observation, #2 seems to be the challenge for most – especially as systems become more complex. Unless you are a top secret government agency, or a cutting edge chip&#x2F;algorithm company, your software IP is probably of marginal use to anyone else. The reason for this is that integration and execution is most often the challenge, not coding. There is plenty of free&#x2F;OSS software out there to do about anything. Integrating this into something that will make a product is the hard part.  It is difficult getting software and hardware to work together, debugging problems, communicating with cloud infrastructure, software updates, maintaining a product, adding features, etc. Modern products are typically not static entities where you design it, toss it over the wall to production, produce millions, make lots of money, and never see it again. Rather modern products are complex, dynamic beasts that have continually changing requirements, bugs to fix, features needed for new customers, manufacturing issues to solve, obsolete parts to replace, and are part of a larger complex system. Execution is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sethgodin.typepad.com&#x2F;seths_blog&#x2F;2007&#x2F;09&#x2F;big-ideas.html&quot;&gt;hard&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;the-mission&#x2F;give-your-ideas-away-f21d8dbf9c1&quot;&gt;valuable&lt;&#x2F;a&gt; part. Increasing developer efficiency and collaboration is important, especially with a distributed team of developers. You can require your developers to use company issued Windows computers and fussy VPNs in an attempt to protect your IP, or you can simply host your Git repositories in the cloud secured by industry proven methods such as https and ssh. As systems become more complex, it is critical to be able to involve domain experts in the project (consultants, contractors, employees at a different office, manufacturing, etc). A Git server in the cloud is the foundation of distributed development collaboration. Emailing zip files may be temping as quick and easy, but it is not a sustainable way to develop products that have so many moving parts. As an extension of this, use a web based Git repository manager (like Gitea, Gitlab, or a hosted solution) to implement your Git server. These repository managers greatly simplify the management of Git repos (teams, users, permissions, creating repositories, issue tracking, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Software should be released with a version number. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;Semantic Versioning&lt;&#x2F;a&gt; is a good place to start. Your needs may vary, but you may as well start with the good ideas of others. Additionally, a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;keepachangelog.com&#x2F;&quot;&gt;changelog&lt;&#x2F;a&gt; should be maintained that lists all changes for each software release. Being able to quickly understand what changed with each release is critical as multiple versions are being used. Keeping a changelog requires a little discipline, but is fairly easy to do if you keep an unreleased section at the top of your changelog file to track changes for the upcoming release, as described in the above link.&lt;&#x2F;p&gt;
&lt;p&gt;A discussion on branching only really makes sense if you are using Git. Source code branches greatly improve your development process flow. The ease with which Git allows you to create and merge source code branches enables development flows which were impractical before Git. With an Embedded Linux project you are typically building images that get loaded on some type of hardware device. In this case, it’s useful to have &lt;em&gt;development&lt;&#x2F;em&gt; and &lt;em&gt;production&lt;&#x2F;em&gt; releases. Production releases are sent to customers, and development releases are used internally to test new features under development. Every software component that is under active development (OE build system, custom applications, kernel, etc) should likewise have production and development branches that feed into their respective builds. For a more extensive discussion of this topic, consider &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nvie.com&#x2F;posts&#x2F;a-successful-git-branching-model&#x2F;&quot;&gt;this post&lt;&#x2F;a&gt;. Again, start with the good ideas of others, and then use what makes sense. An OE build can be configured to pull from the latest HEAD of your custom components, so that for each new build you get the latest from the respective branches for various components. To do this, you typically have something like the following in a bitbake recipe:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;git:&#x2F;&#x2F;git.mycompany.com&#x2F;myproject.git;branch=develop;protocol=ssh;user=git
PV = &amp;quot;4.1.15+git${SRCPV}&amp;quot;
SRCREV = &amp;quot;${AUTOREV}&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In some cases, for production builds we’ll manually specify the Git hash or tag in the bitbake recipe so that versions of all components are explicitly locked down. To specify a git version, replace &lt;em&gt;${AUTOREV}&lt;&#x2F;em&gt; with a Git hash. Either way, if you include the Git version (&lt;em&gt;SRCPV&lt;&#x2F;em&gt;) in the package version (&lt;em&gt;PV&lt;&#x2F;em&gt;) variable, you can always figure out what Git version was used to build a package for a particular release. Below is an example of a package file name:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;my-app_4.1.15+git0+a05d9b23b9-r0.10_var_som_mx6.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, &lt;em&gt;a05d9b23b9&lt;&#x2F;em&gt; tells you what Git version was used to build &lt;em&gt;my-app&lt;&#x2F;em&gt;. This is often adequate if you don’t spend a lot of time building or patching old software releases. With each release of software, it is beneficial to tag the software components used in the build with a version. This allows a clear view of what changed between releases, and allows us to easily check out old versions of software.&lt;&#x2F;p&gt;
&lt;p&gt;With development and production branches, we should consider how to version the different branches. One simple way is to use a sequence like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1.0.0 (production)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.900 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.901 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.1 (production bug fix)&lt;&#x2F;li&gt;
&lt;li&gt;1.0.902 (develop)&lt;&#x2F;li&gt;
&lt;li&gt;merge develop to production and do a new release&lt;&#x2F;li&gt;
&lt;li&gt;1.1.0 (production)&lt;&#x2F;li&gt;
&lt;li&gt;1.1.900 (continue development&lt;&#x2F;li&gt;
&lt;li&gt;1.1.901 (develop)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this case, the development version is always the last production release &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;&lt;em&gt;MAJOR.MINOR&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and the &lt;em&gt;PATCH&lt;&#x2F;em&gt; version starts at 900 and is incremented with each development release. If a version number ends in 9xx, you know it’s a development build. You can use more complex version schemes like 1.1.0-alpha1 (instead of 1.0.901), but then you might run into sorting problems where 1.1.0-alpha1 is listed after 1.1.0, even though 1.1.0 is a later release than 1.1.0-alpha1. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;meta-bec&#x2F;blob&#x2F;master&#x2F;recipes&#x2F;updater&#x2F;files&#x2F;imx6ul-var-dart&#x2F;init#L288&quot;&gt;Recent versions&lt;&#x2F;a&gt; of the &lt;a href=&quot;&#x2F;146&#x2F;do-you-need-software-update&#x2F;&quot;&gt;BEC software updater&lt;&#x2F;a&gt; look at all update files on a USB disk and pick the latest one using a natural sort of version numbers within the text. In the example below, you can see how versions are sorted:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[cbrake@mars ver]$ ls -lv
total 0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.1
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.900
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.0.901
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.1.0
-rw-r--r-- 1 cbrake cbrake 0 Dec 7 10:23 1.1.0-alpha1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, 1.0.9xx works much better for development builds if you want update systems to automatically pick the latest release from a list of options. You can also use versions like 1.0.0+1.1.0-alpha1 to get around the sorting problem if you want something a little more explicit.&lt;&#x2F;p&gt;
&lt;p&gt;Versioning and branching does not have to be complex, and in many cases the above is adequate for small teams. Your needs may vary, but the important thing is to have a source control, versioning, and branching process in place. These practices require some discipline to implement, and may seem unnecessary to those who have not used them, but with a little experience we soon realize that efforts to introduce appropriate amounts of organization and process into our development efforts clearly communicates what we did, what we are doing, and what gets released to production. This then frees us up to focus on what really adds value.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Separation of Source and Build Directories</title>
        <published>2017-11-16T00:00:00+00:00</published>
        <updated>2017-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1113/separation-of-build-and-source-directories/"/>
        <id>https://bec-systems.com/1113/separation-of-build-and-source-directories/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1113/separation-of-build-and-source-directories/">&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2017&#x2F;11&#x2F;oe-tree2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As we work with larger and more complex systems (i.e. Linux), more and more of our time is spent on integration and pulling different pieces together.  We often need to debug or understand code we did not write – especially in build systems.  To work effectively in this scenario you must be able to quickly search through a lot of source code.  Therefore, we are always looking for ways to make this more efficient.&lt;&#x2F;p&gt;
&lt;p&gt;One pattern that is very useful is separating source and build files into two separate directories at the top level of the project.  There are several reasons for this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It is easy to grep the source (or today we &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BurntSushi&#x2F;ripgrep&quot;&gt;ripgrep&lt;&#x2F;a&gt;) if it is not littered with transient build data.&lt;&#x2F;li&gt;
&lt;li&gt;Its easy to reset the build by simply deleting the build directory.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is especially important for large builds like OpenEmbedded, where a build directory can be on the order of 40GiB. If your grep tool has to process 40GiB of data every time it runs, it will be very slow.&lt;&#x2F;p&gt;
&lt;p&gt;This separation should occur at the top level of the project.  Ideally you want something like this for an OpenEmbedded build:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;├── build&#x2F;
│   ├── sstate-cache&#x2F;
│   └── tmp&#x2F;
├── downloads&#x2F;
├── sources&#x2F;
│   ├── bitbake&#x2F;
│   ├── meta-bec&#x2F;
│   ├── meta-browser&#x2F;
│   ├── meta-freescale&#x2F;
│   ├── meta-freescale-3rdparty&#x2F;
│   ├── meta-freescale-distro&#x2F;
│   ├── meta-openembedded&#x2F;
│   ├── meta-qt5&#x2F;
│   ├── meta-variscite-fslc&#x2F;
│   ├── meta-myproject&#x2F;
│   ├── meta-mycompany&#x2F;
│   └── openembedded-core&#x2F;
├── conf&#x2F;
└── etc ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;sources&lt;&#x2F;em&gt; directory contains OpenEmbedded metadata (core, 3rd party, and your own custom meta-myproject layers).  The &lt;em&gt;downloads&lt;&#x2F;em&gt; directory might contain 3rd party sources or tar balls that are downloaded by the build tool.  And the &lt;em&gt;build&lt;&#x2F;em&gt; directory contains transient build data that can be deleted and re-created at any time.  This configuration is used in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YoeDistro&#x2F;yoe-distro&quot;&gt;Yoe distribution&lt;&#x2F;a&gt;.  It should be noted that in this example, the desire is to cleanly separate OE metadata (source) from build data.  Source code for individual packages is considered build data from an OE perspective.  Most of the development work in this case is creating&#x2F;customizing OE recipes, images, etc, thus the need is to quickly grep the various OE meta layers.&lt;&#x2F;p&gt;
&lt;p&gt;This idea can be contrasted with the Poky reference distribution directory layout:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;├── bitbake 
├── build 
│   ├── cache 
│   ├── conf 
│   ├── downloads 
│   ├── sstate-cache 
│   └── tmp 
├── documentation 
├── meta 
├── meta-poky 
├── meta-selftest 
├── meta-skeleton 
├── meta-yocto-bsp 
└── scripts
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, there are multiple meta directories in the top level.  If you want to search all of the OE meta data, you need to instruct your search tool to exclude the &lt;em&gt;build&lt;&#x2F;em&gt; directory.  Additionally, the build directory is dynamically generated, which includes the conf directory.  If you want to completely reset your build, you need to clean several directories in the build directory.  For a production build, you need some of the conf files to be in revision control; therefore, they are more difficult to manage when they are dynamically generated, or copied from another location.  Why not move conf to the top and use it there?&lt;&#x2F;p&gt;
&lt;p&gt;Most decisions are tradeoffs, so there may be good reasons for the Poky directory structure.  For a reference (demo) distro, simplicity and ease of setup may be valued over reproducibility.  For production builds (builds used in products), rock solid reproducability is important.  To get that, you need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;all source and configuration is locked down in version control&lt;&#x2F;li&gt;
&lt;li&gt;a build should be a minimal number of steps: checkout source, a very simple setup&#x2F;configuration step, and then a build command.  There should be no complex scripts that copy files around that may be modified later, or manual steps.&lt;&#x2F;li&gt;
&lt;li&gt;the output is ready to program into the target.  There are no manual post processing steps.&lt;&#x2F;li&gt;
&lt;li&gt;keep things as simple as possible.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The separation of source and build can also be used&#x2F;observed with many other build systems.  With CMake, if you have a project directory named &lt;em&gt;myproject&lt;&#x2F;em&gt;, you can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mkdir myproject-build
cd myproject-build
cmake ..&#x2F;myproject
make
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Qt Creator also sets up a separate build directory by default.&lt;&#x2F;p&gt;
&lt;p&gt;With the linux kernel, you can specify a separate build directory with the ‘O’ option:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cd linux
mkdir ..&#x2F;linux-build
make O=..&#x2F;linux-build
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Think about directory structure – it can make a difference.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding the NXP i.MX6UL Pin Mux (Part 2)</title>
        <published>2017-11-06T00:00:00+00:00</published>
        <updated>2017-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/"/>
        <id>https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1377/understanding-the-nxp-i-mx6ul-pin-mux-part-2/">&lt;p&gt;In the &lt;a href=&quot;&#x2F;1313&#x2F;understanding-the-nxp-i-mx6ul-pin-mux&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;, it was noted that bit 30 needs to be set in the i.MX6UL pad config if you want to read the state of a GPIO output. Digging into this a bit more, we find the following text in the &lt;em&gt;Documentation&#x2F;devicetree&#x2F;bindings&#x2F;pinctrl&#x2F;fsl,imx-pinctrl.txt&lt;&#x2F;em&gt; file:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;SION(1 &amp;lt;&amp;lt; 30): Software Input On Field.&lt;&#x2F;em&gt;
&lt;em&gt;Force the selected mux mode input path no matter of MUX_MODE functionality. By default the input path is determined by functionality of the selected mux mode (regular).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the i.MX6UL developers manual, we also find the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2017&#x2F;10&#x2F;imx6ul-sion-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When we look at the &lt;em&gt;SW_MUX_CTL&lt;&#x2F;em&gt; register, we notice the &lt;em&gt;SION&lt;&#x2F;em&gt; bit is located at the bit 4 position.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the question is: How does bit 30 in the device tree file get mapped to bit 4 in the &lt;em&gt;SW_MUX_CTL&lt;&#x2F;em&gt; register? In the Linux kernel source we find the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;drivers&#x2F;pinctrl&#x2F;freescale&#x2F;pinctrl-imx.c:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* The bits in CONFIG cell defined in binding doc*&#x2F;
#define IMX_NO_PAD_CTL 0x80000000 &#x2F;* no pin config need *&#x2F;
#define IMX_PAD_SION 0x40000000 &#x2F;* set SION *&#x2F;

...

 &#x2F;* SION bit is in mux register *&#x2F;
 config = be32_to_cpu(*list++);
 if (config &amp;amp; IMX_PAD_SION)
 pin-&amp;gt;mux_mode |= IOMUXC_CONFIG_SION;
 pin-&amp;gt;config = config &amp;amp; ~IMX_PAD_SION;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;drivers&#x2F;pinctrl&#x2F;freescale&#x2F;pinctrl-imx.h&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#define IOMUXC_CONFIG_SION (0x1 &amp;lt;&amp;lt; 4)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From this code, we can see that bit 30 is a virtual bit that gets translated into bit 4 in the mux mode register.&lt;&#x2F;p&gt;
&lt;p&gt;Hope this helps in understanding how to configure the i.MX6UL gpio. Once you understand the details; the process is very simple.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding the NXP i.MX6UL Pin Mux</title>
        <published>2017-09-14T00:00:00+00:00</published>
        <updated>2017-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/"/>
        <id>https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1313/understanding-the-nxp-i-mx6ul-pin-mux/">&lt;p&gt;&lt;em&gt;(note, the article is also applicable to the i.MX6ULL as these processors are very similar)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The NXP i.MX6UL application processor has a very flexible pin multiplexer, that is somewhat difficult to understand at first glance.  Most times when we’re configuring the pin mux in Linux, we modify Device Tree files, so perhaps that is the place to start.  The pin mux options for the i.MX6UL are defined in the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git&#x2F;tree&#x2F;arch&#x2F;arm&#x2F;boot&#x2F;dts&#x2F;imx6ul-pinfunc.h?h=v4.11#n155&quot;&gt;&lt;em&gt;arch&#x2F;arm&#x2F;boot&#x2F;dts&#x2F;imx6ul-pinfunc.h&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; file.  The arguments to the macros in this file are defined as:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;*
 * The pin function ID is a tuple of
 * &amp;lt;mux_reg conf_reg input_reg mux_mode input_val&amp;gt;
 *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first 5 are defined in the pinfunc.h file, where the config value is defined in a user’s DTS file.  As an example, consider the following section from &lt;em&gt;imx6ul-pinfunc.h.&lt;&#x2F;em&gt; Column headings are added for clarity.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;&#x2F; headings:                                  mux_  conf_   input_ mux_ input
&#x2F;&#x2F;                                            reg   reg     reg    val  _val
#define	MX6UL_PAD_GPIO1_IO09__PWM2_OUT        0x0080 0x030C 0x0000 0    0
#define	MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY  0x0080 0x030C 0x0000 1    0
#define	MX6UL_PAD_GPIO1_IO09__SPDIF_IN        0x0080 0x030C 0x0618 2    0
#define	MX6UL_PAD_GPIO1_IO09__CSI_HSYNC       0x0080 0x030C 0x0524 3    1
#define	MX6UL_PAD_GPIO1_IO09__USDHC2_RESET_B  0x0080 0x030C 0x0000 4    0
#define	MX6UL_PAD_GPIO1_IO09__GPIO1_IO09      0x0080 0x030C 0x0000 5    0
#define	MX6UL_PAD_GPIO1_IO09__USDHC1_RESET_B  0x0080 0x030C 0x0000 6    0
#define	MX6UL_PAD_GPIO1_IO09__UART5_DCE_CTS   0x0080 0x030C 0x0000 8    0
#define	MX6UL_PAD_GPIO1_IO09__UART5_DTE_RTS   0x0080 0x030C 0x0640 8    2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the i.MX6UL processor reference manual (IOMUX Controller chapter), we can determine the mux_reg is indeed located at offset 0x80.  We can also see that the &lt;em&gt;mux_val&lt;&#x2F;em&gt; values match MUX_MODE in the datasheet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;mux-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;mux_val&lt;&#x2F;em&gt; in the &lt;em&gt;imx6ul-pinfunc.h&lt;&#x2F;em&gt; file also match the MUX_MODE field values in the above register.&lt;&#x2F;p&gt;
&lt;p&gt;The config register can also be located in the datasheet.  Again, we notice that the offset of 0x30C matches &lt;em&gt;config_reg&lt;&#x2F;em&gt; setting.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;cfg-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;cfg-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lets consider the last option listed in the pinfunc file: UART5_DTE_RTS.  The input register is used to mux a pin to an input function inside the SOC – in this case, the UART5_RTS_B input.  We find the input register at offset 0x640 and can see that the input value of 0x2 matches what we would expect in the reference manual.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;input-reg-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;07&#x2F;input-reg-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, how do we know if the pinmux is configured correctly for a pin?  One way is to use devmem2 and dump the register contents directly from user space:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:&#x2F;sys&#x2F;class&#x2F;gpio# devmem2 0x20e0080
&#x2F;dev&#x2F;mem opened.
Memory mapped at address 0x76f02000.
Read at address  0x020E0080 (0x76f02080): 0x00000005
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The mux value is 0x5, which configures the pin for the default GPIO1_9 function.  Next we can look at the config register:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:&#x2F;sys&#x2F;class&#x2F;gpio# devmem2 0x20e030C
&#x2F;dev&#x2F;mem opened.
Memory mapped at address 0x76f0b000.
Read at address  0x020E030C (0x76f0b30c): 0x000010B0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we further decode the bits in this register we find:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Bit index: 12─╮  8─╮  4─╮  0─╮ 
Bits:         1 0000 1011 0000
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and can conclude that the following options are set:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;bits 3-5 = 6: DSE_43ohm&lt;&#x2F;li&gt;
&lt;li&gt;bits 6-7 = 2: Medium speed (100MHz)&lt;&#x2F;li&gt;
&lt;li&gt;bit 12: PKE: Pull&#x2F;Keeper Enabled&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are additional options that can be configured such as hysteresis, pull up&#x2F;down, open drain, and slew rate.  I&#x2F;O is very configurable on this device!&lt;&#x2F;p&gt;
&lt;p&gt;If we want to use this pin as a GPIO, it appears that everything is configured correctly, so let’s give it a try.  GPIO in the i.MX6UL is banked in 32 bit registers, so we need to map this to a sequential GPIO in Linux.  The formula for this mapping is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;linux gpio number = (gpio_bank - 1) * 32 + gpio_bit&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For GPIO1_9, this would be GPIO9.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;linux gpio number = (1 - 1) * 32 + 9 = 9&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To read the GPIO, execute the following commands:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@imx6ul-var-dart:~# cd &#x2F;sys&#x2F;class&#x2F;gpio&#x2F;
root@imx6ul-var-dart:~# echo 9 &amp;gt; export
root@imx6ul-var-dart:~# cat gpio9&#x2F;value
0 (current gpio value)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another nuance of configuring the i.MX6UL pin mux in Linux is that for GPIO outputs, you need to set a magical bit 30 in the Device Tree configuration as show below.  If you don’t set bit 30, it will always read back as 0.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x4001b0b0 &#x2F;* 2_nSLEEP *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The reason for this will be explored in a future post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why Git?</title>
        <published>2016-08-18T00:00:00+00:00</published>
        <updated>2016-08-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/723/why-git/"/>
        <id>https://bec-systems.com/723/why-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/723/why-git/">&lt;p&gt;Some time back, I gave a &lt;a href=&quot;&#x2F;video&#x2F;2010-08-26_git.ogv&quot;&gt;presentation&lt;&#x2F;a&gt; that included an overview of the Git version control system.  I still occasionally get asked why Git should be used instead of Subversion, as it seems harder at first.  Most developers don’t really understand Git until they have used it for awhile, and then they will have an “aha moment.”  There are 3 features of Git that are especially interesting to me:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;many repositories (vs. one large repository)&lt;&#x2F;li&gt;
&lt;li&gt;distributed development&lt;&#x2F;li&gt;
&lt;li&gt;cheap branches&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The fundamental driver for better tools is increasing system complexity.  Developers are required to manage and integrate more third party software, work in distributed teams, and more effectively re-use the software we do have.  Git is a tool that helps you accomplish these goals.&lt;&#x2F;p&gt;
&lt;p&gt;Git is a fairly new project, but it is already nearly universal among open source software projects.  Its uptake and acceptance speaks for itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;many-repositories&quot;&gt;Many Repositories&lt;&#x2F;h2&gt;
&lt;p&gt;In the past when most companies used Subversion, there was one huge company repository (I’ve seen them in the 10’s of GB in size) that held a hierarchical tree of all the company source code.  This worked fairly well, and is comfortable in that it is very similar to a file system directory structure.  However, this model is not very flexible in that it does not have a consistent way to re-use components between different projects.  Some people simple copy source code.  Some have a “common” project that is included in all their other projects.  Subversion externals can be used.  But with Git, typically a separate repository is created for each software component.  There are perhaps several reasons for this, but one reason is that Git simply does not scale to huge multi-GByte repositories.  However, this turns out to be a blessing in disguise as I think it is a better model in many cases.  What we end up with is more of a catalog of software components rather than a rigid hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot; alt=&quot;svn-vs-git_600&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is much emphasis these days made on modular, re-usable software components (Object Oriented Programming, plugins, etc.).  Why not keep things modular at the repository level?  Another example of this type of organization is the Internet itself.  It is not a hierarchy of information, but rather a flat system that is organized by hyperlinks.&lt;&#x2F;p&gt;
&lt;p&gt;One of the benefits of organizing your source code this way is that it encourages clean boundaries between software components.  Each software component needs to stand on its own fairly well without being propped up by header files located in an unrelated source tree 3 levels up in the directory hierarchy.  This type of organization forces us to make better use of standard build system practices.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distributed-development&quot;&gt;Distributed Development&lt;&#x2F;h2&gt;
&lt;p&gt;The “many repository” paradigm has been partly driven by the distributed development paradigm.  Git solves the problem of multiple developers working in multiple repositories very well.  Because we want to use and customize projects like the Linux kernel, U-boot, and OpenEmbedded in our projects, then we naturally find ourself in the situation where we need to manage multiple repositories.  Yes, you can check the Linux kernel into your company Subversion repository, but you are much better off long term if you bite the bullet and implement your own Git infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider the product development process, we need to consider the life cycle of a product.  Most products live for at least several years, and will go through several software iterations.  If we can update the software components we use, then we can add value to the product in the form of new or updated drivers to support new peripherals, new libraries, performance improvements, etc.  But we are dealing with millions of lines of source code, so we must have an efficient way to deal with software projects of this size.  The below Figure 2, below, illustrates how you might organize a typical project.  Notice we can pull updates from the U-boot and Kernel source trees at any time in the development process.  We might have an outside team working an application, and we then easily synchronize the repositories when it makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot; alt=&quot;git-distributed_600&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many other design flows possible.  Once you have the ability to support multiple branches and repositories easily, it becomes trivial to implement a staging&#x2F;testing repository for QA processes, maintenance repositories for supporting old releases, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cheap-branches&quot;&gt;Cheap Branches&lt;&#x2F;h2&gt;
&lt;p&gt;The last feature discussed in this article is that of cheap branches.  Just as Git excels in allowing us easily integrate changes from multiple repositories at a team level, Git also allows us to easily work with multiple branches at the personal developer level.  This is a revolutionary feature, and perhaps has to be experienced to be fully appreciated.  With SVN, branching and merging is painful; therefore branches are not used a lot.  In Git, branches are easy, therefore branching is naturally encouraged.  Below is a typical flow of development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;cheap-branches-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;cheap-branches-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In this case, a developer is working on a performance improvement that is largely experimental – depending how it works out, it may or may not be used.  So he starts a branch and experiments with various changes.  As he goes along, he makes nice granular commits that are easy to follow.  He may reach a dead-end, delete the branch and start a new one.  In this middle of this development, his boss asks him to make a quick bug fix.  He checks out master, makes the change, switches back to the branch and keeps working.  The switching between branches takes seconds and is very easy.  Finally, he has some performance changes he is happy with.  He merges master to his perf-improvement branch and tests his changes with the latest master changes.  Everything looks good, so he then merges his branch to master.  Git makes this type of development flow natural and easy.  Because branching is painful in SVN, changes tend to be made in large commits that are difficult to understand.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to keep separate tasks isolated is analogous to having a clean, neat desk with only one thing on it, or having a messy desk with a half a dozen different projects going at once.  Git is a tool to help maintain different working contexts, and it allows work to be staged in a natural flow.  In the end, Git will change how you work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Go in place of a Spreadsheet</title>
        <published>2016-06-28T00:00:00+00:00</published>
        <updated>2016-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/"/>
        <id>https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1303/using-go-in-place-of-a-spreadsheet/">&lt;p&gt;Recently I needed to calculate NAND partition tables for a project where we will be supporting a number of different flash parts from 500MB to 2GB.  I first tried this in a spreadsheet, but found it difficult to work easily with hex numbers and do the calculations I needed.  I then looked into options for formatting text in columns from a program and found the nice &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;pkg&#x2F;text&#x2F;tabwriter&#x2F;&quot;&gt;text&#x2F;tabwriter&lt;&#x2F;a&gt; Go library.  With a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;go-partition-calcs&quot;&gt;few lines of code&lt;&#x2F;a&gt;, I was then able to get the below output, which is quite easy to read.  The only tricky part was figuring out that for right justified data, you need to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;not use tabs for the padding character&lt;&#x2F;li&gt;
&lt;li&gt;add a trailing \t in the input data&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The Go stdlib is quite extensive, and often has everything you need.  This makes “go run” a nice solution for scripting tasks.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Old Partitions
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x1c0000       1.75          14
    mtd2  uboot env    0x240000     0x40000       0.25           2
    mtd3      linux    0x280000    0xa00000         10          80
    mtd4     rootfs    0xc80000  0x186a0000    390.625        3125
    mtd5       data  0x19320000  0x26ce0000    620.875        4967
total size = 0x40000000, 1024MiB

New Partitions 500MB
  Device       Name       Start    Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0    0x80000        0.5           4
    mtd1      uboot     0x80000   0x500000          5          40
    mtd2  uboot env    0x580000    0x40000       0.25           2
    mtd3     linux1    0x5c0000  0x1400000         20         160
    mtd4     linux2   0x19c0000  0x1400000         20         160
    mtd5    rootfs1   0x2dc0000  0xa000000        160        1280
    mtd6    rootfs2   0xcdc0000  0xa000000        160        1280
    mtd7        log  0x16dc0000   0xa00000         10          80
    mtd8       data  0x177c0000  0x7c40000     124.25         994
total size = 0x1f400000, 500MiB

size of boot partitions:  45.75 MiB

New Partitions 1G
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x500000          5          40
    mtd2  uboot env    0x580000     0x40000       0.25           2
    mtd3     linux1    0x5c0000   0x1400000         20         160
    mtd4     linux2   0x19c0000   0x1400000         20         160
    mtd5    rootfs1   0x2dc0000   0xfa00000        250        2000
    mtd6    rootfs2  0x127c0000   0xfa00000        250        2000
    mtd7        log  0x221c0000   0x3200000         50         400
    mtd8       data  0x253c0000  0x1ac40000     428.25        3426
total size = 0x40000000, 1024MiB

size of boot partitions:  45.75 MiB

New Partitions 2G
  Device       Name       Start     Size(B)  Size(MiB)  Size(Blks)
    mtd0    xloader         0x0     0x80000        0.5           4
    mtd1      uboot     0x80000    0x500000          5          40
    mtd2  uboot env    0x580000     0x40000       0.25           2
    mtd3     linux1    0x5c0000   0x1400000         20         160
    mtd4     linux2   0x19c0000   0x1400000         20         160
    mtd5    rootfs1   0x2dc0000  0x1f400000        500        4000
    mtd6    rootfs2  0x221c0000  0x1f400000        500        4000
    mtd7        log  0x415c0000   0x6400000        100         800
    mtd8       data  0x479c0000  0x38640000     902.25        7218
total size = 0x80000000, 2048MiB

size of boot partitions:  45.75 MiB
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt; &lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Docker for OE&#x2F;Yocto builds</title>
        <published>2016-04-21T00:00:00+00:00</published>
        <updated>2016-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1281/using-docker-for-oeyocto-builds/"/>
        <id>https://bec-systems.com/1281/using-docker-for-oeyocto-builds/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1281/using-docker-for-oeyocto-builds/">&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2016&#x2F;04&#x2F;docker_small_h-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2016&#x2F;04&#x2F;docker_small_h-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Why Docker?  When using OE to build software for products, we often run into the scenario where software needs to be built using the same version of OpenEmbedded over the course of several years.  Production builds need to be predictable.  We’ve also observed that old versions of OE often break as new Linux distros come out.  This is just the result of the complexity of building tool chains.  Additionally, for predictable builds you really don’t want to be changing the build OS.  This requirement automatically rules out Arch Linux, Debian Unstable, Gentoo, etc as production build machines.  Additionally, having developers debug OE build issues on varying workstation distributions is frustrating and time consuming.&lt;&#x2F;p&gt;
&lt;p&gt;There are several options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keep a golden build machine around with a fixed OS&lt;&#x2F;li&gt;
&lt;li&gt;do builds in cloud on a machine with a fixed OS&lt;&#x2F;li&gt;
&lt;li&gt;build in a systemd-nspawn, or chroot&lt;&#x2F;li&gt;
&lt;li&gt;build in a virtual machine (Virtualbox, etc)&lt;&#x2F;li&gt;
&lt;li&gt;use Docker&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have used all of the above and recently started experimenting with Docker.  As an example, I set up a container named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;cbrake&#x2F;oe-build&#x2F;&quot;&gt;cbrake&#x2F;oe-build&lt;&#x2F;a&gt; and provided an example of how to use a Debian based container for OE builds.&lt;&#x2F;p&gt;
&lt;p&gt;Docker requires a bit of a mind-shift from virtual machines.  The 1st aha moment with Docker comes when you realize data and build directories should be mapped from the host into the container such that the container does not really have any state.  There are no ssh keys, etc in the container.  This allows the container to be immutable and easily replicated across any number of machines.  Stuff that needs to change goes in your build directory and is managed using Git.  Users specific information lives on your host machine.&lt;&#x2F;p&gt;
&lt;p&gt;The 2nd aha moment with Docker is running commands with Docker instead of working in the context of Docker.  For years, I have run OE builds in a systemd-nspawn.  I’d always have two terminal windows open – one for the container context, and one for the host.  With Docker, you typically just work in your host context, and spin up a Docker container every time you need to run a command in the container (bitbake, etc).  If you define a few shell functions to wrap the docker commands, you hardly even know that commands are executing in the container.  This might seem impractical, but it actually works quite well.  Of course you can still run a container shell and work in the context of the container if you want, but its not really necessary or desired once you get the container set up.&lt;&#x2F;p&gt;
&lt;p&gt;Docker is a neat tool and allows you to have a consistent environment for developer and production build machines.  It also encourages a natural separation of immutable containers and transient data that makes it much simpler to manage and distribute containers.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up a Go development environment</title>
        <published>2016-04-15T00:00:00+00:00</published>
        <updated>2016-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1275/setting-up-a-go-development-environment/"/>
        <id>https://bec-systems.com/1275/setting-up-a-go-development-environment/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1275/setting-up-a-go-development-environment/">&lt;p&gt;Go has a pretty neat development environment, and its helpful to set up a standard GOPATH on your workstation up front.  This is what I do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;mkdir ~&#x2F;go&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;add the following to .bashrc (or some file that configures your env on login)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;export GOPATH=~&#x2F;go&lt;&#x2F;li&gt;
&lt;li&gt;export PATH=$GOPATH&#x2F;bin:$PATH&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, after you log in, you can do things like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;go get -u github.com&#x2F;monochromegane&#x2F;the_platinum_searcher&#x2F;...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;go get -u github.com&#x2F;schachmat&#x2F;wego
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;(set up wego with forcast developer key)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;godoc.org&#x2F;&quot;&gt;lots of&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gowalker.org&#x2F;&quot;&gt;Go apps&lt;&#x2F;a&gt; out there and if you just set up a global GOPATH, they are trivial to install and use anywhere on your system!  Generally your ~&#x2F;go directory is also used for Go development projects, but that is a topic for another day.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go Language for Embedded ARM Linux Systems</title>
        <published>2016-03-08T00:00:00+00:00</published>
        <updated>2016-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/"/>
        <id>https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1269/go-language-for-embedded-arm-linux-systems/">&lt;p&gt;In the quest for technologies that work well for embedded Linux systems, I recently gave Go another try.  The &lt;a href=&quot;&#x2F;579&#x2F;the-go-language-for-embedded-systems&#x2F;&quot;&gt;last time&lt;&#x2F;a&gt;I tried this was very early on and there were some floating point issues on ARM that appear to be fixed now.  Having spent a few days porting an existing application to Go, there is a lot to like about Go.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Compiles very fast&lt;&#x2F;li&gt;
&lt;li&gt;Nice set of default libraries that are nice to use&lt;&#x2F;li&gt;
&lt;li&gt;Binaries are reasonable size&lt;&#x2F;li&gt;
&lt;li&gt;Memory usage is reasonable&lt;&#x2F;li&gt;
&lt;li&gt;Very simple to deploy (run time and libs are bundled with a single executable)&lt;&#x2F;li&gt;
&lt;li&gt;many 3rd party libraries available&lt;&#x2F;li&gt;
&lt;li&gt;Tooling is good (build, unit testing, etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example of running a Go app on an embedded Linux system, enter the following in hello.go:&lt;&#x2F;p&gt;
&lt;p&gt;package main&lt;&#x2F;p&gt;
&lt;p&gt;import (&lt;&#x2F;p&gt;
&lt;p&gt;“fmt”&lt;&#x2F;p&gt;
&lt;p&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;func main() {&lt;&#x2F;p&gt;
&lt;p&gt;fmt.Println(“Hello”);&lt;&#x2F;p&gt;
&lt;p&gt;}&lt;&#x2F;p&gt;
&lt;p&gt;To run on x86:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;go run Hello.go
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To build for ARM Linux:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ GOARCH=arm GOARM=5 go build hello.go
$ file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, cross compiling is very easy with Go.&lt;&#x2F;p&gt;
&lt;p&gt;Now, to try this exe on a Raspberry PI 3 running Arch Linux:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[root@alarmpi ~]# .&#x2F;hello
Hello
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did notice the time to build for ARM is a bit longer than building for x86:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ time go build hello.go

real	0m0.262s
user	0m0.337s
sys	0m0.030s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;$ time GOARCH=arm GOARM=5 go build hello.go
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;real	0m2.533s
user	0m4.930s
sys	0m0.183s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, still pretty reasonable considering what all it is doing.  The simplicity of all this is very attractive.  There is no runtime to cross compile and deploy.  Just one executable and you’re good to Go.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IOT Protocols: MQTT vs CoAP vs HTTP</title>
        <published>2015-12-11T00:00:00+00:00</published>
        <updated>2015-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/"/>
        <id>https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1200/iot-protocols-mqtt-vs-coap-vs-http/">&lt;p&gt;With the explosion of IOT (Internet of things), there are now more technologies we can use to build systems.  In reality, we’ve been doing IOT for years.  We’ve been networking devices for a long time.  We’ve been collecting data from remote nodes.  This is nothing new, but what the IOT movement brings to the table is technologies that are much lower cost, and more standardized.  Two of these technologies are MQTT and CoAP.  Both very interesting, and very useful.  Recently, I helped a system manufacturer think through the architecture of a system with the following requirements:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;They plan to sell a relatively small number (200-1000) of fairly expensive machines ($5,000-$10,000).  The point here is we are not dealing with millions of $10 nodes, which is really the vision of IOT.&lt;&#x2F;li&gt;
&lt;li&gt;There might be as many as a dozen machines installed in each location.&lt;&#x2F;li&gt;
&lt;li&gt;Users of these machines need to monitor them remotely.  The manufacturer would also like to monitor them for diagnostics and customer support.&lt;&#x2F;li&gt;
&lt;li&gt;The machines can be connected to the Internet at the install sites.&lt;&#x2F;li&gt;
&lt;li&gt;These machines are installed at various locations where the manufacturer doesn’t have much control over the network (firewall, filtering, which ports are blocked, etc).&lt;&#x2F;li&gt;
&lt;li&gt;The machines don’t need to talk to each other.&lt;&#x2F;li&gt;
&lt;li&gt;It should be relatively difficult to hack into a machine and mess up what it is doing.&lt;&#x2F;li&gt;
&lt;li&gt;Data will be mostly going from machines to the cloud.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are several ways to address these requirements, but one of the simplest today is for each machine to talk to a server in the cloud, and then users monitor and control the machines through a web application running in the cloud.  The web application can be designed to be viewed on both personal computers and mobile devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;12&#x2F;IOT-protocols-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;12&#x2F;IOT-protocols-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the question is which protocol do we use to communicate from the installed machines to the cloud?  In this case, we really do not need a lot of efficiency, as the number of nodes is relatively small.  Bandwidth requirements are not really a huge concern because a) the number of nodes is relatively small, and b) we can use the existing broadband infrastructure at the install sites.  While it might be interesting to use one of the new protocols like MQTT or CoAP, we need to carefully consider them in the context of requirement #5 – we don’t have control over what ports are blocked or what type of filtering&#x2F;proxying happens at the install site.  Support costs can run very high debugging networking problems at remote locations.  Because MQTT and CoAP typically use non-standard ports, they are less attractive for this application.  Even if we did run MQTT or CoAP over port 80, the install site might have internet filters or proxies that would reject non HTTP data.  So this puts us back to HTTP, perhaps with a REST implementation.  As it turns out, this is not a bad way to go.  Even though HTTP is old, it is still a perfectly valid protocol for this application.  Some of the advantages include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP is the most compatible with existing network infrastructure, and you are pretty much guaranteed HTTP will work.  If a web browser works, then machines in this scenario should be able to send data to the cloud.&lt;&#x2F;li&gt;
&lt;li&gt;Stateless HTTP&#x2F;REST will traverse firewalls and NAT systems easily.  Again, web browsers work.&lt;&#x2F;li&gt;
&lt;li&gt;Because the Machines initiate the connection to the server (users are not connecting directly to a browser on the machine), the machines are much easier to secure.  Thy don’t even need any open ports.  Most of the security effort in this system only needs to be focused in one place (cloud server).&lt;&#x2F;li&gt;
&lt;li&gt;HTTP provides well understood authentication and encryption mechanisms.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are other applications where MQTT or CoAP might make more sense.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In a system connected via cellular modems where data is very expensive, you might want to consider CoAP, because it can use UDP which eliminates the overhead of TCP&#x2F;IP, which is significant (both MQTT and HTTP require TCP&#x2F;IP).  Especially if you have 1000’s of nodes, and are trying to keep the monthly usage of each one under 5MB.&lt;&#x2F;li&gt;
&lt;li&gt;If the various machines need to talk to each other, then MQTT would be a good choice.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While I’d like to use MQTT or CoAP, in this application I’m going to recommend they stick with HTTP(S).  Even though MQTT might be more convenient to work with, the support costs of debugging network issues at install sites will probably swamp any advantages during development.  This project can benefit from the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.esp8266.com&#x2F;&quot;&gt;host of&lt;&#x2F;a&gt; Wifi &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.arduino.cc&#x2F;en&#x2F;Main&#x2F;ArduinoMKR1000&quot;&gt;enabled&lt;&#x2F;a&gt; microcontroller &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.particle.io&#x2F;&quot;&gt;systems&lt;&#x2F;a&gt;, low cost &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxgizmos.com&#x2F;tiny-iot-sbc-runs-openwrt-on-mediatek-mips-soc&#x2F;&quot;&gt;embedded Linux&lt;&#x2F;a&gt; technologies, or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AdisonTech&quot;&gt;cloud technologies&lt;&#x2F;a&gt; aimed at IOT systems.  All of these support HTTP just fine.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded &#x2F; Yocto Usage Survey</title>
        <published>2015-11-18T00:00:00+00:00</published>
        <updated>2015-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1175/openembedded-yocto-usage-survey/"/>
        <id>https://bec-systems.com/1175/openembedded-yocto-usage-survey/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1175/openembedded-yocto-usage-survey/">&lt;p&gt;Recently, I sent a survey to the OpenEmbedded and Yocto mail lists asking a series of questions about how they use OE.  38 people responded.  The average number of years using OE is 4.8 years.&lt;&#x2F;p&gt;
&lt;p&gt;Below are the results of the questions.  (update 2015-11-23 – the below numbers are absolute numbers, not percentage)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart1-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart1-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart2-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart3-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart3-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart4-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart4-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart5-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart5-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart61-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart61-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart7-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart7-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart8-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart8-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart9-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart9-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart10-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;chart10-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On the question about tooling, 4 people responded they use Toaster (two specified toaster analysis mode).  Two use devtool.  One uses ADT.&lt;&#x2F;p&gt;
&lt;p&gt;I plan to follow up with additional articles discussing some of these results.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to all who responded to this survey.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rebasing a set of changes with Git</title>
        <published>2015-11-11T00:00:00+00:00</published>
        <updated>2015-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/"/>
        <id>https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1159/rebasing-a-set-of-changes-with-git/">&lt;p&gt;One of the common things we do during Linux kernel development is move a series of patches from one kernel version to a similar version (say Linux 4.1 to 4.1.12).  This is required as new stable versions of particular kernel version are released.  One approach is to merge, but then your changes are mixed in with upstream commits and are more difficult to manage.  Git rebase offers a convenient way to move a set of patches.  In the following example we have a series of changes we made (or patches we applied) on top of the 4.1 kernel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git1-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git1-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now we want to move the same patchset to the 4.1.12 stable kernel.  To do this, we can use the following commands:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;git checkout -b 4.1.12-armv7-x0-dugen2 4.1-armv7-x0-dugen2 (create a new branch that will be rebased)&lt;&#x2F;li&gt;
&lt;li&gt;git rebase --onto v4.1.12 v4.1 4.1.12-armv7-x0-dugen2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A few details on the git rebase arguments:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;--onto v4.1.12  (this tells git what version we want to move our changes to)&lt;&#x2F;li&gt;
&lt;li&gt;v4.1 (upstream – tells git where our patchset starts)&lt;&#x2F;li&gt;
&lt;li&gt;4.1.12-armv7-x0-dugen2 (branch – is the branch to do the operation on)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After the rebase, our patchset looks very similar, only on top of the 4.1.12 kernel version.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git2-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2015&#x2F;11&#x2F;git2-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It this example (which included many more patches than shown above), I only encountered one conflict which was easy to resolve.  This process can also be used to move a patchset to a new kernel version (say 4.2, or 4.3), but you would obviously expect more conflicts.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Modifying the BusyBox config in OpenEmbedded</title>
        <published>2015-09-30T00:00:00+00:00</published>
        <updated>2015-09-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/"/>
        <id>https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1145/modifying-the-busybox-config-in-openembedded/">&lt;p&gt;Recently, I needed to enable the &lt;em&gt;eject&lt;&#x2F;em&gt; command in BusyBox for an OpenEmbedded (Yocto) based project.  Below is a way to do this in a fairly painless way:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;bitbake -c menuconfig busybox (enable the eject command in the config and save)&lt;&#x2F;li&gt;
&lt;li&gt;bitbake -c diffconfig busybox (this generates a config fragment, note the fragment file location)&lt;&#x2F;li&gt;
&lt;li&gt;recipetool appendsrcfile -w [path to layer] busybox [path to fragment generated in step #2]&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now, in my project layer, I have the following files:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;recipes-core&#x2F;busybox&#x2F;busybox_%.bbappend:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI += &amp;quot;file:&#x2F;&#x2F;fragment.cfg&amp;quot;
FILESEXTRAPATHS_prepend := &amp;quot;${THISDIR}&#x2F;${PN}:&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;recipes-core&#x2F;busybox&#x2F;busybox&#x2F;fragment.cfg:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# Wed Sep 30 15:23:49 2015
CONFIG_EJECT=y
CONFIG_FEATURE_EJECT_SCSI=y
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wow, that is pretty neat!  The same procedure should work on kernel recipes as well.&lt;&#x2F;p&gt;
&lt;p&gt;Notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If you have trouble running &lt;em&gt;bitbake -c menuconfig&lt;&#x2F;em&gt; in a remote ssh shell, trying installing screen on the build machine.&lt;&#x2F;li&gt;
&lt;li&gt;recipetool is located in &lt;em&gt;openembedded-core&#x2F;scripts&#x2F;recipetool&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;&quot;&gt;Chris L.&lt;&#x2F;a&gt; noted the -w option in recipetool would have simplified the append slightly (would avoid the subdir= on the SRC_URI, since it’d install it to workdir instead of the source tree)   Great idea – example above modified to include -w.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for using CMake in OpenEmbedded&#x2F;Yocto</title>
        <published>2015-03-10T00:00:00+00:00</published>
        <updated>2015-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/"/>
        <id>https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1128/best-practices-for-using-cmake-in-openembeddedyocto/">&lt;p&gt;I’ve already written about using &lt;a href=&quot;&#x2F;509&#x2F;best-practices-for-building-gtk-applications-with-openembedded&#x2F;&quot;&gt;autotools&lt;&#x2F;a&gt; and &lt;a href=&quot;&#x2F;501&#x2F;best-practices-for-building-qt-applications-with-openembedded&#x2F;&quot;&gt;qmake&lt;&#x2F;a&gt; in OE.  With recent projects, we’re using CMake to build most C&#x2F;C++ components.  Like any good tool, CMake has a learning curve, but it seems to do its job quite well.  Below are examples of a CMake build file, and corresponding OE recipe.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;CMakeLists.txt&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cmake_minimum_required(VERSION 2.8)
project(MyApp)
file(GLOB_RECURSE src&#x2F;*.cpp)
add_executable(MyAPP ${src_files})
target_link_libraries(MyApp pthread)
install(TARGETS MyApp DESTINATION bin)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;myapp.bb (OE recipe)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DESCRIPTION = “My xyz app” LICENSE = “CLOSED” inherit cmake SRCREV = “${AUTOREV}” PV = “1.1+gitr${SRCPV}” SRC_URI = “git:&#x2F;&#x2F;my-git-server&#x2F;myapp.git;branch=master;protocol=ssh;user=git” S = “${WORKDIR}&#x2F;git” BBCLASSEXTEND = “native”&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Notice the OE recipe above has no build&#x2F;install logic other than “inherit cmake”.&lt;&#x2F;p&gt;
&lt;p&gt;Below are some tips on using CMake.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;put your source files in a src directory.  This allows you to easily build a list by using GLOB patterns.  If you put the source files in the root directory of your application source, then the GLOB pattern will also find temporary C files that CMake generates, and you’ll get multiple “main” errors.  Some recommend against using GLOB patterns for finding source files because it may miss additions, but in practice I find the benefits of this pattern outweigh the negatives.&lt;&#x2F;li&gt;
&lt;li&gt;do all install operations in CMake if possible (vs do_install in the OE recipe).  The reason for this is its &lt;strong&gt;much&lt;&#x2F;strong&gt; easier to debug install in CMake then OE.  You can build the app for x86 on your workstation, run “make install” and easily verify the files get installed correctly.  Typically, things get installed in &#x2F;usr&#x2F;local when building on your workstation, and &#x2F;usr when built in the context of OE.&lt;&#x2F;li&gt;
&lt;li&gt;do most of your development on your workstation.  Most of the time, you can test 99% of an application’s functionality on your workstation.  Do what you can there with unit tests where development is much faster and easier.&lt;&#x2F;li&gt;
&lt;li&gt;change ownership of &#x2F;usr&#x2F;local by running “&lt;em&gt;sudo chown -R $USER &lt;a href=&quot;&#x2F;usr&#x2F;local&quot;&gt;&#x2F;usr&#x2F;local&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;”.  This allows you to run “make install” of the CMake project during development without sudo.  It also helps ensure you are not accidentally installing stuff outside &#x2F;usr&#x2F;local.&lt;&#x2F;li&gt;
&lt;li&gt;you don’t need to add header files to the target sources.  CMake automatically figures out include dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;you can run “&lt;em&gt;make VERBOSE=1”&lt;&#x2F;em&gt; to see the commands make is running during a compile.&lt;&#x2F;li&gt;
&lt;li&gt;cmake -DCMAKE_BUILD_TYPE=Debug can be used to add debugging information (essentially -g).&lt;&#x2F;li&gt;
&lt;li&gt;When developing on your workstation, do the following to build: &lt;em&gt;mkdir build; cd build; cmake ..&#x2F;; make&lt;&#x2F;em&gt; The advantage of running cmake inside a &lt;em&gt;build&lt;&#x2F;em&gt; directory is you can simply wipe the entire build dir to completely reset the build.  Otherwise, the cmake files are mixed up with your source files.&lt;&#x2F;li&gt;
&lt;li&gt;The following is the CMake version of printf – very useful for debugging: &lt;em&gt;message(some_var: ${some_var})&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;ccmake&lt;&#x2F;em&gt; and &lt;em&gt;cmake-gui&lt;&#x2F;em&gt; are useful tools for examining the state of various CMake variables.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Most of these tips are general and have nothing to do with OE, but that is the entire point – using CMake with OE rarely requires you to do anything beyond what you normally do with CMake.  So, if you use CMake correctly, there is usually not a lot more required to cross compile and package your apps in OE.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PCB Schematics Style Guide</title>
        <published>2014-08-25T00:00:00+00:00</published>
        <updated>2014-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1116/schematics-style/"/>
        <id>https://bec-systems.com/1116/schematics-style/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1116/schematics-style/">&lt;p&gt;As I work at the intersection of hardware and software, I spend a fair amount of time reading schematics for printed circuit boards (PCBs).  I’m astounded at how sloppy most schematics are, and have come up with a few suggestions to consider.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Schematics are not only design entry – &lt;strong&gt;schematics are documentation&lt;&#x2F;strong&gt;.  Unless you are writing all the software, handling all the manufacturing, and debugging all field issues yourself, there will be others who will be using them.  Be considerate.&lt;&#x2F;li&gt;
&lt;li&gt;Not everyone has a D size plotter (even B size printers are fairly rare).  I have a rather large (27“, 2560x1140) monitor, and have seen schematics that I have to zoom in to read.  Schematics should be created such that they &lt;strong&gt;can be printed on letter size paper&lt;&#x2F;strong&gt; (everyone has a letter size printer), and easily read – even by folks in their 60’s.  This is fairly simple – just spend some time breaking large symbols into smaller sections, and use a few more pages.  Even for viewing on a screen, putting &lt;strong&gt;less stuff on each page&lt;&#x2F;strong&gt; makes it easier to scroll through pages.  Most people print out schematics for review or bench work – so having letter size pages makes this possible.&lt;&#x2F;li&gt;
&lt;li&gt;Schematics should be organized to have &lt;strong&gt;one function per page&lt;&#x2F;strong&gt;, or group similar functions on a page.  Don’t intermix power supplies and an audio codec unless they are related.  We realize the importance of organizing software in modules, and a large schematic is really no different.&lt;&#x2F;li&gt;
&lt;li&gt;Keep &lt;strong&gt;all pages the same size&lt;&#x2F;strong&gt;.  When every page is a different size, you can’t easily scroll through pages, or print them out.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Avoid hierarchical schematics&lt;&#x2F;strong&gt;.  For most PCB designs, hierarchical schematics offer no advantage over a flat schematic logically organized on pages.  PCB’s can only be so big, therefore even if you have 20 pages for a schematic, 20 pages is really not all that much, and adding hierarchy to 20 pages just adds complexity and makes them harder to read.  In a sense, your schematic page becomes a “hierarchical block.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Off page references&lt;&#x2F;strong&gt; are the key to making smaller schematic pages work.&lt;&#x2F;li&gt;
&lt;li&gt;Spend a little more time &lt;strong&gt;putting a little art&lt;&#x2F;strong&gt; into your schematic symbols.  If you have a DB-9 connector, and you draw a connector in the shape of a DB-9 (only takes a few more minutes), then you can instantly recognize what it is in the schematic, and it is much quicker to find the circuit you are looking for during debugging sessions.  The same can be said for USB connectors, etc.  In some cases, it may make sense to draw a connector symbol to match how it looks physically, so you can quickly find a pin on the bench without digging out a datasheet.&lt;&#x2F;li&gt;
&lt;li&gt;Schematic text must &lt;strong&gt;be easily searchable&lt;&#x2F;strong&gt;.  I don’t want to install a clunky schematic viewer that only runs on X.XX version of windows just to search for text.  I want to use the PDF reader I already have installed.  Make sure schematics are cleanly exported to PDF, and are easy to search.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I’m sure there are many other ideas – in a brief search, I turned up the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.upverter.com&#x2F;schematic-style-guide&quot;&gt;http:&#x2F;&#x2F;blog.upverter.com&#x2F;schematic-style-guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.k-state.edu&#x2F;ksuedl&#x2F;publications&#x2F;Technote%208%20-%20Guidelines%20for%20Drawing%20Schematics.pdf&quot;&gt;http:&#x2F;&#x2F;www.k-state.edu&#x2F;ksuedl&#x2F;publications&#x2F;Technote%208%20-%20Guidelines%20for%20Drawing%20Schematics.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;electronics.stackexchange.com&#x2F;questions&#x2F;28251&#x2F;rules-and-guidelines-for-drawing-good-schematics&quot;&gt;http:&#x2F;&#x2F;electronics.stackexchange.com&#x2F;questions&#x2F;28251&#x2F;rules-and-guidelines-for-drawing-good-schematics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Library sizes for C vs C++ in an embedded Linux system</title>
        <published>2013-12-18T00:00:00+00:00</published>
        <updated>2013-12-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/"/>
        <id>https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1107/library-sizes-for-c-vs-c-in-an-embedded-linux-system/">&lt;p&gt;Is the size of the libraries required for C++ (vs C) a concern in Embedded Linux systems?  Most Embedded Linux systems likely include some C++ code, so this is probably not even a decision we need to make in many cases.  However, often there is a need for a small initramfs that is used as part of the boot process (perhaps for software updates) before switching to the main root file system.  In this case, it makes sense to keep the initramfs as small as possible, and we might be concerned here with the size of C++ libraries.&lt;&#x2F;p&gt;
&lt;p&gt;To find out what additional libraries are required when compiling with a C++ compiler vs C, a simple hello-world app was created.  It was then compiled with gcc and g++.  The outputs were then parsed with readelf to determine the required dynamic libraries.  The results are shown below:&lt;&#x2F;p&gt;
&lt;p&gt;C:&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;C++:&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]&lt;&#x2F;p&gt;
&lt;p&gt;0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]&lt;&#x2F;p&gt;
&lt;p&gt;The sizes of packages for these libraries in an OpenEmbedded build are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;libc: 1.4KiB (libm is inlcuded with libc)&lt;&#x2F;li&gt;
&lt;li&gt;libstdc++6: 256KiB&lt;&#x2F;li&gt;
&lt;li&gt;libgcc1: 204KiB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(The above sizes are compressed, so the actually will be some larger, but are useful for comparison.)&lt;&#x2F;p&gt;
&lt;p&gt;The installed sizes of libstdc++6 and libgcc1 on a ext3 file system are 1.4MiB and 750KiB.&lt;&#x2F;p&gt;
&lt;p&gt;It may also take slightly longer to load a C++ application as there is time required to dynamically load and link additional libraries.  Is an extra 2MiB of libraries a big deal?  It depends on your situation, but should be considered any time you are trying to create a small image.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up an OpenEmbedded Package Feed Server</title>
        <published>2013-12-11T00:00:00+00:00</published>
        <updated>2013-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/"/>
        <id>https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1085/setting-up-an-openembedded-package-feed-server/">&lt;p&gt;With the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OE build template&lt;&#x2F;a&gt;, you can easily set up an opkg feed server that serves up packages from your build directory.  This allows you to easily install new packages during development, without generating and reflashing an entire image.  To use:&lt;&#x2F;p&gt;
&lt;p&gt;On workstation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;edit local.sh, and define MACHINE_IP to point to your target machine, and re-run “source envsetup.sh”.  Alternatively, you can export the MACHINE_IP variable in your environment.&lt;&#x2F;li&gt;
&lt;li&gt;run: oe_setup_feed_server&lt;&#x2F;li&gt;
&lt;li&gt;run: oe_feed_server&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg update&lt;&#x2F;li&gt;
&lt;li&gt;opkg install &lt;some package&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Opkg will install dependencies, so if you have a complex package, this is so much easier than copying over an opkg file manually, and figuring out you need 6 other packages as dependencies.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why systemd in Embedded Linux Systems?</title>
        <published>2013-12-11T00:00:00+00:00</published>
        <updated>2013-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/"/>
        <id>https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1098/why-systemd-in-embedded-linux-systems/">&lt;p&gt;Recently I was asked why use systemd vs sysvinit in embedded systems?  There are many discussions on this, and really most of the reasons people use it for servers and desktops are also valid for embedded systems.  Lennart Poettering’s &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;0pointer.de&#x2F;blog&#x2F;projects&#x2F;why.html&quot;&gt;articles&lt;&#x2F;a&gt; explain very well why you might want to consider systemd.  A few things that rank high on my list:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;systemd systems generally boot must faster than sysvinit systems.&lt;&#x2F;li&gt;
&lt;li&gt;systemd monitors every process it starts, so you know conclusively if your app is still running.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has flexible mechanisms for restarting apps that crash, and rebooting if you get so many restarts in X amount of time.  This is very important in embedded systems where you need to keep things running.&lt;&#x2F;li&gt;
&lt;li&gt;systemd logging (journald) is very flexible.  The stdout of every process that is started by systemd is captured in the journal.  You can also capture kernel messages in the journal.  The end result is you have one place to look for system logs.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has support for &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;0pointer.de&#x2F;blog&#x2F;projects&#x2F;watchdog.html&quot;&gt;watchdog chaining&lt;&#x2F;a&gt; – again, important for many embedded systems.&lt;&#x2F;li&gt;
&lt;li&gt;The systemd dependency mechanism is very flexible.&lt;&#x2F;li&gt;
&lt;li&gt;systemd has tools to debug the init process: systemd-analyze, systemd-cgls, systemd-cgtop, bootchart, pybootchargui, etc.&lt;&#x2F;li&gt;
&lt;li&gt;on demand launch of services can improve boot time and conserve resources.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In summary, with systemd I have more control over the system startup and shutdown, and have better mechanisms to monitor things to make sure they stay running.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template</title>
        <published>2013-06-28T00:00:00+00:00</published>
        <updated>2013-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1047/openembedded-build-template/"/>
        <id>https://bec-systems.com/1047/openembedded-build-template/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1047/openembedded-build-template/">&lt;p&gt;How does one set an OpenEmbedded&#x2F;Yocto&#x2F;Poky&#x2F;Angstrom build? There are many options. Some include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;angstrom-distribution&#x2F;setup-scripts&quot;&gt;Angstrom setup scripts&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.yoctoproject.org&#x2F;cgit&#x2F;cgit.cgi&#x2F;poky&#x2F;&quot;&gt;Poky&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Freescale&#x2F;fsl-community-bsp-platform&quot;&gt;Freescale Community BSP&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;wiki&#x2F;OE-Core_Standalone_Setup&quot;&gt;OpenEmbedded core standalone&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(I’m sure there are many others, feel free to add in comments …)&lt;&#x2F;p&gt;
&lt;p&gt;Over the past years, we’ve supported a number of customers using OpenEmbedded to develop products using various SOC’s. We also try to keep builds going for a number of different systems so that we can continuously evaluate the state of OpenEmbedded and related Embedded Linux technologies. We also needed a standard way to set up builds for customers (some don’t have a lot of experience with OE and Git) that is simple and consistent. What we ended up with is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&quot;&gt;BEC OpenEmbedded build template&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to have a quick entry point into OpenEmbedded that includes the necessary layers for a number of different machines, and automates a number of routine tasks such as installing images to a SD card, setting up a development feed server, etc. The build template is only updated when the build is stable and tested on a number of machines, so it provides a series of stable snapshots of OpenEmbedded and associated layers.&lt;&#x2F;p&gt;
&lt;p&gt;This build template currently tracks the master branches for all the layers used. This gives us a platform to track the latest OE changes. With most projects, that ability to use the features in the latest versions of software outweighs the stability benefits of OpenEmbedded release branches. There are times when the OpenEmbedded project goes through invasive changes (such as the systemd integration), and using the master branches is not practical, so in this case we simply use the last stable snapshot that builds and works. In most cases if there are issues, simply report or fix the issue and wait a week.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps the most controversial decision is the use of Git submodules for including OpenEmbedded layers. The Internet is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;somethingsinistral.net&#x2F;blog&#x2F;git-submodules-are-probably-not-the-answer&#x2F;&quot;&gt;full&lt;&#x2F;a&gt; of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;Git-Tools-Subtree-Merging&quot;&gt;rants&lt;&#x2F;a&gt; against Git submodules. For heavy developer use, submodules may not be optimal. However, from a user perspective, Git submodules provide a simple mechanism for including external repositories in a project. If most of the submodules (OE layers) won’t be touched (typical OE user scenario), submodules work very well. The fact that Git locks down submodules to a specific commit ensures you are getting exactly what you think you are getting (vs a branch that may have been rebased, modified etc). If the git hash matches, you can be pretty sure it is the same as the last time you built it. This is an important factor in production build systems where you want to be sure of what you are building. Google repo is another option under consideration, but there are still some trade-offs to work through.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, build systems are very personal, and must be customized for your product and development team. The number one requirement for a an Embedded Linux build system is that you can get repeatable builds with a single command. There must be no manual steps where human error can be introduced. This is just one way to accomplish this goal.&lt;&#x2F;p&gt;
&lt;p&gt;(2023-09-05 update: the BEC OE Build template has been replaced by the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoedistro.org&#x2F;&quot;&gt;Yoe Distribution&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OS Containers for Build Systems</title>
        <published>2013-05-08T00:00:00+00:00</published>
        <updated>2013-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1029/os-containers-for-build-systems/"/>
        <id>https://bec-systems.com/1029/os-containers-for-build-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1029/os-containers-for-build-systems/">&lt;p&gt;Since I’ve been running archlinux on some of my systems, one thing I’ve found useful is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;systemd-nspawn.html&quot;&gt;systemd-nspawn&lt;&#x2F;a&gt;. systemd-nspawn containers (or chroots on non-systemd systems) give you a quick way to install a Linux distribution, that can run inside an existing Linux system.&lt;&#x2F;p&gt;
&lt;p&gt;Some cases where systemd-nspawn containers (referred to as containers in this document) are useful:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;At one point, OpenEmbedded would not build with GCC 4.8 (this is no longer the case with recent versions of OE).  So a Debian or Ubuntu OS container was a quick way to get builds going again.&lt;&#x2F;li&gt;
&lt;li&gt;For product build systems (may live for many years), typically OE will eventually break as you upgrade the workstation distribution.  For projects that need a long-lived OpenEmbedded build system, setting it up in a chroot makes a lot of sense.&lt;&#x2F;li&gt;
&lt;li&gt;Someone might be having a compile or build problem with a distribution you don’t currently have installed.  With containers, you can quickly set up a test distribution to reproduce problems.&lt;&#x2F;li&gt;
&lt;li&gt;I’ve had cases where I need an older version of Qt for a project, but my workstation includes a newer version.  Again, setting up a OS container is sometimes simpler than getting two versions of Qt to dwell together peaceably in the same distribution.&lt;&#x2F;li&gt;
&lt;li&gt;Backing up or replicating your entire build system is very easy – simply rsync the OS container directory to another machine.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;So the solution is to select a relatively stable, long-lived distribution to host your product builds. Debian is good choice.  Because the container is simply a directory in the host workstation filesystem, you can use host workstation tools (editors, git, etc) directly in the container filesystem.  The only thing you need to use the chroot for is the actual building.  If you make sure the user ID is the same between your workstation and nspawn container, then permissions are seamless – you can easily access files in the container from the context of your host workstation.&lt;&#x2F;p&gt;
&lt;p&gt;To set up a nspawn-container:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Install debootstrap.  On arch systems, this needs to be obtained for the AUR.&lt;&#x2F;li&gt;
&lt;li&gt;host: &lt;em&gt;sudo debootstrap --arch=amd64 wheezy ~&#x2F;debian-wheezy&#x2F;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;host: &lt;em&gt;sudo systemd-nspawn -D ~&#x2F;debian-wheezy&#x2F;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;apt-get update &amp;amp;&amp;amp; apt-get install ssh&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;edit &#x2F;etc&#x2F;ssh&#x2F;sshd_config, and set port to something other than 22 (23 in this example)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;container: &lt;em&gt;&#x2F;etc&#x2F;init.d&#x2F;ssh start&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;(This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;systemd-nspawn.html&quot;&gt;systemd-nspawn&lt;&#x2F;a&gt; man page gives examples for setting up other distributions.)&lt;&#x2F;p&gt;
&lt;p&gt;To set up a user in your container:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;host: id&lt;&#x2F;li&gt;
&lt;li&gt;will return something like: uid=1000(cbrake) gid=100(users) …&lt;&#x2F;li&gt;
&lt;li&gt;container: adduser --uid 1000 -gid 100 cbrake&lt;&#x2F;li&gt;
&lt;li&gt;host: ssh-copy-id -p 23 localhost (will copy public key to container)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now, on the host system, you can simply “&lt;em&gt;ssh -p23 localhost”&lt;&#x2F;em&gt; any time you want to log into the container.  Soft links between the project workspace on the host system, and the container can also make shifting between the two easier.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative way to start the container once its set up is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;sudo systemd-nspawn -D ~&#x2F;debian-wheezy &#x2F;sbin&#x2F;init&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Its also handy to make the shell prompt in the container slightly different than the host OS so that you can easily tell the difference.  To accomplish this, add the following to ~&#x2F;.profile in the container OS:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;export PS1=“[\u@wheezy \w]\$ “&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To create a service that starts your container, put something like the following in &#x2F;lib&#x2F;systemd&#x2F;system&#x2F;debian-wheezy.service&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Debian Wheezy
[Service]
ExecStart=&#x2F;usr&#x2F;bin&#x2F;systemd-nspawn -D &#x2F;scratch&#x2F;debian-wheezy&#x2F; &#x2F;sbin&#x2F;init 3
KillMode=process
[Install]
WantedBy=multi-user.target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hopefully this gives you a quick overview of how OS containers can be set up, and used in your OpenEmbedded build systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git submodules can now track branches</title>
        <published>2013-04-22T00:00:00+00:00</published>
        <updated>2013-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1020/git-submodules-can-now-track-branches/"/>
        <id>https://bec-systems.com/1020/git-submodules-can-now-track-branches/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1020/git-submodules-can-now-track-branches/">&lt;p&gt;As of version 1.8.2, Git submodules can now track branches instead of specific commits.  This is good news as in many cases, this is exactly the behavior we want.  However, Git submodules are still not as flexible as Google &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;git-repo&#x2F;&quot;&gt;repo&lt;&#x2F;a&gt;, but since submodules are built into Git, the submodule command is a good solution in many cases.&lt;&#x2F;p&gt;
&lt;p&gt;The “&lt;em&gt;git submodule update --remote&lt;&#x2F;em&gt;” command is the key to tracking branches with submodules.   The following is from the Git man pages:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;--remote
This option is only valid for the update command. Instead of using the superproject’s recorded SHA-1 to update the submodule, use the status of the submodule’s remote tracking branch. The remote used is branch’s remote (branch.&lt;name&gt;.remote), defaulting to origin. &lt;strong&gt;The remote branch used defaults to master, but the branch name may be overridden by setting the submodule.&lt;name&gt;.branch option in either .gitmodules&lt;&#x2F;strong&gt; or .git&#x2F;config (with .git&#x2F;config taking precedence).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;This works for any of the supported update procedures (--checkout, --rebase, etc.). The only change is the source of the target SHA-1. For example, submodule update --remote --merge will merge upstream submodule changes into the submodules, while submodule update --merge will merge superproject gitlink changes into the submodules.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;In order to ensure a current tracking branch state, update --remote fetches the submodule’s remote repository before calculating the SHA-1. If you don’t want to fetch, you should use submodule update --remote --no-fetch.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, if you already have a Git submodule set up, its a simple matter to run &lt;em&gt;git submodule update --remote&lt;&#x2F;em&gt; to update the submodule to the latest master branch.  If you want a different branch, simple edit &lt;em&gt;.gitconfig&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[submodule &amp;quot;meta-bec&amp;quot;]
   path = meta-bec
   url = git@github.com:cbrake&#x2F;meta-bec.git
   branch = test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, if you run *git submodule update --remote,*Git will update the &lt;em&gt;meta-bec&lt;&#x2F;em&gt; submodule to the latest on the &lt;em&gt;test&lt;&#x2F;em&gt; branch.&lt;&#x2F;p&gt;
&lt;p&gt;This functionality is purely a convenience feature in the &lt;em&gt;submodule update&lt;&#x2F;em&gt; command.  In the actual repository, Git still stores submodules pointed to a particular commit.  The same thing could be accomplished with something like &lt;em&gt;git foreach “git fetch &amp;amp;&amp;amp; git checkout test”&lt;&#x2F;em&gt;.  The branch option in .gitmodules functions more as documentation and convenience.  It is very handy to be able to look at .gitmodules and quickly determine that submodule X is tracking branch Y.  Normally, this would have to be documented elsewhere, or figured out in some other way.  Also, for build systems where you want the build to always track the production branches of various projects, &lt;em&gt;update --remote&lt;&#x2F;em&gt; gives you a convenient way to update the build tree.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick way to share files from any directory</title>
        <published>2013-01-22T00:00:00+00:00</published>
        <updated>2013-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/"/>
        <id>https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1015/a-quick-way-to-share-files-from-any-directory/">&lt;p&gt;Did you ever need a quick way to share files from a directory on your computer?  Or perhaps transfer a large file to another person?  With &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nodejs.org&#x2F;&quot;&gt;nodejs&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;expressjs.com&#x2F;&quot;&gt;express&lt;&#x2F;a&gt;, you can easily set up a temporary web server that allows users to browse and access a list of files in a directory.  For convenience, I created a simple &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&quot;&gt;github project&lt;&#x2F;a&gt; that can be cloned into any directory, and then a server started in a matter of seconds.  Yes, you could upload files to a server, or share them with a file sharing service, but if you can expose a random port on your computer to the person who needs the files, then this is faster, and does not require any intermediate steps.  Check out &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;http-file-server&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Source Mirrors</title>
        <published>2013-01-07T00:00:00+00:00</published>
        <updated>2013-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1010/openembedded-source-mirrors/"/>
        <id>https://bec-systems.com/1010/openembedded-source-mirrors/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1010/openembedded-source-mirrors/">&lt;p&gt;When using OpenEmbedded for product development, there are several reasons you may want to consider setting up a source mirror for your OpenEmbedded build:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;over time, sources disappear from download locations&lt;&#x2F;li&gt;
&lt;li&gt;various servers for source packages may be off-line at the time a build is run&lt;&#x2F;li&gt;
&lt;li&gt;some servers may be very slow, which slows down your build&lt;&#x2F;li&gt;
&lt;li&gt;occasionally the checksums of a source package will change&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a production build system, you want the build to be reliable and consistent, so this means not depending on 3rd party web sites&#x2F;servers for a clean build to complete.  Fortunately, OpenEmbedded makes it easy to set up a source mirror with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;1.0&#x2F;poky-ref-manual&#x2F;poky-ref-manual.html#idm1091472&quot;&gt;PREMIRRORS&lt;&#x2F;a&gt; variable. When bitbake tries to fetch source code, it tries PREMIRRORS, the upstream source, and then MIRRORS.  There are several advantages to using a PREMIRROR variable over a MIRROR for your source mirror:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;your source mirror will be used first, thus slow web sites are not an issue&lt;&#x2F;li&gt;
&lt;li&gt;if the checksums of the package change, the build will not fail because its still using the original source package from the mirror.  You are guaranteed to be always using the same source package.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Setting up a source mirror is as simple as copying the contents of your downloads directory to a web server, and then populating the following variable in local.conf:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PREMIRRORS_prepend = &amp;quot;\
     git:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     ftp:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     http:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n \
     https:&#x2F;&#x2F;.*&#x2F;.* http:&#x2F;&#x2F;my-server&#x2F;sources&#x2F; \n&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Poky reference manual has more &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;1.0&#x2F;poky-ref-manual&#x2F;poky-ref-manual.html#idm1091472&quot;&gt;details&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Perisistent device names for USB serial ports</title>
        <published>2012-12-19T00:00:00+00:00</published>
        <updated>2012-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/"/>
        <id>https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/</id>
        
        <content type="html" xml:base="https://bec-systems.com/1004/perisistent-device-names-usb-serial-ports/">&lt;p&gt;Currently, my workstation has &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;usbgear.com&#x2F;USB2-8COM-M.html&quot;&gt;two 8-port USB&amp;lt;-&amp;gt;RS232 devices&lt;&#x2F;a&gt;, one &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;usbgear.com&#x2F;USB-2COMi-M.html&quot;&gt;dual port USB&amp;lt;-&amp;gt;RS422&#x2F;RS485 adapter&lt;&#x2F;a&gt;, and several single port adapters such as the very useful &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;shop.moderndevice.com&#x2F;products&#x2F;bub_ii&quot;&gt;BUBII&lt;&#x2F;a&gt;.  So with around 20 USB-&amp;gt;serial devices, figuring out which &#x2F;dev&#x2F;ttyUSBx entry corresponds to which port is not really practical.  However, with udev in Linux, you can easily give static names to each device.  This is especially convenient to do with FTDI devices because each FTDI device has a serial number.  In devices such as the 8-port RS232 adapter, there are 4, 2-port FTDI chips.  I could not find a serial number available in the adapter with a Prolific IC, so I would avoid those until that is sorted.&lt;&#x2F;p&gt;
&lt;p&gt;udevadm can be used to discover the serial number for a FTDI device:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;udevadm info --attribute-walk -n &#x2F;dev&#x2F;ttyUSB0|grep serial
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After the serial number is known, rules can be created in the &lt;em&gt;&#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;99-usb-serial.rules&lt;&#x2F;em&gt; as shown in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;4337154&quot;&gt;this example&lt;&#x2F;a&gt;.  Now, serial ports can be accessed using convenient names such as &lt;em&gt;&#x2F;dev&#x2F;ttyUSB_beagle&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick way to set up an OpenEmbedded feed server</title>
        <published>2012-12-08T00:00:00+00:00</published>
        <updated>2012-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/"/>
        <id>https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/</id>
        
        <content type="html" xml:base="https://bec-systems.com/988/a-quick-way-to-set-up-an-openembedded-feed-server/">&lt;p&gt;During development with OpenEmbedded (oe-core, meta-oe, meta-angstrom), I often find it useful to set up a feed server so that packages can quickly be installed on the target system without manually copying them over or building a new image.  One way to do this is copy your deploy&#x2F;ipk directory to an existing web server (perhaps Apache running on your workstation), or configure Apache to point at your OE build directory, etc.  But, it might be more convenient if your build system could directly create an opkg feed with no extra configuration.  In the below example, we use &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;nodejs.org&#x2F;&quot;&gt;node.js&lt;&#x2F;a&gt; + &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;expressjs.com&#x2F;&quot;&gt;express.js&lt;&#x2F;a&gt; to create a feed server (basically just a web server that serves up the ipk files).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;tools&#x2F;feed-server&#x2F;app.js:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;&#x2F; nodejs script to start a http server with the feed from this directory
&#x2F;&#x2F; default is port 4000
var express = require(&amp;#39;express&amp;#39;)
var app = express()
app.use(&amp;#39;&#x2F;&amp;#39;, express.static(__dirname +
   &amp;#39;&#x2F;..&#x2F;..&#x2F;build&#x2F;tmp-angstrom_next-eglibc&#x2F;deploy&#x2F;ipk&#x2F;&amp;#39;))
app.use(&amp;#39;&#x2F;&amp;#39;, express.directory(__dirname +
   &amp;#39;&#x2F;..&#x2F;..&#x2F;build&#x2F;tmp-angstrom_next-eglibc&#x2F;deploy&#x2F;ipk&#x2F;&amp;#39;))
console.log(&amp;quot;feed server started on port 4000&amp;quot;)
app.listen(4000)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;express.directory&lt;&#x2F;em&gt; function is used to create a directory listing that can be browsed.  With most other web servers, at least this much code is required just for configuration.  With node.js, this is the code to create an entire server from scratch!  This node.js app can be started with a bash function in the environment:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;function oe_feed_server()
{
  cd $OE_BASE
  bitbake package-index
  node tools&#x2F;feed-server&#x2F;app.js
  cd -
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;package-index&lt;&#x2F;em&gt; target is used to rebuild the index files that list the available packages.&lt;&#x2F;p&gt;
&lt;p&gt;On the target system, the &#x2F;etc&#x2F;opkg configuration files must be modified to point to the feed server, and then you can run:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;opkg update; opkg install &amp;lt;package&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An exmaple build environement with this integrated is located:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;23352b9a43c60d67070abe5ac001aba9a9ac5cc4&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;23352b9a43c60d67070abe5ac001aba9a9ac5cc4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;6baceb8b1e4477ccfd03aa553a5fcf501b398196&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build-core&#x2F;commit&#x2F;6baceb8b1e4477ccfd03aa553a5fcf501b398196&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It might be argued that it is just as easy or easier to set up a more conventional web server.  However, the benefit of node.js is that it is a full blown programming environment.  You can quickly extend it to provide a web interface, perhaps add functionality to automatically push updated opkg configuration files to the target system that point to your feed server, etc.  It is much more than just a web server.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting the root password in an OpenEmbedded image</title>
        <published>2012-12-05T00:00:00+00:00</published>
        <updated>2012-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/"/>
        <id>https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/967/setting-the-root-password-in-an-openembedded-image/">&lt;p&gt;During development, often a blank root password is used for the embedded Linux target system.  However, when deploying an embedded Linux system, often there is a requirement to set the root password to something non-obvious.  One way to do this is boot the system, and change the password using the passwd command.  Then copy the password hash from the &#x2F;etc&#x2F;shadow file into the below line in your image recipe.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ROOTFS_POSTPROCESS_COMMAND += &amp;quot;\
sed &amp;#39;s%^root:[^:]*:%root:password_hash_from_etc_shadow:%&amp;#39; \
&amp;lt; ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow \
&amp;gt; ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow.new;\
mv ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow.new ${IMAGE_ROOTFS}&#x2F;etc&#x2F;shadow ;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The ROOTFS_POSTPROCESS_COMMAND is useful for simple modifications like this to the rootfs image.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded: configuring openssh to allow a blank password</title>
        <published>2012-12-05T00:00:00+00:00</published>
        <updated>2012-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/"/>
        <id>https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/</id>
        
        <content type="html" xml:base="https://bec-systems.com/978/openembedded-configuring-openssh-to-allow-blank-password/">&lt;p&gt;Noticed the following when browsing around in the OpenEmbedded sources the other day:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ROOTFS_POSTPROCESS_COMMAND += &amp;quot;openssh_allow_empty_password ;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows a blank password for development, which is conveient for running ssh&#x2F;scp commands to the device.  The above can be placed in an image recipe.&lt;&#x2F;p&gt;
&lt;p&gt;The command modifies the PermitEmptyPasswords config option in &#x2F;etc&#x2F;ssh&#x2F;sshd_config or &#x2F;etc&#x2F;default&#x2F;dropbear.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running a reboot cycle test shell script with systemd</title>
        <published>2012-08-29T00:00:00+00:00</published>
        <updated>2012-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/"/>
        <id>https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/942/running-a-reboot-cycle-test-shell-script-with-systemd/">&lt;p&gt;One of the easiest ways to stress test an embedded Linux system is to continuously reboot the system. Booting is a difficult activity for a Linux system (similar to waking up in the morning). The CPU is maxed out. There are a lot of things happening in parallel. Software is initializing. There is a lot of filesystem activity. Often, if there is an instability in the system (and especially the filesystem), continuously rebooting will expose it.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we use systemd for most new systems, we need to run a simple script X seconds after the system boots to increment the boot count, and reboot. This is the classic domain of a shell script. However, for a simple task like this, it’s a little cumbersome to create a seperate shell script and then call this script from a systemd unit. The following is a way to embed the script directly in a systemd unit.&lt;&#x2F;p&gt;
&lt;p&gt;Put the following in: &lt;em&gt;&#x2F;lib&#x2F;systemd&#x2F;system&#x2F;cycletest.service&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Reboots unit after 30s

[Service]
StandardOutput=syslog+console
ExecStart=&#x2F;bin&#x2F;sh -c &amp;quot;\
test -f &#x2F;cycle-count || echo 0 &amp;gt; &#x2F;cycle-count;\
echo &amp;#39;starting cycletest&amp;#39;;\
sleep 30;\
expr `cat &#x2F;cycle-count` + 1 &amp;gt; &#x2F;cycle-count;\
systemctl reboot;\
&amp;quot;

[Install]
WantedBy=multi-user.target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To install and start the script:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;systemctl daemon-reload&lt;&#x2F;li&gt;
&lt;li&gt;systemctl enable cycletest.service (enable the service to start on reboot)&lt;&#x2F;li&gt;
&lt;li&gt;systemctl start cycletest.service (start the service, should reboot in 30s)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bitbake has a new way of displaying build status</title>
        <published>2012-08-29T00:00:00+00:00</published>
        <updated>2012-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/"/>
        <id>https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/</id>
        
        <content type="html" xml:base="https://bec-systems.com/958/bitbake-has-a-new-way-of-displaying-build-status/">&lt;p&gt;Now instead of displaying a scrolling log, bitbake will display a simple output that lists which tasks it is working on at the moment:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;﻿﻿Currently 4 running tasks (185 of 3093):
0: gmp-native-5.0.5-r0 do_configure (pid 22919)
1: lzo-native-2.06-r1 do_configure (pid 27103)
2: expat-native-2.1.0-r0 do_compile (pid 7463)
3: ncurses-native-5.9-r10.1 do_compile (pid 9820)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This really allows for a clear view of how the parallel threads option (BB_NUMBER_THEADS) in bitbake works.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mounting a UBIFS partition using systemd</title>
        <published>2012-08-16T00:00:00+00:00</published>
        <updated>2012-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/"/>
        <id>https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/</id>
        
        <content type="html" xml:base="https://bec-systems.com/917/mounting-a-ubifs-partition-using-systemd/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;Software&#x2F;systemd&#x2F;&quot;&gt;Systemd&lt;&#x2F;a&gt; is becoming the defacto system and service manager for Linux, replacing the SysV init scripts.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.angstrom-distribution.org&#x2F;&quot;&gt;Angstrom distribution&lt;&#x2F;a&gt; has supported systemd for some time now. Recently, I needed to mount a UBIFS filesystem in one of my projects.  The main application is being started with systemd, so it seemed like a good fit to also use systemd to mount a data partition needed by the application. Systemd can use entries from &#x2F;etc&#x2F;fstab, but one additional wrinkle in this system is that I also wanted to run the UBI attach in a controlled way. This can be done with a kernel command line argument, but there are times in this system where we will want to format the data partition, so this requires a detach&#x2F;attach operation.&lt;&#x2F;p&gt;
&lt;p&gt;The resulting systemd units are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;data.mount﻿﻿&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Mount data partition
Requires=data-attach.service
After=data-attach.service
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;[Mount]
What=ubi1:data
Where=&#x2F;data
Type=ubifs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;data-attach.service&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Attach data ubi partition

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=&#x2F;usr&#x2F;sbin&#x2F;ubiattach &#x2F;dev&#x2F;ubi_ctrl -m 6
ExecStop=&#x2F;usr&#x2F;sbin&#x2F;ubidetach &#x2F;dev&#x2F;ubi_ctrl -m 6
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;add the following to &lt;em&gt;&lt;strong&gt;my-application.service&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Wants=data.mount
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The only real problem I ran into is the “After” statement in the &lt;em&gt;data.mount&lt;&#x2F;em&gt; unit.  It turns out that the mount will run before the attach operation is finished unless this is included.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;RemainAfterExit&lt;&#x2F;em&gt; seems to be required so that &lt;em&gt;ExecStop&lt;&#x2F;em&gt; can be run when the unit is stopped.&lt;&#x2F;p&gt;
&lt;p&gt;(There may be a better ways to do all this, so comments are welcome!)&lt;&#x2F;p&gt;
&lt;p&gt;One of the benefits of systemd is that everything is very controlled.  If the dependencies are specified properly, there are no race conditions.  Additionally, if you need to manage units (services, mounts, etc) from a program, it is much easier to check the states as everything is very consistent.  For example, if you want to query the state of a unit, the *systemctl show &lt;unit&gt;*command will return easily parsed output (as shown below):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
Before=umount.target
After=data-attach.service systemd-journald.socket -.mount
Description=Mount data partition
LoadState=loaded
ActiveState=active
SubState=mounted
FragmentPath=&#x2F;lib&#x2F;systemd&#x2F;system&#x2F;data.mount
UnitFileState=static
InactiveExitTimestamp=Thu, 01 Jan 1970 00:00:17 +0000
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the data-attach service is stopped, systemd automatically unmounts the data partition first – very nice!&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this example illustrates how to do simple tasks in systemd.  It appears that instead of having a complex script or program to initialize a system, the systemd “way” is to create a number of small units that get connected with dependencies.  This seems like a much more controlled and flexible approach.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Review of Graphical Application Solutions for Embedded Linux Systems</title>
        <published>2012-08-07T00:00:00+00:00</published>
        <updated>2012-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/890/graphical-solutions-for-embedded-linux/"/>
        <id>https://bec-systems.com/890/graphical-solutions-for-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/890/graphical-solutions-for-embedded-linux/">&lt;p&gt;One of the decisions we face when building Embedded Linux systems is what components to use. With Open Source software, there is often more than one good option. Graphical libraries are no exception. In this article, we’ll examine GTK+, Qt, EFL, Android, and HTML&#x2F;Javascript.&lt;&#x2F;p&gt;
&lt;p&gt;There are many factors that go into a choice like this, but some of them are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does the application need to run on Windows or MacOS?&lt;&#x2F;li&gt;
&lt;li&gt;Does the GUI need to be viewed remotely over a network?&lt;&#x2F;li&gt;
&lt;li&gt;Are dynamic effects (think iPhone) desired?&lt;&#x2F;li&gt;
&lt;li&gt;Does the application need to run on low end CPU’s (ones without a GPU)?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Putting some effort into selecting the right GUI technology is important for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Most of the development effort for the product will likely be in the graphical application, so it makes sense to maximize the productivity of the application developers.  Typically there might be 3-10 application developers on a project for every system software developer.&lt;&#x2F;li&gt;
&lt;li&gt;You want a technology that will scale with new revisions and improvements of the product.&lt;&#x2F;li&gt;
&lt;li&gt;You want a technology that will be supported and improved long term.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With Open Source software, things are always changing.  Leading technologies change.  This can be illustrated by following Intel’s support for their open source software platforms.  While some of this may be driven by politics, we can also see clear technical and licensing reasons why these shifts were made.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Moblin (GTK+), became public around 2007, merged into MeeGo in 2010&lt;&#x2F;li&gt;
&lt;li&gt;MeeGo (Qt), announced in 2010-02, cancelled 2011-09&lt;&#x2F;li&gt;
&lt;li&gt;Tizen (HTML&#x2F;Javascript, EFL), announced in 2011-09&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can see similar shifts in other companies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Nokia started with GTK+ as the GUI technology for their tablet computers, and then shifted to Qt&lt;&#x2F;li&gt;
&lt;li&gt;Samsung has been using GTK+ on top of DirectFB, and now is moving toward EFL&#x2F;HTML&#x2F;Javascript for some phones&lt;&#x2F;li&gt;
&lt;li&gt;Many phone manufactures are producing Android products&lt;&#x2F;li&gt;
&lt;li&gt;Palm moved from a proprietary GUI to HTML in webOS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;gtk&quot;&gt;GTK+&lt;&#x2F;h2&gt;
&lt;p&gt;GTK+ is part of the GNOME desktop project and is perhaps the most used graphical library for desktop Linux applications, and in the past has been very popular in Embedded systems.  Nokia has invested heavily in GTK+ in the past with its early tablet products (N770, N800, N900, etc).  However, with the advent of the iPhone and faster processors with GPUs, everything has changed.  The standard is now dynamic GUI’s with sliding effects, etc.  The Clutter project is a library that can be used to build dynamic GUIs and fits in with the GNOME stack.  GTK+ supports Windows and MacOS, but probably not as well as Qt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qt&quot;&gt;Qt&lt;&#x2F;h2&gt;
&lt;p&gt;Qt is a very mature project that is also extensively used for desktop projects, and recently is being used on some of Nokia’s phones.  Qt was originally developed by the Norwegian company Trolltech. Originally, Qt was only offered with either a proprietary license or the GPL license.  This meant if you wanted to write a proprietary application using Qt, you had to purchase Trolltech’s commercial license. This factor alone probably made GTK+ a much more popular solution for many years for Embedded Linux GUI’s, including most cell phone stacks.  In 2008, Trolltech was acquired by Nokia, and shortly after that, Qt was offered under the LPGL license, giving it the same license as GTK+.&lt;&#x2F;p&gt;
&lt;p&gt;One of Qt’s compelling features introduced in Qt 4.7 is its QML (or Qt Quick) technology.  This allows you to write declarative GUI’s in a Javascript like syntax with many automatic bindings.  There is good support for dynamic operations like sliding effects, and the performance is reasonable, even on low-end systems without a GPU.&lt;&#x2F;p&gt;
&lt;p&gt;In the future, Qt 5.0 will require OpenGL, and hence be relegated to high end ARM CPU’s with a GPU, or desktop systems.&lt;&#x2F;p&gt;
&lt;p&gt;Qt’s cross platform support is excellent, and provides good native support for Linux, MacOS, and Windows.&lt;&#x2F;p&gt;
&lt;p&gt;Recently, Nokia has made efforts to set up Qt as more of a community project, instead of retaining exclusive control over it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;efl&quot;&gt;EFL&lt;&#x2F;h2&gt;
&lt;p&gt;EFL (Enlightenment Foundation Libraries) is a project that started out as the Enlightenment window manager, and grew into a set of general purpose libraries.  It claims to be to be more efficient than GTK+ and Qt, and work with or without hardware acceleration.  Recently, EFL seems to have garnered the commercial interest of Samsung, Intel, and others involved in the Tizen project.  According to a presentation by Carsten Haitzler (one of EFL’s founders and developers), Samsung was using GTK+ and DirectFB, but switched to EFL after seeing the performance.  Perhaps the most compelling story for EFL is the high performance over a range of hardware capabilities (from simple phones with low end processors, to high end smart-phones running OpenGL).  Parts of EFL are also used in the commercial GUI FancyPants.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;android&quot;&gt;Android&lt;&#x2F;h2&gt;
&lt;p&gt;Android is an interesting GUI solution, especially as many developers have experience working on Android applications.  Android now seems to be used in many applications where Windows CE was used in the past, probably due to its polished application development tool-set.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;html-javascript&quot;&gt;HTML&#x2F;Javascript&lt;&#x2F;h2&gt;
&lt;p&gt;Application development with HTML and Javascript is one of the more interesting developments because many embedded systems are headless (don’t have a local display). Couple this with the fact that many users now have smartphones or tablets readily available, and it may make sense to simply use an external device for displaying the UI.  There is often a requirement for accessing the UI of a device remotely, and in this case, HTML&#x2F;Javascript works very well.  If the UI needs to be displayed locally, then a fairly powerful CPU is required (an ARM Cortex-A8, etc) to run a modern web browser.  If there is no physical display on the device, and the UI is accessed remotely on a computer or mobile device, then a less powerful CPU is required because the embedded device does not actually have to do any of the rendering.  HTML&#x2F;Javascript also has the benefit that it is a very popular technology, thus there are many experienced developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Each of the above technologies has benefits and drawbacks.  Understanding your project’s requirements, and what each solution offers is key to making the best decision.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Linux Kernel Tracing Tutorial</title>
        <published>2012-01-31T00:00:00+00:00</published>
        <updated>2012-01-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/865/linux-tracing-tutorial/"/>
        <id>https://bec-systems.com/865/linux-tracing-tutorial/</id>
        
        <content type="html" xml:base="https://bec-systems.com/865/linux-tracing-tutorial/">&lt;p&gt;The Linux kernel has a fairly extensive tracing infrastructure that is quite useful for debugging.  There are a number of things you can do with tracing, but the focus of this article will be the traditional printk type debugging we often end up doing to trace initialization issues with a driver.  The following links provide additional information on the linux kernel tracing infrastructure:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;865&#x2F;linux-tracing-tutorial&#x2F;%EF%BB%BFhttp:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&quot;&gt;﻿&lt;&#x2F;a&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&quot;&gt;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git;a=tree;f=Documentation&#x2F;trace&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Debugging the kernel using Ftrace - part 1: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;365835&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;365835&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Debugging the kernel using Ftrace - part 2: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;366796&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;366796&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Secrets of the Ftrace function tracer: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;370423&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;370423&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;elinux.org&#x2F;Kernel_Trace_Systems&quot;&gt;http:&#x2F;&#x2F;elinux.org&#x2F;Kernel_Trace_Systems&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this example, I am working on a new audio driver.  The typical experience with a new driver is that you install it and nothing happens because something is not registered correctly with the Linux driver model.  So, the first thing I do is start with with the platform_device_add() function in my drivers init function.  To observe the kernel activity around the kernel platform code, I can do the following:&lt;&#x2F;p&gt;
&lt;p&gt;﻿﻿cd &#x2F;sys&#x2F;kernel&#x2F;debug&#x2F;tracing&#x2F;
echo 0 &amp;gt; tracing_on﻿ (keep trace from filling up until we set filter)
echo function_graph &amp;gt; current_tracer
echo platform* &amp;gt; set_ftrace_filter
echo 1 &amp;gt; tracing_on
cat trace_pipe (leave running in a different shell)
&lt;insmod my driver&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After executing the above, we see the following.  For this example, trace_pipe is preferred because the trace is then emptied and only new information is shown.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;0) + 30.518 us   |  platform_device_alloc();
0)               |  platform_device_add() {
0)   0.000 us    |    platform_uevent();
0) + 30.518 us   |  platform_uevent();
0)   0.000 us    |  platform_uevent();
0) + 30.518 us   |    platform_match();
0) + 30.518 us   |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();

...

0) + 30.518 us   |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0)   0.000 us    |    platform_match();
0) ! 3936.767 us |  }
0) + 30.518 us   |  platform_uevent();
0) + 30.518 us   |  platform_device_alloc();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the above, I can conclude that the platform_match() is not succeeding, because I would expect some more activity.  At this point I chose to add a printk:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a&#x2F;drivers&#x2F;base&#x2F;platform.c b&#x2F;drivers&#x2F;base&#x2F;platform.c
index 7a24895..f9ce0c7 100644
--- a&#x2F;drivers&#x2F;base&#x2F;platform.c
+++ b&#x2F;drivers&#x2F;base&#x2F;platform.c
@@ -662,6 +662,8 @@ static int platform_match(struct device *dev, struct device_driver *drv)
        struct platform_device *pdev = to_platform_device(dev);
        struct platform_driver *pdrv = to_platform_driver(drv);

+       trace_printk(&amp;quot;pdev-&amp;gt;name = %s, drv-&amp;gt;name = %s&amp;quot;, pdev-&amp;gt;name, drv-&amp;gt;name);
+
        &#x2F;* Attempt an OF style match first *&#x2F;
        if (of_driver_match_device(dev, drv))
                return 1;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, if I re-run the trace, I see the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = davinci_emac *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc_audio, drv-&amp;gt;name = omap-pcm-audio *&#x2F;
 0)   0.000 us    |    }
 0) ! 4241.943 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the above, it looks like we have a simple mismatch between “soc_audio” and “soc-audio.”  Fixing this problem, and re-installing the module, we now have:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0)   0.000 us    |    }
 0) + 91.553 us   |    platform_drv_probe();
 0) ! 4241.943 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can see that the names match, and the probe function is now being called.  At this point, we may want to turn on tracing of some additional functions to try to determine what is happening next.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;platform* snd* mydriver*&amp;quot; &amp;gt; set_ftrace_filter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the result:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = snd-soc-dummy *&#x2F;
 0)   0.000 us    |    }
 0)               |    platform_match() {
 0)               |      &#x2F;* pdev-&amp;gt;name = soc-audio, drv-&amp;gt;name = soc-audio *&#x2F;
 0) + 30.517 us   |    }
 0)               |    platform_drv_probe() {
 0)               |      snd_soc_register_card() {
 0) + 30.518 us   |        snd_soc_instantiate_cards();
 0) ! 17852.78 us |      }
 0) ! 17883.30 us |    }
 0) ! 22125.24 us |  } &#x2F;* platform_device_add *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the above additional information, we can continue to learn more about the flow through the kernel.&lt;&#x2F;p&gt;
&lt;p&gt;While all of the above could have been done with printk’s, it would have been more time consuming.  The kernel function tracing capabilities allow us to quickly get a high level view of the flow through the kernel without manually adding a bunch of printk statements.  The kernel tracing features are completely contained in the kernel without requiring additional user space utilities which makes it very convenient to use in embedded systems.  The low overhead is also important in resource constrained embedded systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The easy way to get serial terminal in Linux</title>
        <published>2012-01-26T00:00:00+00:00</published>
        <updated>2012-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/"/>
        <id>https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/859/the-easy-way-to-get-serial-terminal-in-linux/">&lt;p&gt;When doing embedded Linux development, most of us spend out time tethered to a target system with a serial cable, which is used for a serial console.  Minicom is the defacto serial terminal software for Linux.  However, Minicom is a little fussy in that you typically have to set it up for each port you want to use.  This is no big deal, but is generally difficult for new users to understand, and yet another hurdle.  And with 8-port USB-&amp;gt;serial adapters, I have a lot of ports to set up.&lt;&#x2F;p&gt;
&lt;p&gt;Just recently, I discovered that screen can be used as a serial terminal program:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;screen &#x2F;dev&#x2F;ttyUSB0 115200
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A few notes on using:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;to exit screen: Ctrl-a k&lt;&#x2F;li&gt;
&lt;li&gt;to write a hardcopy of the screen image: Ctrl-a h&lt;&#x2F;li&gt;
&lt;li&gt;to get help: Ctrl-?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All the neat features of screen are two numerous to list here, but one more that I’ll point out is the scrollback&#x2F;copy feature (activated by Ctrl-a [ ).  This allows you to scroll back and the navigation works much like VI – what could be nicer?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Verizon UML290 and Sprint U600 USB Modems in Embedded Systems</title>
        <published>2011-03-31T00:00:00+00:00</published>
        <updated>2011-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/"/>
        <id>https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/842/verizon-uml290-and-sprint-u600-usb-modems-in-embedded-systems/">&lt;p&gt;Recently I tested support for the Verizon UML290 and Sprint U600 USB Cellular modems in an embedded Linux system.  Both modems support 3G and 4G networks, but only the 3G modes were tested due to lack of 4G coverage at the testing location.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110331_001-1-scaled.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110331_001-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, both modems function very similar to previous modems, so with the drivers available in the Linux kernel, and standard &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;ppp&quot;&gt;pppd support in OpenEmbedded&lt;&#x2F;a&gt;, they worked fine.&lt;&#x2F;p&gt;
&lt;p&gt;The Verizon UML290 modem provides a challenge in that it must be manually switched between 4G and 3G modes.  Typically this is done automatically by the vzaccess program Verizon supplies with the modem that runs on Windows.  The solution for this system was to manually set the modem to 3G mode as detailed on the following page:&lt;&#x2F;p&gt;
&lt;p&gt;﻿&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.evdoinfo.com&#x2F;content&#x2F;view&#x2F;3492&#x2F;64&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.evdoinfo.com&#x2F;content&#x2F;view&#x2F;3492&#x2F;64&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It appears that some embedded systems such as the Cradlepoint routers have implemented automatic 3G&#x2F;4G switching support for the UML290, so this is no doubt possible with a little effort.&lt;&#x2F;p&gt;
&lt;p&gt;The Sprint U600 modem appears to default to 3G, or automatically switch inside the modem.&lt;&#x2F;p&gt;
&lt;p&gt;The same pppd scripts can be used with both modems:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290
user a
password v
connect &amp;quot;&#x2F;usr&#x2F;sbin&#x2F;chat -v -f &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290_chat&amp;quot;
defaultroute
usepeerdns
ttyACM0
921600
local
usepeerdns
debug
-detach
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_um290_chat
&amp;#39;&amp;#39; &amp;#39;ATZ&amp;#39;
&amp;#39;OK&amp;#39; &amp;#39;ATDT#777&amp;#39;
&amp;#39;CONNECT&amp;#39; &amp;#39;&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To initiate a connection:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;pppd call verizon_um290
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With Verizon cellular modems, it appears that port 22 is often blocked, so if you need to access a remote device via ssh, you may need to run ssh on a higher port number.  With 4G networks, it appears that the networking setup may be different in that a public IP address may not be assigned.  From the above evdoinfo.com page, we find the following text:&lt;&#x2F;p&gt;
&lt;p&gt;﻿﻿&lt;em&gt;This fix will also work for users looking to use their device for remote based applications because it assigns a public facing IP address (3G ONLY). With eHRPD you’re assigned a private IP in either 3G or 4G mode, which has prevents UML290 users from accessing remote applications.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps the Rev A HDR Service mode will also work in 4G mode, but its seems as cellular networks become more complicated, there will be more issues to deal with in using USB Cellular modems for remote access in embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Past articles on USB Cellular modems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;353&#x2F;sprint-598u-usb-broadband-modem-in-embedded-systems&#x2F;&quot;&gt;&#x2F;353&#x2F;sprint-598u-usb-broadband-modem-in-embedded-systems&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&quot;&gt;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git and Distributed Development</title>
        <published>2011-03-29T00:00:00+00:00</published>
        <updated>2011-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/832/git-and-distributed-development/"/>
        <id>https://bec-systems.com/832/git-and-distributed-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/832/git-and-distributed-development/">&lt;p&gt;This is part of an ongoing &lt;a href=&quot;..&#x2F;tag&#x2F;git&quot;&gt;series of articles&lt;&#x2F;a&gt; on the Git version control system.&lt;&#x2F;p&gt;
&lt;p&gt;The “&lt;a href=&quot;&#x2F;780&#x2F;git-and-multiple-repositories&#x2F;&quot;&gt;many repository&lt;&#x2F;a&gt;” paradigm has been partly driven by the  distributed development paradigm.  Git solves the problem of multiple  developers working in multiple repositories very well.  Because we want  to use and customize projects like the Linux kernel, U-boot, and  OpenEmbedded in our projects, then we naturally find ourself in the  situation where we need to manage multiple repositories.  Yes, you can  check the Linux kernel into your company Subversion repository, but you  are much better off long term if you bite the bullet and implement your  own Git infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;As we consider the product development process, we need to consider  the life cycle of a product.  Most products live for at least several  years, and will go through several software iterations.  If we can  update the software components we use, then we can add value to the  product in the form of new or updated drivers to support new  peripherals, new libraries, performance improvements, etc.  But, we are  dealing with millions of lines of source code, so we must have an  efficient way to deal with software projects of this size.  The below  Figure 2 illustrates how you might organize a typical project.  Notice  we can pull updates from the U-boot and Kernel source trees at any time  in the development process, and merge the changes with our own modifications.  We might have an outside team working an  application, and we then easily synchronize the repositories when it  makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;git-distributed_600-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many other design flows possible.  Once you have the  ability to support multiple branches and repositories easily, it becomes  trivial to implement a staging&#x2F;testing repository for a QA processes,  maintenance repositories for supporting old releases, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Even at a personal developer level, Git’s distributed capabilities offers many advantages.  Each Git workspace is actually a full Git repository.  This means you can check changes in locally, re-organize your changes, be able to track changes when off-line, etc.  For this reason, many developers are now using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git&#x2F;docs&#x2F;git-svn.html&quot;&gt;git-svn&lt;&#x2F;a&gt; when they need to work with Subversion repositories.  With git-svn, you have all the benefits of using git locally, and yet you can easily synchronize with Subversion repositories.  And this leads us to our next topic: cheap branches (coming soon).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How do modern USB chargers work</title>
        <published>2011-03-19T00:00:00+00:00</published>
        <updated>2011-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/800/how-do-modern-usb-chargers-work/"/>
        <id>https://bec-systems.com/800/how-do-modern-usb-chargers-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/800/how-do-modern-usb-chargers-work/">&lt;p&gt;As we help customers design products, we often try to leverage the latest cell phone practices and technologies.  One of these is USB charging.  There has been a push in recent years to standardize on USB chargers for cell-phones.  There are a number of organizations involved including the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usb.org&quot;&gt;USB-IF&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.omtp.org&#x2F;&quot;&gt;OMTP&lt;&#x2F;a&gt;.  Two of the specification available include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;﻿﻿﻿[http:&#x2F;&#x2F;internal.omtp.org&#x2F;Lists&#x2F;ReqPublications&#x2F;Attachments&#x2F;59&#x2F;OMTP CCLDC V1.1 Final.pdf](http:&#x2F;&#x2F;internal.omtp.org&#x2F;Lists&#x2F;ReqPublications&#x2F;Attachments&#x2F;59&#x2F;OMTP CCLDC V1.1 Final.pdf)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usb.org&#x2F;developers&#x2F;devclass_docs&#x2F;Battery_Charging_V1_2.zip&quot;&gt;http:&#x2F;&#x2F;www.usb.org&#x2F;developers&#x2F;devclass_docs&#x2F;Battery_Charging_V1_2.zip&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is also a Chinese standard titled the “Telecommunications Industry Standard of the PRC“ that has been instrumental in influencing these standards.&lt;&#x2F;p&gt;
&lt;p&gt;The fundamental problem is a battery powered device needs to know if it is plugged into a computer USB port, or a dedicated charger.  A standard USB port on a computer is only specified to provide 500mA.  Typically a dedicated charger that plugs into a wall outlet provides more current than 500mA so that the battery can be charged quicker.  To differentiate between a computer USB port, and a dedicated charger, the dedicated charger shorts the D+ and D- USB signals together with a resistance of less than 200 ohms (specified by USB-IF).&lt;&#x2F;p&gt;
&lt;p&gt;One of the goals of these standards is that any charger can be used with any battery powered device.  The next question is how do we handle the case where every USB charger has a different rated current?  How can a device that charges its battery at 1.7A be compatible with a charger that only outputs 0.7A?  One theoretical solution would be for the device to query the current capacity of the charger and then only use that much current.  It turns out a much simpler approach is used.  The USB-IF provides the following chart in the above specification:&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;a rel=&quot;attachment wp-att-801&quot; href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;Selection_009-1.png&quot;&gt;&lt;figcaption&gt;&lt;img title=&quot;USB-IF charger operating range&quot; src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;Selection_009-1.png&quot; alt=&quot;&quot;&gt;&lt;&#x2F;figcaption&gt;&lt;&#x2F;a&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;As long as the charger outputs power in the Required Operating Range, the battery powered device must be able to use whatever power is available to charge its battery.  If the device uses more current than the charger can supply, the charger simply goes into a constant current mode and the battery charges slower than it would with a higher capacity charger.  Thus we have a very simple scheme where we can theoretically use any charger with any device.&lt;&#x2F;p&gt;
&lt;p&gt;As a simple test, I charged a Nokia N900 phone (which came with a  1.2A charger) with a smaller LG charger that is rated for 0.7A.  I  monitored the LG charger a couple times during charging to make sure it  was not getting hot.  It seemed to charge the N900 battery just fine.&lt;&#x2F;p&gt;
&lt;p&gt;When  purchasing after-market USB chargers, it is sometimes difficult to  determine if they have the USB D+ and D- lines shorted together.  In  once case I purchased a car USB charger that did not work with my  phones, but was able to “fix” it by disassembling it, and putting a  solder blob between the D+ and D- signals on the USB connector.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_001-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_001-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_002-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_002-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_003-1.jpg&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2011&#x2F;03&#x2F;20110319_003-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While shorting the D+ and D- pins usually makes a charger work, it is nice to know if the charger is compliant with the USB-IF specification and is designed to work in the constant current mode without shutting down, catching fire, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git Overview Screencast</title>
        <published>2011-03-17T00:00:00+00:00</published>
        <updated>2011-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/778/git-overview-screencast/"/>
        <id>https://bec-systems.com/778/git-overview-screencast/</id>
        
        <content type="html" xml:base="https://bec-systems.com/778/git-overview-screencast/">&lt;p&gt;This &lt;a href=&quot;..&#x2F;..&#x2F;video&#x2F;2010-08-26_git.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; (use Firefox to view the screencast) provides an overview of the  Git version control system.  There are 3 features of Git that are  especially interesting:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;many repositories (vs. one large repository)&lt;&#x2F;li&gt;
&lt;li&gt;distributed development&lt;&#x2F;li&gt;
&lt;li&gt;cheap branches&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The fundamental driver for better tools is increasing system  complexity.  More and more we are required to manage and integrate more  third party software, work in distributed teams, and more effectively  re-use the software we do have.  Git is a tool that helps you accomplish  these goals.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git and Why Multiple Repositories</title>
        <published>2011-03-17T00:00:00+00:00</published>
        <updated>2011-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/780/git-and-multiple-repositories/"/>
        <id>https://bec-systems.com/780/git-and-multiple-repositories/</id>
        
        <content type="html" xml:base="https://bec-systems.com/780/git-and-multiple-repositories/">&lt;p&gt;This is part of an ongoing &lt;a href=&quot;&#x2F;tags&#x2F;git&#x2F;&quot;&gt;series of articles&lt;&#x2F;a&gt; on the Git version control system.&lt;&#x2F;p&gt;
&lt;p&gt;This article discusses the trend in software configuration management toward multiple repositories, rather than one large repository.  In the past when many companies used Subversion or comparable systems, there was typically one huge  company repository (I’ve seen them in the 10’s of GB in size) that held a  hierarchical tree of all the company source code.  This worked fairly  well, and is comfortable in that the organization is very similar to a file system  directory structure.  However, this model is not very flexible in that  it does not have a consistent way to re-use components between different  projects.  Some people simply copy source code.  Some have a “common”  project that is included in all their other projects.  Subversion  externals can be used.  With Git, typically a separate repository is  created for each software component.  There are perhaps several reasons  for this, but one reason is that Git simply does not scale to huge  multi-GByte repositories.  However, this turns out to be a blessing in  disguise as I think it is a better model in many cases.  What we end up  with is more of a catalog of software components rather than a rigid hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot;&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;10&#x2F;svn-vs-git_600-1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There  is much emphasis these days on modular, re-usable software  components (Object Oriented Programming, plugins, etc.).  Why not keep  things modular at the repository level?  Another example of this type of  organization is the Internet itself.  It is not a hierarchy of  information, but rather a flat system that is organized by hyperlinks.&lt;&#x2F;p&gt;
&lt;p&gt;One  of the benefits of organizing your source code this way is that it  encourages clean boundaries between software components.  Each software  component needs to stand on its own without being propped up  by header files located in an unrelated source tree 3 levels up in the directory hierarchy.  This type of organization forces us to make better use of standard build system practices.&lt;&#x2F;p&gt;
&lt;p&gt;How do you implement this type of repository infrastructure?  Build systems such as OpenEmbedded, Gentoo, and the Android build system manage this fairly well.  However, Git also includes a feature named “submodules” that provides a mechanism for one repository to reference source code from another.  What you end up using really depends on your needs, and what you are trying to accomplish.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a href=&quot;&#x2F;778&#x2F;git-overview-screencast&#x2F;&quot;&gt;screencast&lt;&#x2F;a&gt; is also available that covers this topic.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>C++ callbacks to member functions</title>
        <published>2010-12-16T00:00:00+00:00</published>
        <updated>2010-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/760/c-callbacks-to-member-functions/"/>
        <id>https://bec-systems.com/760/c-callbacks-to-member-functions/</id>
        
        <content type="html" xml:base="https://bec-systems.com/760/c-callbacks-to-member-functions/">&lt;p&gt;How to properly do callbacks to C++ member functions is something that has intrigued me for some time now.  There are a number of solutions, none of which I really liked.  But now with the &lt;strong&gt;std::tr1::function&lt;&#x2F;strong&gt; and &lt;strong&gt;std::tr1::bind&lt;&#x2F;strong&gt; functions, there appears to be a clean solution.&lt;&#x2F;p&gt;
&lt;p&gt;In the past, if you wanted a callback to a C++ member function a typical approach was to create a static function wrapper as described &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.parashift.com&#x2F;c++-faq-lite&#x2F;pointers-to-members.html&quot;&gt;here&lt;&#x2F;a&gt;.  However, this is ugly, and a step backwards from the capabilities of plain old C.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;std::tr1::function&lt;&#x2F;strong&gt; is a function wrapper that can be used to create function objects for a number of scenarios.  We are interested in representing class member functions.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct X {
	int foo(int);
};

std::tr1::function&amp;lt;int (X*, int)&amp;gt; f;

f = &amp;amp;X::foo;

X x;
f(&amp;amp;x, 6);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;f() is now a simple function representation that can be passed around, etc.  However, what we don’t like is the reference to the struct X type, which makes it much less generic.  This is where the &lt;strong&gt;std::tr1::bind&lt;&#x2F;strong&gt; function comes in.  With bind, we can dynamically bind one function to another, and re-arrange the arguments, etc.  So to make a generic portable function that points to X::foo(), we can do something like the following.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct X {
	int foo(int);
};

std::tr1::function&amp;lt;int (int)&amp;gt; f;

X x;
f = std::tr1::bind(&amp;amp;X::foo, &amp;amp;x, _1);

f(6);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, f() is a very generic function that could be used in various interfaces without specifically referencing struct X.&lt;&#x2F;p&gt;
&lt;p&gt;A more complete example of how callbacks might work is given below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;tr1&#x2F;functional&amp;gt;

struct B
{
  std::tr1::function &amp;lt;void ()&amp;gt; _callback;

void reg_callback(std::tr1::function &amp;lt;void ()&amp;gt; callback)
  {
    _callback = callback;
  }

void unreg_callback()
  {
    _callback = NULL;
  }

void process() {
    &#x2F;&#x2F; simply calls callback
    if (_callback)
      _callback();
  }
};

struct A
{
  B * _b;

A(B * b) :
    _b(b)
  {
    std::tr1::function&amp;lt;void()&amp;gt; callback;
    callback = std::tr1::bind(&amp;amp;A::callback, this);
    b-&amp;gt;reg_callback(callback);
  }

~A()
  {
    _b-&amp;gt;unreg_callback();
  }

void callback() {
    std::cout &amp;lt;&amp;lt; &amp;quot;A::callback called\n&amp;quot;;
  }

void process() {
    _b-&amp;gt;process();
  }
};

int main()
{
  B * b = new B();
  A * a = new A(b);

&#x2F;&#x2F; the following is example where object b calls
  &#x2F;&#x2F; back into a method
  &#x2F;&#x2F; in object a
  a-&amp;gt;process();

&#x2F;&#x2F; now delete object a, and verify the callback
  &#x2F;&#x2F; in B does not crash or still get called
  delete a;

&#x2F;&#x2F; now b should not execute the callback
  b-&amp;gt;process();
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the above example, the callback in the object &lt;em&gt;a&lt;&#x2F;em&gt; will be called once.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yocto and OpenEmbedded</title>
        <published>2010-12-10T00:00:00+00:00</published>
        <updated>2010-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/755/yocto-and-openembedded/"/>
        <id>https://bec-systems.com/755/yocto-and-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/755/yocto-and-openembedded/">&lt;p&gt;Recently, I attended an Embedded Linux summit hosted by the Linux Foundation to discuss the Yocto project.  Overall, I thought the meeting was very positive and constructive. Having met and discussed at length the methods and goals of the Linux Foundation with some of their people, I’m impressed with their approach. They are there to help Linux succeed in the Embedded space in any way they can.&lt;&#x2F;p&gt;
&lt;p&gt;It is my understanding that the Yocto project has the goal of making Linux much more accessible and usable in embedded systems, and improve efficiencies. While the OpenEmbedded project has served many of us well for many years, we all can readily understand there are some deficiencies. These can be overcome by experienced developers, but there are a number of areas that can obviously be improved. Not only are we concerned with making it easier for new users to use Embedded Linux, I think there are areas where we can drastically improve the efficiency of implementing embedded Linux systems for those who are experienced. It was stated once that tools implemented must be useful to both the new developer as well as the experienced developer.&lt;&#x2F;p&gt;
&lt;p&gt;It should be noted that building an embedded Linux system is an inherently complex undertaking, and although we can improve tools and processes to make it more efficient, and somewhat easier, in the end it is still a very complex problem, and will require considerable skill to be an effective embedded Linux developer. There is no substitute for experience, and developer skill. Just as we would not slap a fancy GUI on top of a robotic surgery instrument, and tell a novice to have at it, likewise it is still going to require considerable engineering skill to be effective in developing Embedded Linux systems. But, if we improve the base technologies, and tools, we will spend less time messing with these and doing the same things over and over, and will have more resources toward implementing new things.&lt;&#x2F;p&gt;
&lt;p&gt;One example of the pain experienced in a typical OpenEmbedded system is getting Oprofile to run. Oprofile requires that ARM system be built with frame pointers (OE defaults to not), and that you have symbols in your binaries. Figuring out how to build a reasonably sized image with the needed symbols might be a 1-2 day process for me. Then there is the issue of kernel symbols, etc. I’m sure many other developers go through the same steps, but as many of us are paid to develop products on tight schedules, we don’t have the time to polish the Oprofile integration and tools.&lt;&#x2F;p&gt;
&lt;p&gt;As an extension of this, the application development story with OpenEmbedded is not all that great. Yes, we can generate a binary SDK, but again it may take a couple days of messing around to figure out the process, and get all the necessary libraries, etc. Then you still have the problem that application developers want Eclipse&#x2F;Qt Creator integration, etc. Again, this can all be done, but takes time, and many people are doing the same things over and over again.&lt;&#x2F;p&gt;
&lt;p&gt;The Yocto project seems to have two primary thrusts:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;stabilize a subset of the OpenEmbedded (called Poky) metadata and make it very high quality.&lt;&#x2F;li&gt;
&lt;li&gt;improve tools associated with the build process, and general embedded Linux development.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;One thing the OpenEmbedded project has historically lacked in the past is industry funding and ongoing developer commitment. The OE project is characterized by a rotating group of developers. When someone needs OE for a project, they jump in and do a lot of work on OE, then they disappear again once their need is met. We have very few developers who work on the project consistently for long periods of time. This has been positive in some ways in that we have a very large number of contributors, and a very open commit policy. There are so many patches coming in right now, we can’t even keep up with processing them. Week after week, we have a healthy number of committers and changesets. The community behind OE is rather astounding, and it is amazing how OE succeeds almost in spite of itself as a self organizing project without much organization.&lt;&#x2F;p&gt;
&lt;p&gt;In the past the OpenEmbedded and Poky projects have existed as two independent trees, and things were shared back and forth manually. This works fairly well as recipes are self contained, and generally can simply be copied from one tree to another. However, some of the core recipes are fairly complex, and if they start to diverge, then sharing information can get more difficult.&lt;&#x2F;p&gt;
&lt;p&gt;It seems the vision that is emerging is that Poky could become the core component of OpenEmbedded. Poky would contain a very controlled subset of core recipes that must remain at a very high quality level. OpenEmbedded could then expand on this (through the use of layers) to provide the breadth and scope it has traditionally provided.&lt;&#x2F;p&gt;
&lt;p&gt;We may bemoan the lack of quality in the OpenEmbedded project as it has 1000’s of recipes, and many of them have rotted, etc. But as a consultant helping people implement products, I still find considerable value in this. For example, one of the products I support uses the HPLIP drivers from HP. Yes, the recipe is broke every time I go to use the latest version, but with a little work I can get it working again. Having something to start with provides value. The same is true for the geos mapping libraries. Very few people are going to use geos, so it will never be in a Poky type repository, but some of us do use geos, so having a common place like OpenEmbedded to put recipes like this is very important. Using Poky as the core of OpenEmbedded seems like a win-win. We are relieved of some of the burden of maintaining core components (like compilers, C library, tool integration, sdk generation, etc), but we can still have a very open culture, and provide a wide scope of platform, library, and application support that we have historically provided.&lt;&#x2F;p&gt;
&lt;p&gt;Richard Purdie is poised to become the Linus Torvalds of Yocto, and if OpenEmbedded choses to base on Poky, then the Torvalds of the OpenEmbedded core. I am personally fine with this as I don’t know anyone else who has contributed so much time and has the same level of skill in the OE&#x2F;Poky area. He has proven over time to be levelheaded and able to deal with difficult situations. Also, as a Linux Foundation fellow, he is positioned to be company neutral, which is very important for someone in this position.&lt;&#x2F;p&gt;
&lt;p&gt;Yocto is using a “pull” model similar to the Linux kernel for accepting changes. It is planned to put maintainers in place for various subsystems. With the goal of providing a very high quality subset of embedded Linux technologies, it seems this makes a lot of sense. If OpenEmbedded choses to base on Poky, there is no reason OpenEmbedded can’t continue to still use the push model for its layer that has worked well in the past. But, as we see patches languishing in the patchwork, perhaps a pull model might actually be more efficient at processing incoming patches so they don’t get lost. This is also an area where layers might actually help in that we have dedicated people committed to processing patches for each layer. One of the problems with the OpenEmbedded project with its 1000’s of recipes, the structure is very flat, and its fairly difficult to divide it up into areas of responsibility.&lt;&#x2F;p&gt;
&lt;p&gt;So going forward, it seems that if OpenEmbedded can somehow use Poky as a core technology (just like it uses bitbake, etc), then we could have the best of both worlds. With Poky, we get strong industry commitment and dedicated people working on making the core pieces better, and the tools better (50 engineers are already dedicated). This is something those of us developing products don’t really have time for and we are not currently funded to do this. With OpenEmbedded we can still keep our broad involvement, and vast recipe and target collection. Yes, the quality of OpenEmbedded will be lower, but it still provides a different type of value. Poky provides the known stable core, and OpenEmbedded is just that–it is “open”, and provides the broad menu of components that can be used. Over time this could evolve into something different, but for now it seems a good place to start.&lt;&#x2F;p&gt;
&lt;p&gt;The last thing to consider is the OpenEmbedded brand. It is recognizable from the name what it is (unlike Yocto, and Poky). It has had broad exposure for many years. It has historically been very vendor neutral with very little corporate direction or influence. From this perspective, it seems the Yocto project can benefit greatly from having an association with the OpenEmbedded project.  This topic was discussed at the summit, and there was general consensus on the strong awareness of the OpenEmbedded brand, as well as an openness to how branding for the Yocto core build system might look.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Qt Developer needed</title>
        <published>2010-11-05T00:00:00+00:00</published>
        <updated>2010-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/747/qt-developer-needed/"/>
        <id>https://bec-systems.com/747/qt-developer-needed/</id>
        
        <content type="html" xml:base="https://bec-systems.com/747/qt-developer-needed/">&lt;p&gt;We are currently in need of a Qt developer to help on a project.  If you are interested, please &lt;a href=&quot;&#x2F;#work-together&quot;&gt;contact us&lt;&#x2F;a&gt;.  Thanks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded srctree and gitver</title>
        <published>2010-10-11T00:00:00+00:00</published>
        <updated>2010-10-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/711/openembedded-srctree-and-gitver/"/>
        <id>https://bec-systems.com/711/openembedded-srctree-and-gitver/</id>
        
        <content type="html" xml:base="https://bec-systems.com/711/openembedded-srctree-and-gitver/">&lt;p&gt;Recently an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&quot;&gt;OpenEmbedded&lt;&#x2F;a&gt; class name &lt;em&gt;srctree&lt;&#x2F;em&gt; became usable.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&#x2F;srctree.bbclass&quot;&gt;srctree.bbclass&lt;&#x2F;a&gt; enables operation inside of an existing source tree for a project, rather than using the fetch&#x2F;unpack&#x2F;patch idiom.  The srctree.bbclass in combination with the OpenEmbedded &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&#x2F;gitver.bbclass&quot;&gt;gitver.bbclass&lt;&#x2F;a&gt; and git submodules provides a very interesting way to build custom software with OpenEmbedded.&lt;&#x2F;p&gt;
&lt;p&gt;One of the classic problems with OpenEmbedded is how do application and kernel developers use it.  While OpenEmbedded excels at automating image builds, it is less friendly when used as a a cross development tool.  Historically there are several options for iterative development:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;develop in the working directory: cd &lt;tmp&gt;&#x2F;work&#x2F;arm…&#x2F;&lt;my recipe&gt;; ..&#x2F;temp&#x2F;run.do_compile …&lt;&#x2F;li&gt;
&lt;li&gt;a variation of #1: bitbake -c devshell &lt;my recipe&gt;&lt;&#x2F;li&gt;
&lt;li&gt;manually set up an environment that uses the toolchain generated by OE.  As example see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;oe-build&#x2F;blob&#x2F;master&#x2F;envsetup.sh&quot;&gt;this script&lt;&#x2F;a&gt; in the &lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;BEC OE template&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;a variation of #3: export a SDK that includes a toolchain and libs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;While the above solutions work OK, the process can be a little cumbersome.  Unless your OE recipe pulls software directly from the TIP of a SVN repository, you may have to manually update the recipe after you make changes, create patch files, etc.  There is also the problem that if your recipe fetches the latest from SVN, it drastically slows down the recipe parsing as it has to check the repository for a new version every time the recipe is processed.&lt;&#x2F;p&gt;
&lt;p&gt;The optimal solution would to be to simply check a software component out of a version control system, and build it directly using OpenEmbedded.  Icing on the cake would be if the package generated would automatically extract version information from the version control system.  This would facilitate iterative development for software components that need to be cross compiled.&lt;&#x2F;p&gt;
&lt;p&gt;Although srctree can be used with any directory of source code, it really works best with a git repository.  The gitver.bbclass provides a GITVER variable which is a (fairly) sane version, for use in ${PV}, extracted from the ${S} git checkout, assuming it is one (text from recipe).  gitver uses the ‘git describe’ command to extract the last tag and uses that for the version.&lt;&#x2F;p&gt;
&lt;p&gt;The best way to illustrate the use of these tools is an example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The easiest way to try this is clone the above project in your openembedded&#x2F;recipes directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ cd openembedded&#x2F;recipes
$ git clone https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo.git
$ cd autotools-demo
$ git describe
1.1
$ git tag -l
1.0
1.1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;em&gt;git describe&lt;&#x2F;em&gt; simple returns the latest tag.   The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cbrake&#x2F;autotools-demo&#x2F;blob&#x2F;master&#x2F;autotools-demo.bb&quot;&gt;recipe&lt;&#x2F;a&gt; can be located in the same directory as the source code and has the following contents:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# recipe to build the autotools-demo in the working tree

inherit srctree autotools gitver

PV = &amp;quot;${GITVER}&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Can’t get much easier than that!  If you build the recipe, you end up with a package:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ bitbake autotools-demo
$ ls tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv5te&#x2F;autotools-demo_1.1-r0.6_armv5te.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, what happens if you make changes and commit them?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$ cd ...&#x2F;autotools-demo
$ (make a change and commit)
$ git describe
1.1-1-gfbc1ecc (notice the count and hash automatically appended)
$ (make another change and commit)
$ git describe
1.1-2-g7ad3715 (notice the count is now 2)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we bitbake the recipe now, we end up with a packaged named:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv5te&#x2F;autotools-demo_1.1-2-g7ad3715-r0.6_armv5te.ipk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;gitver&lt;&#x2F;em&gt; class in OpenEmbedded automatically takes care of creating a usable PV (package version) that always increments.&lt;&#x2F;p&gt;
&lt;p&gt;So in summary, &lt;em&gt;srctree&lt;&#x2F;em&gt; and &lt;em&gt;gitver&lt;&#x2F;em&gt; give developers a convenient way to handle custom components that change often in an Embedded Linux build without increasing parse times, requiring manual tweaks to version numbers, or creating a separate workspace for each version of the application that is built.  As practices such as continuous integration become more common, OpenEmbedded features like this are increasingly needed.  An added benefit is that the OpenEmbedded recipe can now be stored in the same location as the source code.  Perhaps in the future, most applications will include an OpenEmbedded recipe as part of their source code and git submodules could be used to simple populate the components you want to use.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;2017-11-08 update: A tool named &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.yoctoproject.org&#x2F;docs&#x2F;2.4&#x2F;mega-manual&#x2F;mega-manual.html#using-devtool-in-your-sdk-workflow&quot;&gt;devtool&lt;&#x2F;a&gt; is now the preferred way to do much of the above.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Qt Creator for C&#x2F;C++ development</title>
        <published>2010-08-07T00:00:00+00:00</published>
        <updated>2010-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/704/qt-creator-for-cc-development/"/>
        <id>https://bec-systems.com/704/qt-creator-for-cc-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/704/qt-creator-for-cc-development/">&lt;p&gt;Recently, I’ve been evaluating &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;qt.nokia.com&#x2F;developer&#x2F;qt-qtcreator-prerelease&quot;&gt;Qt Creator&lt;&#x2F;a&gt; for general C&#x2F;C++ development.  I’m currently involved in the development of a rather large C++ application that is approaching 200,000 lines of code and 1000 source modules.  In the past, I’ve typically used Vim for editing, and Eclipse as a gdb front-end when needed.  Qt Creator is a rather new tool developed by Nokia’s Qt team.  What initially attracted my attention was that one of the reasons the project was started was no existing tools effectively handled the Qt codebase, which is quite large.  Things I like about Qt Creator:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;it works fairly well with any C++ Make based project.  This includes projects built with autotools as well as the Qt Qmake build system.&lt;&#x2F;li&gt;
&lt;li&gt;easy to import existing projects&lt;&#x2F;li&gt;
&lt;li&gt;it is very fast.  Indexing 200,000 lines of code happens in around a minute or so.&lt;&#x2F;li&gt;
&lt;li&gt;Provides a Vim compatibility mode that actually works&lt;&#x2F;li&gt;
&lt;li&gt;provides fast methods for finding files, symbols, and seeing where symbols are used&lt;&#x2F;li&gt;
&lt;li&gt;did I mention yet it is &lt;em&gt;&lt;strong&gt;fast&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I also &lt;a href=&quot;&#x2F;video&#x2F;2010-08-07_qt-creator-demo.ogv&quot;&gt;recorded a screencast that demos Qt Creator with a large project&lt;&#x2F;a&gt; (can be viewed in firefox).  As always, I’m interested in what others find interesting in this or other tools.  Future efforts will be to use Qt Creator to build and remotely debug ARM binaries – I am interested in what others have done in this regard.&lt;&#x2F;p&gt;
&lt;p&gt;If you do try Qt Creator, I recommend the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;qt.nokia.com&#x2F;developer&#x2F;qt-qtcreator-prerelease&quot;&gt;latest pre-release snapshot&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux Presentation in Cleveland</title>
        <published>2010-07-26T00:00:00+00:00</published>
        <updated>2010-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/"/>
        <id>https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/</id>
        
        <content type="html" xml:base="https://bec-systems.com/701/embedded-linux-presentation-in-cleveland/">&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;coledd.com&#x2F;&quot;&gt;Chris Cole&lt;&#x2F;a&gt; and I will be &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clevelandieee.org&#x2F;content&#x2F;embedded-linux-development&quot;&gt;giving a presentation&lt;&#x2F;a&gt; in Cleveland Tues evening (2010-07-26).  Stop by if you are interested.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git submodules: what to do when you commit to (no branch)</title>
        <published>2010-06-17T00:00:00+00:00</published>
        <updated>2010-06-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/"/>
        <id>https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/</id>
        
        <content type="html" xml:base="https://bec-systems.com/696/git-submodules-what-to-do-when-you-commit-to-no-branch/">&lt;p&gt;When using git submodules, eventually you’ll run into a situation where a workspace has checked out a submodule as (no branch), and you unknownly make modifications and commits to (no branch).  Now what?  It turns out Git has a very useful feature named reflog.  Reflog keeps a local time based log of all activity.  That means that as long as you do not garbage collect your workspace, you can go back to any point in time and get any commit that was made.  This is useful in a number of scenarios, but lets consider the case where we made two commits to a submodule in the (no branch) state.  We are then ready to push our changes to the upstream repo and we get:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git push bec HEAD
error: unable to push to unqualified destination: HEAD
The destination refspec neither matches an existing ref on the remote nor
begins with refs&#x2F;, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to &amp;#39;git@git.bec-systems.com:openembedded.custom&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we do a git log, we find we are on the infamous (no branch).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git branch
* (no branch)
  master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point we may wonder what to do.  How do we get these changes onto the master branch?  Using git reflog, we can view all commits and changes to our local repository based on time.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git reflog
6d195b3 HEAD@{0}: commit: add recipe for qt-embedded image
4cf1bd6 HEAD@{1}: commit: add touchscreen utilities
bcc673c HEAD@{2}: checkout: moving from master to bcc673c9824e916a7ec6c04f60a17116af539423
56d9def HEAD@{3}: commit: add more features
5286f87 HEAD@{4}: commit: rename debug image
90896de HEAD@{5}: pull : Fast-forward
5cc3f3b HEAD@{6}: checkout: moving from 90896deb2a25f0d40b1e6305a0ad994f932f22d8 to master
90896de HEAD@{7}: checkout: moving from master to 90896deb2a25f0d40b1e6305a0ad994f932f22d8
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Git will keep our keeps commits to (no branch) even though we might switch to another name branch.  And using git reflog, we can easily find these commits and merge them to the master branch.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git checkout master
Previous HEAD position was 6d195b3... add recipe for qt-embedded image
Switched to branch &amp;#39;master&amp;#39;
Your branch is behind &amp;#39;origin&#x2F;master&amp;#39; by 1 commit, and can be fast-forwarded.
cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git reflog
56d9def HEAD@{0}: checkout: moving from 6d195b3909553b04cba3d3ac182076a2c6b866b2 to master
6d195b3 HEAD@{1}: commit: add recipe for qt-embedded image
4cf1bd6 HEAD@{2}: commit: add touchscreen utilities
bcc673c HEAD@{3}: checkout: moving from master to bcc673c9824e916a7ec6c04f60a17116af539423
56d9def HEAD@{4}: commit: add more features
5286f87 HEAD@{5}: commit: rename debug image
90896de HEAD@{6}: pull : Fast-forward
5cc3f3b HEAD@{7}: checkout: moving from 90896deb2a25f0d40b1e6305a0ad994f932f22d8 to master
90896de HEAD@{8}: checkout: moving from master to 90896deb2a25f0d40b1e6305a0ad994f932f22d8
cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git merge 6d195b3
Updating 56d9def..6d195b3
Fast-forward
 recipes&#x2F;images&#x2F;bec-debug-image.bb       |   38 +++++++++++++++++++-----------
 recipes&#x2F;images&#x2F;bec-qt-embedded-image.bb |    8 ++++++
 2 files changed, 32 insertions(+), 14 deletions(-)
 create mode 100644 recipes&#x2F;images&#x2F;bec-qt-embedded-image.bb
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, the changes have been merged to the master branch, and we can now push to our public repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;scratch&#x2F;oe&#x2F;oe-build-overo&#x2F;openembedded.custom$ git push bec HEAD
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (9&#x2F;9), done.
Writing objects: 100% (10&#x2F;10), 1.13 KiB, done.
Total 10 (delta 3), reused 0 (delta 0)
To git@git.bec-systems.com:openembedded.custom
   bcc673c..6d195b3  HEAD -&amp;gt; master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Git reflog can also be used to restore commits that you decided at one point to throw away with “git reset --hard HEAD~2”, etc.  As long as you don’t garbage collect the repo, they are simply dangling state and always still exist.  This is just another example of the ways git can be very confusing, but also very powerful if you understand how it works.&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-17_git-reflog.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; covers the operations in this article.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing OMAP3 images on a SD card</title>
        <published>2010-06-14T00:00:00+00:00</published>
        <updated>2010-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/"/>
        <id>https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/</id>
        
        <content type="html" xml:base="https://bec-systems.com/687/installing-omap3-images-on-a-sd-card/">&lt;p&gt;This article and screen-cast is a continuation of that last couple posts describing the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;oe-build&#x2F;&quot;&gt;BEC OE build template&lt;&#x2F;a&gt;.  The purpose again for a build system is to automate tedious manual tasks, and in doing so, we end up documenting how the build system works.  Having a good build system is important during product development so that you have an easy, repeatable process for building and deploying images.  One of these tasks is setting up a SD card and installing images to the SD card that an OMAP system can boot from.  This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-14_installing-on-omap.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; goes over the script and makefile targets that are used to automate this process.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, the steps to set up a SD card and install an image using the build template are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;cd &lt;build template directory&gt;&lt;&#x2F;li&gt;
&lt;li&gt;determine the SD card device name (&#x2F;dev&#x2F;sdX)&lt;&#x2F;li&gt;
&lt;li&gt;unmount any file systems mounted on the SD card&lt;&#x2F;li&gt;
&lt;li&gt;sudo .&#x2F;scripts&#x2F;omap-sd-partitions.sh &#x2F;dev&#x2F;sdX  (make sure you have the right device!!!)&lt;&#x2F;li&gt;
&lt;li&gt;make omap-install-boot&lt;&#x2F;li&gt;
&lt;li&gt;make omap-install-&lt;image name&gt;-rootfs&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Previous articles in this series:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;OpenEmbedded build template&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;..&#x2F;668&#x2F;creating-a-custom-openembedded-image&quot;&gt;Creating  a Custom OpenEmbedded Image&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template posted</title>
        <published>2010-06-08T00:00:00+00:00</published>
        <updated>2010-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/666/openembedded-build-template-posted/"/>
        <id>https://bec-systems.com/666/openembedded-build-template-posted/</id>
        
        <content type="html" xml:base="https://bec-systems.com/666/openembedded-build-template-posted/">&lt;p&gt;A password protected version of this article accidently got pushed into the feed before it was finished, so this post is simply to indicate the following article is now available.  Sorry for the confusion.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;&#x2F;637&#x2F;oe-build-template&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating a Custom OpenEmbedded Image</title>
        <published>2010-06-08T00:00:00+00:00</published>
        <updated>2010-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/668/creating-a-custom-openembedded-image/"/>
        <id>https://bec-systems.com/668/creating-a-custom-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/668/creating-a-custom-openembedded-image/">&lt;p&gt;In this article screencast, we’ll demonstrate how to create a custom Linux OS image using the OpenEmbedded build system.  This demonstration builds on the earlier &lt;a href=&quot;&#x2F;637&#x2F;oe-build-template&#x2F;&quot;&gt;article about using the BEC OE build template&lt;&#x2F;a&gt;.  The OpenEmbedded build system is similar to Linux distributions in that you can select from a wide array of components to install.  One of the big differences is you can select these components when building the OS image, instead of after you have installed the “standard” image.  This &lt;a href=&quot;&#x2F;video&#x2F;2010-06-07_bec-custom-oe-image.ogv&quot;&gt;screencast&lt;&#x2F;a&gt; demonstrates how to set up a custom image (can be viewed with Firefox).&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a href=&quot;&#x2F;177&#x2F;the-correct-way-to-add-packages-to-an-openembedded-image&#x2F;&quot;&gt;related article&lt;&#x2F;a&gt; also covers this procedure.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, the steps include:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create an image recipe (typically in your meta data overlay).  An example is located &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;openembedded.custom&#x2F;tree&#x2F;recipes&#x2F;images&#x2F;bec-beagleboard-image.bb&quot;&gt;here&lt;&#x2F;a&gt;.  An existing image can be referenced for simplicity.&lt;&#x2F;li&gt;
&lt;li&gt;Figure out what packages need to be added.  This can be done by &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&quot;&gt;browsing the recipe tree&lt;&#x2F;a&gt; to see what is available.&lt;&#x2F;li&gt;
&lt;li&gt;Bitbake the recipe.&lt;&#x2F;li&gt;
&lt;li&gt;Look at what packages were generated.  In this example they are found in the &lt;em&gt;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;armv7a&lt;&#x2F;em&gt; directory.&lt;&#x2F;li&gt;
&lt;li&gt;Add the relevant package names to your image recipe.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As the OpenEmbedded project includes over 6000 recipes, it gives you a big head start in including standard components in your Embedded Linux build.  Leveraging these existing components is why we use Linux, and having a way to easily build and deploy these components to your target hardware is what OpenEmbedded is all about.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded Build Template</title>
        <published>2010-06-05T00:00:00+00:00</published>
        <updated>2010-06-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/637/oe-build-template/"/>
        <id>https://bec-systems.com/637/oe-build-template/</id>
        
        <content type="html" xml:base="https://bec-systems.com/637/oe-build-template/">&lt;p&gt;Setting up an OpenEmbedded build is a fairly simple process if you carefully follow the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;Getting_started&quot;&gt;instructions&lt;&#x2F;a&gt;.  There are also a number of scripts available that automate the setup such as the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;OpenEmbedded_Tools_for_Eclipse_%28OTE%29&quot;&gt;OpenEmbedded Tools for Eclipse&lt;&#x2F;a&gt;, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.angstrom-distribution.org&#x2F;simplified-development-setup&quot;&gt;Angstrom setup scripts&lt;&#x2F;a&gt;, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;kom.kaeilos.com&#x2F;&quot;&gt;KaeilOS Openembedded Manager&lt;&#x2F;a&gt;, and I’m sure there are many more (feel free to add in comments section).  As we have helped a number of clients use OpenEmbedded in commercial projects, we have the following requirements for a build template:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The build needs to be completely automated such that only one step is required to build images.&lt;&#x2F;li&gt;
&lt;li&gt;We need to be able to lock down versions of various components.&lt;&#x2F;li&gt;
&lt;li&gt;Needs to be as simple as possible.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As we continue to think about creating a build template, the primary reason for creating one is to get repeatable builds with very little effort.  The build template serves as documentation; how did we build the 1.10 release.  A good build system allows any developer to create any release on about any machine at any time.  A good build system does not depend on the “golden build machine.”  We have been using makefile wrappers around OpenEmbedded for several years now to accomplish much of this.  These wrappers were typically stored in a Subversion repository with the rest of the project files.  However, now that most open source projects have moved to Git repositories, there are significant advantages to using Git for the build system.  Git has a feature called submodules which allows you to embed a git repository inside a source tree, always pointed at a particular commit.  In concept, this is perfect.  In practice, Git submodules are sometimes difficult to use, but considering the functionality provided, I think it is a reasonable trade-off.&lt;&#x2F;p&gt;
&lt;p&gt;The use of Git encourages a different development paradigm.  Typically when people use Subversion within a company, there is one repository that stores everything.  Subversion is actually quite good at this.  I’ve run into a number of companies who have repositories many GB in size that have been running for many years.  The stability is remarkable.  Git does not scale in this way, so people tend to set up a separate repository for each component, application, etc.  While there may be some disadvantages to this model, there are also significant advantages, and we can learn some of these by observing Open Source Software (OSS) development.  Just as we strive for modularity in software development where each class can stand on its own and be generally useful, OSS maintains this dynamic at the project level.  Each OSS project moves at its own pace, largely decoupled from other projects.  This dynamic forces a level of organization that might be neglected otherwise.  Likewise, in any project, if each major component is stored in its own source code repository, there will also tend to be less coupling, willy-nilly including of header files from other components, etc.  It helps people think in a more modular manner at the component level.  A component may be the Linux kernel, bootloader, each application in the system, etc.  A similar concept may be thinking about storing documents in hierarchical filesystem directory structure versus documents in a Wiki, which are stored in a flat structure and then organized by cross linking.  Yes, there are times to use a directory structure, but flexibility of a linked organization system (the essence of the Internet) is hard to beat.  Git submodules (or similar concepts) provides a similar linking method of organization.&lt;&#x2F;p&gt;
&lt;p&gt;With this in mind, we look at a build system as a way to collect a number of independent components and build them in a repeatable fashion.  While this may seem obvious to anyone somewhat familiar with OpenEmbedded, our vision is to extend this concept to easily facilitate product development so that we can move quickly and efficiently, but yet in a controlled and reliable way.  The first step is a new build template that is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.bec-systems.com&#x2F;cgit.cgi&#x2F;oe-build&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.  The following &lt;a href=&quot;&#x2F;video&#x2F;2010-06-04_bec-oe-build-template-1.ogv&quot;&gt;video&lt;&#x2F;a&gt; provides a short overview of how to use the build template (can be viewed in Firefox).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;video controls src=&quot;&#x2F;video&#x2F;2010-06-04_bec-oe-build-template-1.ogv&quot;&gt;&lt;&#x2F;video&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The functionality provided so far is fairly simple and provides a way to quickly set up a build environment.  With Git submodules, the versions of Bitbake and the OpenEmbedded are locked down.  Submodules are also used to provide an array of components to choose from, and the user initializes only the submodules they are interested in using.  The first example of this is providing both the recipe meta data from the OpenEmbedded project or the modified version from Gumstix.  In the future, examples will be provided for doing custom application and kernel development using the OE srctree and gitver classes.  Feedback is welcome; please let me know if you have questions or suggestions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MeeGo Review</title>
        <published>2010-06-02T00:00:00+00:00</published>
        <updated>2010-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/609/meego-review/"/>
        <id>https://bec-systems.com/609/meego-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/609/meego-review/">&lt;p&gt;As we evaluate various technologies that might be applicable in embedded systems, &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;meego.com&#x2F;&quot;&gt;MeeGo&lt;&#x2F;a&gt; is the subject of this article.  MeeGo is a collaboration between Intel and Nokia, and is replacing the Moblin and Maemo efforts.  For this review, MeeGo was installed to a USB flash disk and booted on a Asus EEPC.  This was quite trivial to do, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;meego.com&#x2F;devices&#x2F;netbook&#x2F;installing-meego-your-netbook&quot;&gt;instructions on the MeeGo website are very good&lt;&#x2F;a&gt;.  The following &lt;a href=&quot;&#x2F;video&#x2F;2010-06-01_meego_general.ogg&quot;&gt;video&lt;&#x2F;a&gt; (can be viewed in Firefox) provides a quick overview of the MeeGo Netbook UI.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;video controls src=&quot;&#x2F;video&#x2F;2010-06-01_meego_general.ogg&quot;&gt;&lt;&#x2F;video&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Overall, MeeGo looks interesting.  Hopefully with the collaboration between Intel and Nokia, there will emerge a number of components that become “standards” for embedded systems such as ways to manage wireless networks, cell phone radios, etc.  It would also be nice to have better options for implementing GUI’s on embedded devices with small screens.  While the MeeGo user interface is nice, it is not a radical departure from desktop applications.  Maemo (used on the Nokia N900) is more advanced in that it has optimized widgets for a small screen.  With Maemo, all applications run in a true full screen mode, which is generally desired for devices with smaller screens, or industrial devices where we want to keep user confusion to a minimum.  MeeGo applications seem to run full screen, but you can still drag them around, and some applications like the terminal do not start full screen.&lt;&#x2F;p&gt;
&lt;p&gt;It seems there is considerable interest in providing distributions based on MeeGo.  Novell has &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.novell.com&#x2F;news&#x2F;press&#x2F;novell-announces-support-for-meego&quot;&gt;announced&lt;&#x2F;a&gt; it plans to provide MeeGo based distributions for netbooks, and Intel &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;download.intel.com&#x2F;pressroom&#x2F;kits&#x2F;events&#x2F;computex2010&#x2F;pdf&#x2F;Computex_Day2_FactSheet.pdf&quot;&gt;claims&lt;&#x2F;a&gt; there are a number of other companies planning to build on top of MeeGo.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo review</title>
        <published>2010-02-08T00:00:00+00:00</published>
        <updated>2010-02-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/587/gumstix-overo-review/"/>
        <id>https://bec-systems.com/587/gumstix-overo-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/587/gumstix-overo-review/">&lt;p&gt;Based on the interest and number of embedded modules currently available, it appears that the OMAP3 CPU from TI will be very popular in the general purpose embedded Linux market.  One of the OMAP3 modules available is the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.gumstix.com&#x2F;store&#x2F;catalog&#x2F;index.php?cPath=27_33&quot;&gt;Overo from Gumstix&lt;&#x2F;a&gt;.  As the company name suggests, this module looks about like a stick of gum, but smaller, as shown in the photo below.  The Gumstix module provides a lot of functionality in a very small package.  It is reasonably priced, and is an excellent way to quickly create a product that has advanced functionality such as a high powered CPU (OMAP3), high speed USB, DSP, 3-D graphics acceleration, etc.  For an example of the OMAP3 performance compared to previous generations of ARM processors, see &lt;a href=&quot;&#x2F;316&#x2F;gtk-performance-on-pxa270-vs-omap3&#x2F;&quot;&gt;this article&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2282_-1.jpg&quot; alt=&quot;Overo size comparison to a US dime&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The module contains all the core components, and can then be attached to a custom baseboard using the two high density connectors shown in the above photo.  There are 70 signals on each of the two connectors.  BEC &lt;a href=&quot;&#x2F;113&#x2F;gumstix-overo-connector-spreadsheet&#x2F;&quot;&gt;provides a spreadsheet&lt;&#x2F;a&gt; of the Overo signals to assist in designing a custom baseboard.&lt;&#x2F;p&gt;
&lt;p&gt;Due to the high level of component integration, the Overo has very few components on the module.  As shown in the below photo, there are really only 3 major visible components.  The flash and RAM is stacked on top of the CPU.  The PMIC contains all the required power managment circuitry, as well as Audio and USB interfacing functionality.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2281_1-1.jpg&quot; alt=&quot;Major components on the Gumstix Overo&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Overo module must be used with a baseboard.  Gumstix provides several development baseboards.  For production, a custom baseboard is typically created.  The Gumstix baseboards are reasonable cost, so they could be used for prototyping or low volume production if they have the required functionality.  Below is a photo of the Summit baseboard that provides DVI video out, audio, USB host and OTG, and an expansion connector with a number of signals.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2284_-1.jpg&quot; alt=&quot;Gumstix Summit baseboard (overo is not installed)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below is the Palo baseboard from Gumstix that can be used to interface with a LCD display.  The Palo board contains a resistive touch screen controller, and circuitry required to interface with a LCD.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2283_1-1.jpg&quot; alt=&quot;Palo baseboard with Overo installed&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2276_-1.jpg&quot; alt=&quot;Display connected to Palo baseboard.  Note the tape applied to the display to keep from shorting to components on baseboard.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Overo does not include an Ethernet controller, so you typically use a USB-Ethernet adapter for development.  Below shows a typical development setup.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2273_-1.jpg&quot; alt=&quot;Typical USB-Ethernet connection through a USB hub.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One of the things about the OMAP3 that makes it very attractive for embedded development is the amount of software support, and the number of development and production solutions available.  The OMAP3 is very well supported by the OpenEmbedded project, and TI is very active in making contributions to various open source projects.  This greatly increases the quality and availability of advanced software functionality needed to support a complex system like the OMAP3.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2285_-1.jpg&quot; alt=&quot;Size comparison of several OMAP3 systems&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2286_-1.jpg&quot; alt=&quot;WIFI and BT antennas connected to Overo module&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many options for software development with the OMAP3 systems.  Below is a photo of a very simple Qt application.  GTK+ and Enlightenment are other popular GUI toolkits.  With 256MB of both flash and RAM, this is more than enough memory for most embedded applications, and provides plenty of headroom for adding features for future product revisions.  The Overo has the CPU processing capability to run advanced GUI applications with 3-D affects, as well as advanced web application frameworks like web2py that previous generations of ARM CPUs could not effectively run.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2010&#x2F;01&#x2F;img_2287_-1.jpg&quot; alt=&quot;A simple Qt application that controls LEDs and reads user switch&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Gumstix Overo provides an excellent value for developing advanced products.  Especially for low volume products, when you compare the effort and time required to develop a full custom OMAP3 solution versus a simple Overo baseboard, using a module can provide significant advantages in terms of time to market, and development cost.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Go language for embedded systems</title>
        <published>2010-01-06T00:00:00+00:00</published>
        <updated>2010-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/579/the-go-language-for-embedded-systems/"/>
        <id>https://bec-systems.com/579/the-go-language-for-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/579/the-go-language-for-embedded-systems/">&lt;p&gt;As one of the things I do is evaluate new technologies for embedded systems, the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go language&lt;&#x2F;a&gt; from Google is an interesting development.  I have been looking for a better “system” language for some time.  What I mean by a better system language is one that is nearly as efficient as C, does not require a large runtime, has a fast start-up time, and yet supports modern language features.  It is interesting that the constraints for very high performance server applications are often similar to those found in embedded systems in that applications must make very efficient use of memory and CPU cycles.  This is why C++ is still used a lot by Google and is also popular in embedded systems, but is not as common in applications where CPU power is plentiful compared to the resources to implement the application such as business applications.  One area of divergence is the focus on multi-core for high end server applications, but in the next few years, multi-core CPU’s such as the Atom and ARM Cortex-A9 will likely be common in low power embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;There are other options.  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;live.gnome.org&#x2F;Vala&quot;&gt;Vala&lt;&#x2F;a&gt; is very nice to use, is efficient, offers advanced language features, and extensive language bindings.  Vala is being used to implement some of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;freesmartphone.org&quot;&gt;http:&#x2F;&#x2F;freesmartphone.org&lt;&#x2F;a&gt; software stack.  C&#x2F;C++ are the old standby languages, but are rather tedious to program in compared to some of the newer languages in that source and header files are separate, and memory management is manual.&lt;&#x2F;p&gt;
&lt;p&gt;My interest in Go at this time is for ARM systems, so I ran a few experiments.  From what I can tell, there does exist an ARM Go compiler that is able to produce ARM code, but it &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;golang-nuts&#x2F;browse_thread&#x2F;thread&#x2F;a36e6e2cb254ea36&#x2F;760ef589ad750958&quot;&gt;currently lacks support for EABI soft floating point&lt;&#x2F;a&gt;.  The lack of floating point support is pretty much a show stopper for now, but it is at least a start.  The following is an example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;export GOARCH=arm
cd $GOROOT&#x2F;src&#x2F;
.&#x2F;make-arm.bash

cd
(create the following source file: hello.go)

==================
package main
import &amp;quot;fmt&amp;quot;

func main() {
        fmt.Printf(&amp;quot;Hello, world\n&amp;quot;);
}
=================

5g hello.go   (5g is the ARM compiler)
5l hello.5
scp 5.out root@n900:  (copy to ARM system)
ssh root@n900
?:~# .&#x2F;5.out
Hello, world

(modify with floating point code)

==================
package main
import &amp;quot;fmt&amp;quot;

func main() {
        var f = 1.5;
        fmt.Printf(&amp;quot;Hello, world\n&amp;quot;);
        fmt.Printf(&amp;quot;float f = %f\n&amp;quot;, f);
}

=================

(now run on ARM system)
?:~# .&#x2F;5.out
Segmentation fault
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As, you can see, floating point does not work as expected.  I’m not sure yet if gogcc can be configured to compile ARM binaries.  The other area where Go appears to need a lot of work is bindings to various libraries.  Though it does not appear to be ready for embedded ARM systems at this time, Go will be an interesting language to watch over the next few years.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenEmbedded development activity</title>
        <published>2009-12-29T00:00:00+00:00</published>
        <updated>2009-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/576/openembedded-development-activity/"/>
        <id>https://bec-systems.com/576/openembedded-development-activity/</id>
        
        <content type="html" xml:base="https://bec-systems.com/576/openembedded-development-activity/">&lt;p&gt;Ever since I have been sending out &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;search.gmane.org&#x2F;?query=weekly+changelog&amp;amp;author=&amp;amp;group=gmane.comp.handhelds.openembedded&amp;amp;sort=date&amp;amp;DEFAULTOP=and&amp;amp;xP=Zweek%09Zchangelog&amp;amp;xFILTERS=Gcomp.handhelds.openembedded---A&quot;&gt;weekly change logs&lt;&#x2F;a&gt;, I have been impressed by the consistent amount of development activity in the OpenEmbedded project.  Every week there are consistently over a dozen developers making changes.  Developers come and go, but the contribution level always seems healthy.  While this amount of development leads to some amount of churn and issues, this amount of development is also required to keep pace with all the new developments in the OSS space.  Not having to wait 2 years for the next big release is one of the big advantages of using Linux and OpenEmbedded.  Having access to the latest technology provides a competitive advantage for many products, and makes dealing with the occasional issues that come up an acceptable trade-off.  Coupled with a flexible and consistent build system, OpenEmbedded is the vehicle to build advanced products.  Yes, its hard.  Yes, you better budget for some system software development time.  Yes, you should get some help if you’re not an embedded Linux expert.  Yes, you can start with some canned vendor “BSP” that seems to work and is seemingly the low-cost way to go, but eventually you’ll hit a brick wall where you need some bit of functionality that is not there, and then you’ll start up the exponential curve of dumping lots of time into trying to make something work with little progress forward.  It is much better to count the cost up front, and do things right.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OMAP3 Resume Timing</title>
        <published>2009-12-07T00:00:00+00:00</published>
        <updated>2009-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/569/omap3-resume-timing/"/>
        <id>https://bec-systems.com/569/omap3-resume-timing/</id>
        
        <content type="html" xml:base="https://bec-systems.com/569/omap3-resume-timing/">&lt;p&gt;One of the most common power management modes for ARM processors is the suspend mode.  In this mode, peripherals are shut down when possible, the SDRAM is put into self-refresh, and the CPU is placed in a low power mode.  A useful bit of information is to know how soon the system can respond to a resume (wake) event.&lt;&#x2F;p&gt;
&lt;p&gt;It turns out the answer to this question depends on where you want to do the work.  In the first test, I created a simple application that continuously toggled a GPIO.  This is an easy way to tell determine with a scope when the application was running.  I then measured the time between the wake event, and when this application signal started toggling.  It was a consistent 180ms.&lt;&#x2F;p&gt;
&lt;p&gt;For the next test I simply toggled a gpio in the &lt;em&gt;omap3_pm_suspend()&lt;&#x2F;em&gt; first thing after resume.  This tells me roughly how fast I can execute code in the kernel after a wake event.  This turned out to be 250uS.&lt;&#x2F;p&gt;
&lt;p&gt;So the good news is we can run kernel code very quickly after a resume event (250uS), but it currently takes a long time until user space processes start running again (180mS).  The 180ms can likely be reduced with some work, but this at least gives us a baseline.  180ms is fairly quick from a human perspective (seems pretty much instant), but for industrial devices that are responding to real-world events, then 180mS can be a long time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux kernel stats, and long term advantages</title>
        <published>2009-12-01T00:00:00+00:00</published>
        <updated>2009-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/"/>
        <id>https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/</id>
        
        <content type="html" xml:base="https://bec-systems.com/564/linux-kernel-stats-advantages-and-long-term-advantages/">&lt;p&gt;I just read an interesting &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;howsoftwareisbuilt.com&#x2F;2009&#x2F;11&#x2F;18&#x2F;interview-with-greg-kroah-hartman-linux-kernel-devmaintainer&#x2F;&quot;&gt;interview&lt;&#x2F;a&gt; with Greg Kroah Hartman.  According to Greg, we add 11,000 lines, remove 5500 lines, and modify 2200 lines every single day.  This rate of change is something that few organizations have the resources to match.  It is interesting that Google chose to use the Linux kernel in the Android project even though they implemented most other parts of the system.  Another interesting thing to consider is the consequences of the Linux kernel license, which requires many drivers to be released as GPL.  While initially, this may be viewed as a disadvantage, it leads to some interesting long-term implications.  The obvious effect is that most Linux driver code is maintained in the mainline kernel source.  This leads to other effects.  One is that things are allowed to change, and get better.  The USB stack in both Linux and Windows has been re-written several times, but the difference is that in Linux the old software does not need to be maintained, as most drivers are maintained in the kernel, and can simply be modified along with core changes.  Another advantage is that drivers tend to be much simpler as common code is merged.  As a result, a Linux driver tends to be about 1&#x2F;3 the size of a driver in other operating systems.  Yes, getting driver code accepted in the mainline kernel can be difficult at times, but it is clearly the best long-term option.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux PM: OMAP3 Suspend Support</title>
        <published>2009-11-23T00:00:00+00:00</published>
        <updated>2009-11-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/551/linux-pm-omap3-suspend-support/"/>
        <id>https://bec-systems.com/551/linux-pm-omap3-suspend-support/</id>
        
        <content type="html" xml:base="https://bec-systems.com/551/linux-pm-omap3-suspend-support/">&lt;p&gt;This article provides an overview of the Linux kernel support for the suspend state in the TI OMAP3.  Power management has always been one of the more difficult parts of a system to get right.  The OMAP3 power management is quite extensive.  There are many levels of very granular control over the entire system.  Initially, we are going to focus on a simple power state where we want to put the CPU in a low power mode (basically not doing anything), but resume very quickly once an event occurs and continue running applications where they left off.  This is typically called “Suspend”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;power-states&quot;&gt;Power States&lt;&#x2F;h2&gt;
&lt;p&gt;We must first match up terminology between the Linux kernel and the OMAP documentation.  The Linux kernel supports several suspend power states:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_ON&lt;&#x2F;strong&gt;: system is running&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_STANDBY&lt;&#x2F;strong&gt;: system is in a standby state.  This is typically implemented where the CPU is in a somewhat static state.  After all the peripherals have been shut down, and the memory put into self refresh, the CPU executes an instruction that puts the CPU into a low power state.  After the next wake-event occurs, the CPU resumes operating at the next instruction.  The CPU state is static in this case.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_MEM&lt;&#x2F;strong&gt;: This goes one step beyond STANDBY in that the CPU is completely powered down and loses its state.  Any CPU state that needs to be saved is stored to SDRAM (which is in self refresh), or some other static memory.  When the system resumes, it has to boot through the reset vector.  The bootloader determines that the system was sleeping, and re-initializes the system, enables the SDRAM, restores whatever state is needed, and then jumps to a vector in the kernel to finish the resume sequence.  This mode is fairly difficult to implement as it involves the bootloader, and a lot of complex initialization code that is difficult to debug.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PM_SUSPEND_MAX&lt;&#x2F;strong&gt;: From browsing the kernel source code, it appears this state is used for “Off” or perhaps suspend to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The OMAP3 documentation uses the following terms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SLM&lt;&#x2F;strong&gt;: Static Leakage Management.  Includes “suspend” functionality.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Standby&lt;&#x2F;strong&gt;:  OMAP3x retains internal memory and logic.  (uses 7mW)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Device Off&lt;&#x2F;strong&gt;: System state is saved to external memory(0.590mW).  This could theoretically map to the PM_SUSPEND_MEM state.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;WFI&lt;&#x2F;strong&gt;: Wait for Interrupt.  This is an ARM instruction that puts the CPU in the standby state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Based on the source code in the Linux kernel, there is currently only support for the Standby state:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;static int omap3_pm_enter(suspend_state_t unused)
{
	int ret = 0;

switch (suspend_state) {
	case PM_SUSPEND_STANDBY:
	case PM_SUSPEND_MEM:
		ret = omap3_pm_suspend();
		break;
	default:
		ret = -EINVAL;
	}

return ret;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;what-kernel-branches-versions-support-pm&quot;&gt;What kernel branches&#x2F;versions support PM&lt;&#x2F;h2&gt;
&lt;p&gt;Kevin Hilman has been maintaining an OMAP3 power management branch at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;khilman&#x2F;linux-omap-pm.git&quot;&gt;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;khilman&#x2F;linux-omap-pm.git&lt;&#x2F;a&gt;.  Bits are being merged upstream.  Some of the things that don’t seem to be merged yet are SmartReflex support, and a number of other details.  But, it seems that basic suspend&#x2F;resume support is available in the upcoming 2.6.32 kernel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-details-on-the-standby-mechanism&quot;&gt;More Details on the Standby Mechanism&lt;&#x2F;h2&gt;
&lt;p&gt;Due to the granularity and complexity of the the OMAP3 power management, relevant pieces of documentation are scattered throughout the OMAP35x Technical Reference Manual.  The following were helpful:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Table 3-17: details the MPU subsystem operation power modes&lt;&#x2F;li&gt;
&lt;li&gt;Table 3-18: Power Mode Allowable Transitions.  Standby
mode can enter from active mode only by executing the wait for interruption (WFI) instruction.&lt;&#x2F;li&gt;
&lt;li&gt;SDRC, “Self Refresh Management”.  The OMAP3 can automatically put the SDRAM in self refresh mode when the CPU enters the idle state.&lt;&#x2F;li&gt;
&lt;li&gt;MPU Power Mode Transistions: The ARM core initiates entering into standby via software only (CP15 - WFI).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;em&gt;omap34xx_cpu_suspend&lt;&#x2F;em&gt; function is called to put the CPU into standby mode.  The actual instruction that stops the CPU is the ARM WFI (wait for interrupt) instruction.  This is a little different than previous generations of ARM CPUs that used coprocessor registers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h2&gt;
&lt;p&gt;With the 2.6.32-rcX kernels, suspend&#x2F;resume appears to work at least from the console:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@overo:~# echo mem &amp;gt; &#x2F;sys&#x2F;power&#x2F;state
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.00 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.00 seconds) done.
Suspending console(s) (use no_console_suspend to debug)

&amp;lt;after key press on serial console ...&amp;gt;

omapfb omapfb: timeout waiting for FRAME DONE
CLIFF: going into suspend
Wake up daisy chain activation failed.
CLIFF: returning from suspend
Successfully put all powerdomains to target state
Restarting tasks ...
done.
root@overo:~#
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The CLIFF messages are debug statements placed in the low-level suspend code to make sure we were getting to that point.  The console is disabled early in the suspend process, so we don’t get the debug messages until after resume.  The &lt;em&gt;no_console_suspend&lt;&#x2F;em&gt; kernel option can be used to leave the console enabled during suspend, but that feature does not seem to work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary-future-work&quot;&gt;Summary&#x2F;Future work&lt;&#x2F;h2&gt;
&lt;p&gt;This covers the basics of Linux Suspend&#x2F;Resume support for the OMAP3 CPU.  There are many more options and details such as configuring wake sources, dynamic power management while running, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Integrated CAN solutions for Linux</title>
        <published>2009-11-19T00:00:00+00:00</published>
        <updated>2009-11-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/544/integrated-can-solutions-for-linux/"/>
        <id>https://bec-systems.com/544/integrated-can-solutions-for-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/544/integrated-can-solutions-for-linux/">&lt;p&gt;I just received an email notification from EMS (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ems-wuensche.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;ems-wuensche.com&#x2F;&lt;&#x2F;a&gt;) that support for their CAN controllers is now in mainline Linux kernels.  The EMS PCI products are supported in 2.6.31, and the CPC-USB product will be supported in 2.6.32.  I’ve used various Linux CAN stacks in the past, but none were as well integrated as the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SocketCAN&quot;&gt;SocketCAN&lt;&#x2F;a&gt; solution that has been merged into the mainline Linux kernel.  Though I’ve not used the EMS products yet, the fact that support is in the mainline kernel source provides a good indication that they know how to do things correctly, and that the software is of good quality.&lt;&#x2F;p&gt;
&lt;p&gt;The Microchip MCP2515 is another option for interfacing CAN with a Linux system, but uses the SPI bus so it typically requires a custom hardware design.   The availability of a USB adapter provides an easy way for CAN to be used with about any existing Linux system including small embedded systems.  From looking at the kernel source code, it appears that EMS solutions use the SJA1000 CAN controller, which has been an industry standard controller for many years.&lt;&#x2F;p&gt;
&lt;p&gt;Message buffering is an important consideration when selecting a Linux CAN solution.  Often in a system, the Linux computer is responsible for data processing, user interface, and other CPU intensive operations.  The real-time control is often relegated to a separate microcontroller.  The CAN bus is then just a convenient and robust way to get data from the control part of the system to the data processing part.  The amount of hardware buffering in the CAN controller determines how quickly the system needs to respond to process the CAN data, so the CAN controller has space to receive new data.  The SJA1000 provides a 64-byte receive fifo, or roughly space for 4 CAN messages.  This provides a little more buffering than the 2 messages in the MCP2515.  Dealing with full bandwidth CAN data in a Linux system can be a challenge  with small amounts of buffering as you typically have to implement the Linux RT patch, and spend some time tuning it.  Another upcoming CAN solution that looks nice is the TI High End CAN Controller (HECC) found in the new Sitara CPUs.  This controller provides 32 hardware mailboxes which should provide even more buffering, which makes it even better suited for operating systems like Linux.  As with any technology, there are tradeoffs, so its nice to have options.&lt;&#x2F;p&gt;
&lt;p&gt;One area the EMS solution may be very useful is for prototyping and development.  The ideal development flow when developing an Embedded Linux product is to development as much as possible on a PC.  The EMS product allows you to easily implement SocketCAN functionality on a PC so you can talk to the rest of your system directly from a PC.  The final embedded solution may be based on a more cost effective solution like the MCP2515 or the TI HECC, but being able to interface to the rest of the system directly from a PC has the potential to improve development efficiency.  This is part of the “Big Win” with Embedded Linux where the same technology scales from the embedded system, to the PC, to the server.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notification at the end of builds</title>
        <published>2009-11-05T00:00:00+00:00</published>
        <updated>2009-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/540/notification-at-the-end-of-builds/"/>
        <id>https://bec-systems.com/540/notification-at-the-end-of-builds/</id>
        
        <content type="html" xml:base="https://bec-systems.com/540/notification-at-the-end-of-builds/">&lt;p&gt;I do quite a few OpenEmbedded project builds during the course of a week.  This process usually takes 3-5 minutes.  That is just enough time to get distracted doing something else and forget about the build until an hour later when you realize – oops, I was supposed to send out a release email once the build was finished and uploaded.  It occured to me that it would be nice if my computer played a distinct sound at the end of the build.  With Linux this is incredibly easy:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;wget http:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;7&#x2F;76&#x2F;Ding_Dong_Bell.ogg&lt;&#x2F;li&gt;
&lt;li&gt;sudo mv Ding_Dong_Bell.ogg &#x2F;usr&#x2F;local&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;sudo aptitude install cplay&lt;&#x2F;li&gt;
&lt;li&gt;sudo echo “cplay &#x2F;usr&#x2F;local&#x2F;Ding_Dong_Bell.ogg” &amp;gt; &#x2F;usr&#x2F;local&#x2F;bin&#x2F;bell&lt;&#x2F;li&gt;
&lt;li&gt;sudo chmod 775 &#x2F;usr&#x2F;local&#x2F;bin&#x2F;bell&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, when I have a long build, I simply do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bitbake my-image; bell
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is probably something better than cplay that does not start a UI – any suggestions?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A quick serial logging application</title>
        <published>2009-10-21T00:00:00+00:00</published>
        <updated>2009-10-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/533/a-quick-serial-logging-application/"/>
        <id>https://bec-systems.com/533/a-quick-serial-logging-application/</id>
        
        <content type="html" xml:base="https://bec-systems.com/533/a-quick-serial-logging-application/">&lt;p&gt;Recently when debugging a device connected to a rs485 bus, I needed a simple application to dump the raw data coming over the rs485 bus.  Minicom does all kinds of weird terminal stuff, plus it will not display binary data, so that was out.  While looking for serial analyzer programs for Linux, and pondering writing my own simple C application, it occurred to me to use pyserial.  With a few lines of code, I got exactly what I needed:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;import serial
import sys
import struct

if len(sys.argv) != 3:
    print &amp;quot;Usage: serial-dump.py &amp;lt;serial port&amp;gt; &amp;lt;baud rate&amp;gt;&amp;quot;
    sys.exit(-1)

print &amp;quot;Dumping data on %s&amp;quot; % (sys.argv[1])

ser = serial.Serial(sys.argv[1], sys.argv[2], timeout=0.3)

while(1):
    buf = ser.read(500)
    if len(buf) &amp;gt; 0:
        print &amp;quot;Read %i bytes:&amp;quot; % (len(buf)),

for i in buf:
            value = struct.unpack(&amp;#39;B&amp;#39;, i)[0]
            print &amp;quot;%02x&amp;quot; % (value),

print &amp;quot;&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The full source is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;svn.bec-systems.com&#x2F;pub&#x2F;py-serial-dump&#x2F;serial-dump.py&quot;&gt;here&lt;&#x2F;a&gt;.  This could obviously be improved to do true blocking reads, automatically parse protocols, implement a gui, etc.  Ideas for efficiently reading data using pyserial is available in a &lt;a href=&quot;&#x2F;257&#x2F;tips-for-reading-a-serial-data-stream-in-python&#x2F;&quot;&gt;previous post&lt;&#x2F;a&gt;.  Another example of using a scripting language for quick tasks is &lt;a href=&quot;&#x2F;226&#x2F;a-really-nice-hex-calculator&#x2F;&quot;&gt;&#x2F;226&#x2F;a-really-nice-hex-calculator&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Apache and how to correctly use NameVirtualHost</title>
        <published>2009-10-16T00:00:00+00:00</published>
        <updated>2009-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/"/>
        <id>https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/</id>
        
        <content type="html" xml:base="https://bec-systems.com/528/apache-and-how-to-correctly-use-namevirtualhost/">&lt;p&gt;As I often get involved in server administration (SVN, git, redmine, etc setup), I deal with Apache on a regular basis.  For simple configurations, the default Ubuntu&#x2F;debian config works well.  However, for a more complex setup with virtual hosts, multiple IP addresses, and SSL support, it is common to run into the following message:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;mixing * ports and non-* ports with a NameVirtualHost address is not supported, proceeding with undefined results&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Googling does not return a clear explanation to this problem, so that is why I’m writing this article. The impulsive approach of randomly changing things does not get you too far – especially with the Debian&#x2F;Ubuntu Apache configuration that is composed of seperate files for each virtual host.  After reading the documentation, things become clearer:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note that the argument to the &lt;code&gt;&amp;lt;VirtualHost&amp;gt;&lt;&#x2F;code&gt; directive must       exactly match the argument to the &lt;code&gt;NameVirtualHost&lt;&#x2F;code&gt; directive.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And, by considering the fact that the seperate virtual host config files really just get concatenated into one big file, it makes sense that you can’t have more than one NameVirtualHost entry.  Ubuntu by default puts the NameVirtualHost in the default virtual host file, which gets soft linked to sites-enabled&#x2F;000-default.  I presume the ‘000’ means it gets loaded first.  I find it much more intuitive to put the NameVitualHost directives in the &#x2F;etc&#x2F;apache2&#x2F;httpd.conf file.  This way it is clear that these entries are common to all virtual host entries.  So what I end up with is:&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;apache2&#x2F;httpd.conf&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;NameVirtualHost 74.208.184.45:80
NameVirtualHost 74.208.184.46:80
NameVirtualHost 74.208.184.45:443
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apache2&#x2F;sites-available&#x2F;bec-systems.com&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:80&amp;gt;
        ServerName bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;bec-systems.com.ssl&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:443&amp;gt;
        ServerName bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;svn.bec-systems.com&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.45:80&amp;gt;
        ServerName svn.bec-systems.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;apach2&#x2F;sites-available&#x2F;site2.com (with different IP address)&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost 74.208.184.46:80&amp;gt;
        ServerName site2.com
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again, the points to remember are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The argument to VirtualHost must match a NameVirtualHost directive&lt;&#x2F;li&gt;
&lt;li&gt;the NameVirtualHost directive is common, so there should only be one entry&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for kernel development with OpenEmbedded</title>
        <published>2009-10-13T00:00:00+00:00</published>
        <updated>2009-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/"/>
        <id>https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/521/best-practices-for-kernel-development-with-openembedded/">&lt;p&gt;A common question is how do you do kernel development with OpenEmbedded?  Typically, OpenEmbedded builds a kernel by checking the source out of a git repository, or by applying patch files to a released version of the kernel.  See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&quot;&gt;many recipes&lt;&#x2F;a&gt; for examples.  This works very well for a Linux distribution build system, but is less than ideal for ongoing kernel development where you will have many iterations over a period of time. The OE work directory is considered transient, and should not be used for any ongoing development.  Fortunately, the kernel build system is self contained, so it is a very simple matter to reference the toolchain built by OpenEmbedded and work outside the OpenEmbedded build system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-git&quot;&gt;Use Git&lt;&#x2F;h2&gt;
&lt;p&gt;Trust me on this one, just use it!  It will make your life easier.  There is a learning curve to any powerful tool.  Another way to state this is if a tool does not do much, then it would be easy to learn.  So expect to spend a little time learning to use git.  With modern Linux kernel development, much of your time is spent integrating work that others are doing.  For example, if you are using the OMAP3 CPU, you might want to start with linux-omap branch, integrate some patches from the OE beagleboard build, merge the OMAP PM tree, and then merge some bits from the Linux-wireless tree.  This is the way embedded Linux development is done today.  Git makes it possible to have many parallel developments going at their own pace, including your own.  Even in your own development, you will find significant advantages to being able to quickly create and merge branches, revise commits, etc.  There are several &lt;a href=&quot;&#x2F;tags&#x2F;git&#x2F;&quot;&gt;articles about git&lt;&#x2F;a&gt; on this site.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;importing-an-oe-kernel-into-git&quot;&gt;Importing an OE kernel into git&lt;&#x2F;h2&gt;
&lt;p&gt;If you are starting with an existing OE kernel tree, then you typically need to set up an equivalent tree in your local git workspace.  Typically you just look at the recipe to see how to manually reconstruct it.  For example, lets consider the SRC_URI from the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-palm-omap1_2.6.22-omap1.bb&quot;&gt;palm-omap1&lt;&#x2F;a&gt; recipe:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;${KERNELORG_MIRROR}&#x2F;pub&#x2F;linux&#x2F;kernel&#x2F;v2.6&#x2F;linux-2.6.22.tar.bz2 \
           http:&#x2F;&#x2F;www.muru.com&#x2F;linux&#x2F;omap&#x2F;patches&#x2F;patch-2.6.22-omap1.bz2;patch=1 \
	   file:&#x2F;&#x2F;defconfig&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To set this kernel up in git, we might do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;git clone git:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux-2.6.git&lt;&#x2F;li&gt;
&lt;li&gt;cd linux-2.6&lt;&#x2F;li&gt;
&lt;li&gt;git checkout -b my_branch v2.6.22&lt;&#x2F;li&gt;
&lt;li&gt;wge&lt;code&gt;t http:&#x2F;&#x2F;www.muru.com&#x2F;linux&#x2F;omap&#x2F;patches&#x2F;patch-2.6.22-omap1.bz2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;bzip2 -d patch-2.6.22-omap1.bz2&lt;&#x2F;li&gt;
&lt;li&gt;git am patch-2.6.22-omap1&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If the git am fails, then you might need to add a subject and author line to the patch in the following form and then retry git am.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;From: Name &amp;lt;name@company.com&amp;gt;
Subject: omap1 patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now when you do a git log, you will see the above patch applied.  git apply can also be used to apply patches, but I prefer git-am as it automatically handles new files and fills in the commit message and author.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-the-toolchain&quot;&gt;Setting up the toolchain&lt;&#x2F;h2&gt;
&lt;p&gt;Now that you have a kernel, you must set up a toolchain so you can build it.  I typically set up my kernel directory next to my OE build directory in my project space, so I can then source the following &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;oe&#x2F;scripts&#x2F;setup-env&quot;&gt;script&lt;&#x2F;a&gt; to set up the toolchain:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CROSS_COMPILER_PATH=`cd ..&#x2F;oe&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;cross&#x2F;armv7a&#x2F;bin; pwd`
BUILD_ARCH=`uname -m`
OE_STAGING_PATH=`cd ..&#x2F;oe&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;staging&#x2F;${BUILD_ARCH}-linux&#x2F;usr&#x2F;bin; pwd`
STAGING_KERNEL_DIR=`cd linux-2.6; pwd`
export PATH=$PATH:$CROSS_COMPILER_PATH:$OE_STAGING_PATH
export ARCH=arm
export CROSS_COMPILE=arm-angstrom-linux-gnueabi-
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adjust to whatever you are building for.  Now you can simply type make.  The reason the OE_STAGING_PATH is added to the PATH in the above example is so that the uboot mkimage utility can be used directly from the OE build if your build target is make uImage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-modules&quot;&gt;Installing modules&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes you need to re-install all modules on the target because you changed kernel version, etc.  Typically OE packages up all modules and adds the one you specify to the rootfs.  Because we are building the kernel outside the OE directory, OE can no longer do this.  However, its still very easy to install modules from your kernel development directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;rm -rf modules_install; INSTALL_MOD_PATH=modules_install make modules_install
rsync -av modules_install&#x2F;lib&#x2F;modules&#x2F;2.6.22 root@192.168.1.115:&#x2F;lib&#x2F;modules&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first command installs the modules to a temporary directory, and the second command rsync’s the modules to your target system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-a-kernel-recipe-with-your-changes&quot;&gt;Creating a kernel recipe with your changes&lt;&#x2F;h2&gt;
&lt;p&gt;Once you get to the point where you want to create a recipe with your changes, you can easily export a patch, or series of patches using git diff or git format-patch.  Simply add the patch files to your kernel recipe SRC_URI.  You can also teach bitbake to fetch your kernel source directly from a git repository, but I’ve generally found the patch mechanism to be adequate and easier in most cases.  As an example, you can create one large patch with all your changes that can be applied on the 2.6.22 released kernel:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git diff HEAD..v2.6.22 &amp;gt; my_kernel_changes.patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;other-ways&quot;&gt;Other ways …&lt;&#x2F;h2&gt;
&lt;p&gt;This is just one flow and there are many variations.  There is also a  new mechanism in OpenEmbedded called srctree that allows you to use OpenEmbedded in an external source tree.  srctree has the potential to further streamline this type of development.&lt;&#x2F;p&gt;
&lt;p&gt;As with any task, you want to use the tools that make sense for the task.  OpenEmbedded makes sense for building Linux distributions, but it is not a kernel development tool.  Git and the kernel build system make sense for kernel development.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>converting digital camera movies to ogg format</title>
        <published>2009-09-09T00:00:00+00:00</published>
        <updated>2009-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/"/>
        <id>https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/</id>
        
        <content type="html" xml:base="https://bec-systems.com/514/converting-digital-camera-movies-to-ogg-format/">&lt;p&gt;Now that firefox (v3.5) has built in support for ogg videos, ogg is now the most convenient format for “easy to view” video files (assuming you don’t want to use a service like youtube).  Some digital cameras (like my Canon) records movies in AVI format.  I created a script that uses gstreamer to convert the AVI file to an ogg file for easy viewing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;avi_to_ogg&#x2F;avi_to_ogg&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;avi_to_ogg&#x2F;avi_to_ogg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And some of the results:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;video&#x2F;&quot;&gt;&#x2F;video&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(hint, download firefox 3.5 to view these videos)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for building Gtk+ applications with OpenEmbedded</title>
        <published>2009-09-08T00:00:00+00:00</published>
        <updated>2009-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/"/>
        <id>https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/509/best-practices-for-building-gtk-applications-with-openembedded/">&lt;p&gt;I recently&lt;a href=&quot;&#x2F;501&#x2F;best-practices-for-building-qt-applications-with-openembedded&#x2F;&quot;&gt;wrote an article about best practices building Qt applications with OpenEmbedded&lt;&#x2F;a&gt;, and it occured to me that I should write an equivalent article for Gtk+ applications.  The same points apply – put your application source in a SCM system, and put the install logic in the application source (read the above article).  The difference is that Gtk applications typically use autotools where Qt applications use qmake to build the application.  This article details how a minimal GTK+ application should be set up and built using OpenEmbedded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;application-source&quot;&gt;Application Source&lt;&#x2F;h2&gt;
&lt;p&gt;I created a sample GTK hello application located at: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&lt;&#x2F;a&gt;.  This is a SVN repository, so you can simply “svn co” the above URI to check out the code.  If you are running Ubuntu, you can install the necessary tools to build a native Gtk+ application by:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;sudo apt-get install libgtk2.0-dev build-essential autoconf automake pkg-config&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To build on your x86 Linux PC, run the following steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;svn co  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;gtk_hello&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;cd gtk_hello&lt;&#x2F;li&gt;
&lt;li&gt;autoreconf -i&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure --prefix=`pwd`&#x2F;install&lt;&#x2F;li&gt;
&lt;li&gt;make install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This compiles and installs the application in to the “install” directory.  If you look in this directory, you will notice the application binary is installed in the “install&#x2F;bin” directory.  Typically, the install directory is set to &#x2F;usr&#x2F;bin, but in this example we set it to install so we don’t need to run “make install” as root, but yet we can verify the install logic works properly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openembedded-recipe&quot;&gt;OpenEmbedded Recipe&lt;&#x2F;h2&gt;
&lt;p&gt;Now that you have verified the application builds and installs properly on a x86 PC, it is trivial to build the application in OpenEmbedded.  Create a recipe in your OE recipes directory named &lt;em&gt;gtk-hello_svn.bb&lt;&#x2F;em&gt; with the following contents:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;Sample Gtk+ Hello application, used to demonstrate build system&amp;quot;
AUTHOR = &amp;quot;Cliff Brake &amp;lt;cbrake@bec-systems.com&amp;gt;&amp;quot;

SRCREV = &amp;quot;17&amp;quot;
PV = &amp;quot;0.0+svn${SRCREV}&amp;quot;
PR = &amp;quot;r0&amp;quot;

DEPENDS = &amp;quot;gtk+&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=gtk_hello;proto=http;rev=17&amp;quot;

S = &amp;quot;${WORKDIR}&#x2F;gtk_hello&#x2F;&amp;quot;

inherit autotools
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, run: bitbake gtk-hello.  That is it!  Building Linux applications is easy if you simply use the tools, whether it be autotools, qmake, etc.  Too often there is the tendency to set up your own compile steps with ${CC} variables, etc.  While this seems to be the simple approach at first glance (autotools is too hard), it quickly becomes unmaintainable and in the end is a lot more work than simply learning the basics of the industry standard tools.  See &lt;a href=&quot;&#x2F;121&#x2F;autotools-quick-reference&#x2F;&quot;&gt;previous autotools article&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best practices for building Qt applications with OpenEmbedded</title>
        <published>2009-08-06T00:00:00+00:00</published>
        <updated>2009-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/"/>
        <id>https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/501/best-practices-for-building-qt-applications-with-openembedded/">&lt;p&gt;This article describes how to cross compile a Qt application (named qt_tutorial) with OpenEmbedded, and several best practices you should consider.  OpenEmbedded currently includes &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&#x2F;qt4&quot;&gt;fairly good support for building Qt&lt;&#x2F;a&gt; – both Qt Embedded and Qt X11.   OE also includes a number of &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;classes&quot;&gt;qt classes&lt;&#x2F;a&gt; that make building Qt applications easy.  One of the main considerations with embedded Linux application development is that you keep the build system flexible so that you can easily build on a PC or for your embedded hardware.  This means that hand crafted Makefiles with hardcoded paths to cross compilers do not quality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;put-your-application-in-a-scm-system&quot;&gt;Put Your Application in a SCM system&lt;&#x2F;h2&gt;
&lt;p&gt;No matter what type of application you are building, it is a good idea to put your source in a SCM or revision control system and fetch it directly using OE.  OpenEmbedded supports fetching sources from a number of revision control systems including Subversion, Git, Bazaar, Mercurial, CVS, etc.   The not so obvious reason we do this is so you can easily check out the source code and build it on a PC as well as your target system in OE.  In this example we fetch the application source from a SVN repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=qt_tutorial;proto=http&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the above repository, the direct URI to the source would be: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;qt_tutorial&#x2F;&quot;&gt;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;qt_tutorial&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;put-the-install-logic-in-the-application-source&quot;&gt;Put the Install logic in the Application Source&lt;&#x2F;h2&gt;
&lt;p&gt;Most Linux applications support “make install”, and this is the case with autotools, and qmake (Qt’s build tool).  We could put logic in the OE recipe to install the application something like the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;do_install() {
	install -d ${D}&#x2F;${bindir}
	install -m 0755  ${S}&#x2F;qt_tutorial ${D}&#x2F;${bindir}
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, the problem with this approach is you can’t install the application in other environments (like a native x86 PC build) unless you are building with OE.  So a better approach is to put the logic to install the application in the application source, so that in can be installed in both your PC environment, and your OpenEmbedded build.  To accomplish this, you can set up the project as follows&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;application qmake project file (qt_tutorial.pro):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;TEMPLATE = app
TARGET = qt_tutorial
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += lcdrange.h
SOURCES += lcdrange.cpp main.cpp

target.path = &#x2F;usr&#x2F;bin
INSTALLS += target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;OpenEmbedded recipe (qt-tutorial_svn.bb):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;inherit qt4e

SRCREV = &amp;quot;${AUTOREV}&amp;quot;
PV = &amp;quot;1.0+svnr${SRCREV}&amp;quot;
PR = &amp;quot;r1&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub;module=qt_tutorial;proto=http&amp;quot;

S = ${WORKDIR}&#x2F;qt_tutorial

FILES_${PN}-dbg += &amp;quot;${bindir}&#x2F;.debug&amp;quot;

do_install() {
	export INSTALL_ROOT=${D}
	make install
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, the same mechanism is used to install the application on both a PC native build, as well an OpenEmbedded build.  If you look in the Makefile generated by qmake, you see the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;install_target: first FORCE
	@$(CHK_DIR_EXISTS) $(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F; || $(MKDIR) $(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F;
	-$(INSTALL_PROGRAM) &amp;quot;$(QMAKE_TARGET)&amp;quot; &amp;quot;$(INSTALL_ROOT)&#x2F;usr&#x2F;bin&#x2F;$(QMAKE_TARGET)&amp;quot;

install:  install_target  FORCE
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;INSTALL_ROOT can be set to force the entire system to be installed in a subdirectory.  This is required for build systems that generate packages, like OpenEmbedded.  To build this example, put the qt-tutorial_svn.bb file in your OE recipes tree, and run: bitbake qt-tutorial.  This will fetch the source code and build a package.  To run the tutorial, install the package on a system that includes Qt Embedded, and then run: qt_tutorial -qws.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo Pinout Spreadsheet updated</title>
        <published>2009-07-30T00:00:00+00:00</published>
        <updated>2009-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/"/>
        <id>https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/</id>
        
        <content type="html" xml:base="https://bec-systems.com/491/gumstix-overo-pinout-spreadsheet-updated/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&quot;&gt;Gumstix Overo Pinout Spreadsheet&lt;&#x2F;a&gt; has been updated with the Palo board connector pinouts, and a few mistakes have been fixed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;overo_pinout2-1.png&quot; alt=&quot;overo_pinout2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;overo_pinout-1.png&quot; alt=&quot;overo_pinout&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to capture source changes to an OpenEmbedded package</title>
        <published>2009-07-14T00:00:00+00:00</published>
        <updated>2009-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/456/capture-oe-source-changes/"/>
        <id>https://bec-systems.com/456/capture-oe-source-changes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/456/capture-oe-source-changes/">&lt;p&gt;One task that is a often confusing to new OpenEmbedded users is how to capture changes to the source code for a package&#x2F;recipe.  First, lets review the progression in tools use to capture source code changes.&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;img title=&quot;patch_quilt_git1&quot; src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;patch_quilt_git1-1.png&quot; alt=&quot;Progression of tools&quot;&gt;&lt;figcaption&gt;Figure 1: Progression of tools&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;In days of yore, developers often used gnu diff to capture modifications to a source tree.  The typical practice was to create two source trees: a pristine, and a dirty tree.  Modifications were made in the dirty tree, and periodically gnu diff was run between the two trees to capture the changes.  Then came quilt which allowed you to capture changes without a pristine tree – kind of a cheap version control system.  The typical flow was:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cd &lt;source dir&gt;&lt;&#x2F;li&gt;
&lt;li&gt;quilt new my_changes.patch&lt;&#x2F;li&gt;
&lt;li&gt;quilt add file1.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file1.c&lt;&#x2F;li&gt;
&lt;li&gt;quilt refresh (now my_changes.patch records the edits to file1.c)&lt;&#x2F;li&gt;
&lt;li&gt;debug&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c&lt;&#x2F;li&gt;
&lt;li&gt;(oops forget to quilt add file2.c – now what ….)&lt;&#x2F;li&gt;
&lt;li&gt;restore file2.c from pristine source&lt;&#x2F;li&gt;
&lt;li&gt;quilt add file2.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c&lt;&#x2F;li&gt;
&lt;li&gt;quilt refresh&lt;&#x2F;li&gt;
&lt;li&gt;(now my_changes.patch records edits to file1.c and file2.c)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As you can see, things are much better than plain diff, but you still have to keep track of the files you edit.  With git, we can do essentially the same things, only git keeps track of the files you edit, plus it is easier to organize patch files.  The flow with git is something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cd &lt;source dir&gt;&lt;&#x2F;li&gt;
&lt;li&gt;git init&lt;&#x2F;li&gt;
&lt;li&gt;git add *&lt;&#x2F;li&gt;
&lt;li&gt;git commit (now the entire source tree is recorded by git)&lt;&#x2F;li&gt;
&lt;li&gt;edit file1.c&lt;&#x2F;li&gt;
&lt;li&gt;edit file2.c ….&lt;&#x2F;li&gt;
&lt;li&gt;git status (shows you files that were modified)&lt;&#x2F;li&gt;
&lt;li&gt;git add file1.c file2.c&lt;&#x2F;li&gt;
&lt;li&gt;git commit&lt;&#x2F;li&gt;
&lt;li&gt;git log (shows you changes you have made)&lt;&#x2F;li&gt;
&lt;li&gt;git format-patch HEAD~1 (outputs the patch created by the last commit)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Once your source code is in git, then you can do all kinds of fancy things like merging, re-ordering, and re-naming patch files with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git-core&#x2F;docs&#x2F;git-rebase.html&quot;&gt;git-rebase --interactive&lt;&#x2F;a&gt; command.&lt;&#x2F;p&gt;
&lt;p&gt;One of the uses of this technique is when you need to record a small change to a package source in a build system such as OpenEmbedded, and apply that change for subsequent builds.  In this case you might do something like the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;bitbake -c devshell &amp;lt;recipe_to_patch&amp;gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;in devshell capture changes in git as shown above to create &lt;em&gt;my_changes.patch&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;cp my_changes.patch &amp;lt;oe_tree&amp;gt;&#x2F;recipes&#x2F;&amp;lt;recipe_to_change&amp;gt;&#x2F;files&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;edit &amp;lt;oe_tree&amp;gt;&#x2F;recipes&#x2F;&amp;lt;recipe_to_change&amp;gt;&#x2F;&amp;lt;recipe_to_change&amp;gt;.bb&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;tell bitbake to apply the patch when building the recipe: SRC_URI += “file:&#x2F;&#x2F;my_changes.patch;patch=1”&lt;&#x2F;li&gt;
&lt;li&gt;increment the PR variable so that bitbake knows to rebuild the recipe.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Figure 2 illustrates the above steps.&lt;&#x2F;p&gt;
&lt;figure&gt;&lt;img title=&quot;oe_patch_flow1&quot; src=&quot;&#x2F;uploads&#x2F;2009&#x2F;07&#x2F;oe_patch_flow1-1.png&quot; alt=&quot;Flow to capture packages source changes in OpenEmbedded&quot;&gt;&lt;figcaption&gt;Figure 2: Flow to capture package source changes in OpenEmbedded&lt;&#x2F;figcaption&gt;&lt;&#x2F;figure&gt;
&lt;p&gt;While the above steps might seem overly complex, you must consider what you are trying to do.  Building a Linux distribution is not a simple task.  We are dealing with large amounts of source code from many different projects.  Putting all this source code in one tree is not an option, because then we would be defeating the very reasons open source is attractive in the first place: flexibility, largly decoupled projects, advanced technology, fast bug fixes, many options to choose from, developer support, etc. Each open source project must remain a self contained project that is largly decoupled from other projects so it can develop at its own pace.  It is for these reasons that open source technologies are used to give products a competitive edge.  So, like any complex process or task, there must be some understanding of how it works, an appreciation for what it can do for you, and an investment in tools and techniques required to be effective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;update 2023-09-23&lt;&#x2F;strong&gt;: &lt;code&gt;recipetool&lt;&#x2F;code&gt; and &lt;code&gt;devtool&lt;&#x2F;code&gt; are updated tools that can be used to make and capture changes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux versus Windows CE</title>
        <published>2009-06-20T00:00:00+00:00</published>
        <updated>2009-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/462/embedded-linux-versus-windows-ce/"/>
        <id>https://bec-systems.com/462/embedded-linux-versus-windows-ce/</id>
        
        <content type="html" xml:base="https://bec-systems.com/462/embedded-linux-versus-windows-ce/">&lt;p&gt;Occasionally I am asked how Embedded Linux compares with Windows CE.  I have spent the past 5 years doing mostly embedded Linux development, and the previous 5 years doing mostly WinCE development with a few exceptions, so my thoughts are no doubt a little biased toward what I understand best.  So take this with a grain of salt :-)  In my experience, the choice is often made largely on perception and culture, rather than concrete data.  And, making a choice based on concrete data is difficult when you consider the complexity of a modern OS, all the issues associated with porting it to custom hardware, and unknown future requirements.  Even from an application perspective, things change over the life of a project.  Requirements come and go.  You find yourself doing things you never thought you would, especially if they are possible.  The ubiquitous USB and network ports open a lot of possibilities – for example adding &lt;a href=&quot;&#x2F;tags&#x2F;cellular&#x2F;&quot;&gt;Cell modem support&lt;&#x2F;a&gt; or &lt;a href=&quot;&#x2F;218&#x2F;printing-from-embedded-systems&#x2F;&quot;&gt;printer support&lt;&#x2F;a&gt;. Flash based storage makes &lt;a href=&quot;&#x2F;146&#x2F;do-you-need-software-update&#x2F;&quot;&gt;in-field software updates&lt;&#x2F;a&gt; the standard mode of operation.  And in the end, each solution has its strengths and weaknesses – there is no magic bullet that is the best in all cases.&lt;&#x2F;p&gt;
&lt;p&gt;When considering Embedded Linux development, I often use the iceberg analogy; what you see going into a project is the part above the water.  These are the pieces your application interacts with, drivers you need to customize, the part you understand.  The other 90% is under water, and herein lies a great deal of variability.  Quality issues with drivers or not being able to find a driver for something you may want to support in the future can easily swamp known parts of the project.  There are very few people who have a lot of experience with both WinCE and Linux solutions, hence the tendency to go with what is comfortable (or what managers are comfortable with), or what we have experience with.  Below are thoughts on a number of aspects to consider:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;system-software-development&quot;&gt;SYSTEM SOFTWARE DEVELOPMENT&lt;&#x2F;h2&gt;
&lt;p&gt;Questions in this realm include CPU support, driver quality, in field software updates, filesystem support, driver availability, etc.  One of the changes that has happened in the past two years, is CPU vendors are now porting Linux to their new chips as the first OS.  Before, the OS porting was typically done by Linux software companies such as MontaVista, or community efforts.  As a result, the Linux kernel now supports most mainstream embedded cpus with few additional patches.  This is radically different than the situation 5 years ago.  Because many people are using the same source code, issues get fixed, and often are contributed back to the mainstream source.  With WinCE, the BSP&#x2F;driver support tends to be more of a reference implementation, and then OEM&#x2F;users take it, fix any issues, and that is where the fixes tend to stay.&lt;&#x2F;p&gt;
&lt;p&gt;From a system perspective, it is very important to consider flexibility for future needs.  Just because it is not a requirement now does not mean it will not be a requirement in the future.  Obtaining driver support for a peripheral may be nearly impossible, or be too large an effort to make it practical.&lt;&#x2F;p&gt;
&lt;p&gt;Most people give very little thought to the build system, or never look much beyond the thought that “if there is a nice gui wrapped around the tool, it must be easy”.  OpenEmbedded is very popular way to build embedded Linux products, and has recently been endorsed as the technology base of MontaVista’s Linux 6 product, and is generally considered “hard to use” by new users.  While WinCE build tools look simpler on the surface (the 10% above water), you still have the problem of what happens when I need to customize something, implement complex features such as software updates, etc.  To build a production system with production grade features, you still need someone on your team who understands the OS and can work at the detail level of both the operating system, and the build system.  With either WinCE or Embedded Linux, this generally means companies either need to have experienced developers in house, or hire experts to do portions of the system software development.  System software development is not the same as application development, and is generally not something you want to take on with no experience unless you have a lot of time.  It is quite common for companies to hire expert help for the first couple projects, and then do follow-on projects in-house.  Another feature to consider is parallel build support.  With quad core workstations becoming the standard, is it a big deal that a full build can be done in 1.2 hours versus 8?  How flexible is the build system at pulling and building source code from various sources such as diverse revision control systems, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded processors are becoming increasingly complex.  It is no longer good enough to just have the cpu running.  If you consider the OMAP3 cpu family from TI, then you have to ask the following questions: are there libraries available for the 3D acceleration engine, and can I even get them without committing to millions of units per year?  Is there support for the DSP bridge?  What is the cost of all this?  On a recent project I was involved in, a basic WinCE BSP for the Atmel AT91SAM9260 cost $7000.  In terms of developer time, this is not much, but you have to also consider the on-going costs of maintenance, upgrading to new versions of the operating system, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;application-development&quot;&gt;APPLICATION DEVELOPMENT&lt;&#x2F;h2&gt;
&lt;p&gt;Both Embedded Linux and WinCE support a range of application libraries and programming languages.  C and C++ are well supported.  Most business type applications are moving to C# in the WinCE world.  Linux has Mono, which provides extensive support for .NET technologies and runs very well in embedded Linux systems.  There are numerous Java development environments available for Embedded Linux.  One area where you do run into differences is graphics libraries.  Generally the Microsoft graphical APIs are not well supported on Linux, so if you have a large application team that are die-hard windows GUI programmers, then perhaps WinCE makes sense.  However, there are many options for GUI toolkits that run on both Windows PCs and Embedded Linux devices.  Some examples include GTK+, Qt, wxWidgets, etc.  The Gimp is an example of a GTK+ application that runs on windows, plus there are many others.  The are C# bindings to GTK+ and Qt.  Another feature that seems to be coming on strong in the WinCE space is the Windows Communication Foundation (WCF).  But again, there are projects to bring WCF to Mono, depending what portions you need.  Embedded Linux support for scripting languages like Python is very good, and Python runs very well on 200MHz ARM processors.&lt;&#x2F;p&gt;
&lt;p&gt;There is often the perception that WinCE is realtime, and Linux is not.  Linux realtime support is decent in the stock kernels with the CONFIG_PREEMPT option, and real-time support is excellent with the addition of a relatively small &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;rt.wiki.kernel.org&#x2F;index.php&#x2F;Main_Page&quot;&gt;real-time patch&lt;&#x2F;a&gt;.  You can easily attain sub millisecond timing with Linux.  This is something that has changed in the past couple years with the merging of real-time functionality into the stock kernel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;development-flow&quot;&gt;DEVELOPMENT FLOW&lt;&#x2F;h2&gt;
&lt;p&gt;In a productive environment, most advanced embedded applications are developed and debugged on a PC, not the target hardware.  Even in setups where remote debugging on a target system works well, debugging an application on a workstation works better.  So the fact that one solution has nice on-target debugging, where the other does not is not really relevant.  For data centric systems, it is common to have simulation modes where the application can be tested without connection to real I&#x2F;O.  With both Linux and WinCE applications, application programing for an embedded device is similar to programming for a PC.  Embedded Linux takes this a step further.  Because embedded Linux technology is the same as desktop, and server Linux technology, almost everything developed for desktop&#x2F;server (including system software) is available for embedded for free.  This means very complete driver support (see USB cell modem and printer examples above), robust file system support, memory management, etc.  The breadth of options for Linux is astounding, but some may consider this a negative point, and would prefer a more integrated solution like Windows CE where everything comes from one place.  There is a loss of flexibility, but in some cases, the tradeoff might be worth it.  For an example of the number of packages that can be build for Embedded Linux systems using Openembedded, see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.org&#x2F;cgit.cgi&#x2F;openembedded&#x2F;tree&#x2F;recipes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gui-trends&quot;&gt;GUI TRENDS&lt;&#x2F;h2&gt;
&lt;p&gt;It is important to consider trends for embedded devices with small displays being driven by Cell Phones (iPhone, Palm Pre, etc).  Standard GUI widgets that are common in desktop systems (dialog boxes, check boxes, pull down lists, etc) do not cut it for modern embedded systems.  So, it will be important to consider support for 3D effects, and widget libraries designed to be used by touch screen devices.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clutter-project.org&#x2F;&quot;&gt;Clutter library&lt;&#x2F;a&gt; is an example of this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remote-support&quot;&gt;REMOTE SUPPORT&lt;&#x2F;h2&gt;
&lt;p&gt;Going back to the issue of debugging tools, most people stop at the scenario where the device is setting next to a workstation in the lab.  But what about when you need to troubleshoot a device that is being beta-tested half-way around the world?  That is where a command-line debugger like Gdb is an advantage, and not a disadvantage.  And how do you connect to the device if you don’t have support for cell modems in New Zealand, or an efficient connection mechanism like ssh for shell access and transferring files?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;SUMMARY&lt;&#x2F;h2&gt;
&lt;p&gt;Selecting any advanced technology is not a simple task, and is fairly difficult to do even with experience.  So it is important to be asking the right questions, and looking at the decision from many angles.  Hopefully this article can help in that.  For additional assistance, please do not hesitate to &lt;a href=&quot;&#x2F;#work-together&quot;&gt;contact BEC Systems&lt;&#x2F;a&gt; – we’re here to help.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dealing with large data structures efficiently in embedded systems</title>
        <published>2009-05-26T00:00:00+00:00</published>
        <updated>2009-05-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/"/>
        <id>https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/438/dealing-with-large-data-structures-efficiently-in-embedded-systems/">&lt;p&gt;I’m currently dealing with a programming problem where I need access to several 64MB, file-backed data structures concurrently on an Embedded Linux system that only has 64MB of RAM.  The data structures are fairly sparse (mostly zero data), and I typically only need to access small portions of them at any particular time.  There is always the brute-force approach where you write code to manually load sections of the file as you need them.  But with a little thought, the realisation hits “this is what operating systems do.”  This article explores using memory mapping, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sparse_file&quot;&gt;sparse file&lt;&#x2F;a&gt; support in file systems to solve this problem in a very efficient manner.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sparse-file-support&quot;&gt;Sparse File Support&lt;&#x2F;h2&gt;
&lt;p&gt;Most Unix file systems support &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sparse_file&quot;&gt;sparse files&lt;&#x2F;a&gt;.  This means that sections of data that is zeros is not stored on the disk.  Consider the following example where we create a 200MB file that is all zeros:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# df
Filesystem           1k-blocks      Used Available Use% Mounted on
&#x2F;dev&#x2F;mmcblk0p1         3917212    202448   3515776   5% &#x2F;media&#x2F;mmcblk0p1

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# dd if=&#x2F;dev&#x2F;zero of=sparse-file bs=1 \
count=1 seek=200M

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# df
Filesystem           1k-blocks      Used Available Use% Mounted on
&#x2F;dev&#x2F;mmcblk0p1         3917212    202456   3515768   5% &#x2F;media&#x2F;mmcblk0p1

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# ls -l
-rw-r--r--    1 root     root    209715201 May 22 08:54 sparse-file

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time od sparse-file
0000000  000000 000000 000000 000000 000000 000000 000000 000000
*
1440000000
real    0m 17.23s
user    0m 14.21s
sys     0m 2.66s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# du sparse-file
68      sparse-file
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It this case we created a 200MiB file on a SD card formatted as ext3.  Even though the file is 200M in size, it only uses a few KiB of disk space.  This same test also worked fine with a JFFS2 filesystem.  With sparse file support, we get a cheap form of run length compression (at least for zeros) with no effort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mmap&quot;&gt;mmap()&lt;&#x2F;h2&gt;
&lt;p&gt;The mmap() system call is used to map a file, or portions of a file into memory.  The data in the file can then be accessed directly in memory.  Because Linux is a demand paged system, portions of the file are paged in as needed, so the entire file does not need to be present in RAM at one time.  There are several advantages to using mmap():&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;mmap() avoids the extraneous copy that occurs when using read() or write() as the data does not need to be copied to a user space buffer.&lt;&#x2F;li&gt;
&lt;li&gt;there is very little overhead&lt;&#x2F;li&gt;
&lt;li&gt;you can directly access any part of the file without doing a lseek() and keeping track of where you are.&lt;&#x2F;li&gt;
&lt;li&gt;the operating system takes care of paging in sections of the file you are using, and discarding sections that are not in use when memory is low.  This includes flushing dirty portions to disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;What this means, is mmap gives you an easy way to work on large, file backed data structures, and the OS takes care of loading the portions you need, and saving the modified portions back to disk.  As most embedded systems are 32-bit, there is a limit to the file size you can use as virtual memory space is limited.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-application&quot;&gt;Test Application&lt;&#x2F;h2&gt;
&lt;p&gt;Next I wrote a small application that is used to create, and modify files using mmap().  I wanted to experiment with creating files of various sizes, writing non-zero data at various intervals, and test the performance of this.  The test application source is located &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;sparse_file_mmap_test&#x2F;sparse_file_mmap_test.c&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Usage: sparse_file_mmap_test [OPTION]

-s, --filesize   File size to allocate
  -o, --offset     Will write a few bytes every offset bytes
  -m, --modify     Modify existing file
  -d, --data       Data to write to file at offset location (0-255)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The application creates a file of size &lt;em&gt;filesize&lt;&#x2F;em&gt;, and writes the value of &lt;em&gt;data&lt;&#x2F;em&gt; to the file every &lt;em&gt;offset&lt;&#x2F;em&gt; bytes.  There is also an option to modify existing files, so we can test the performance of opening a large file, making a small change, and then closing it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-results&quot;&gt;Test Results&lt;&#x2F;h2&gt;
&lt;p&gt;The results are pretty amazing, and the performance is beyond my expectations. This type of problem is where you learn to appreciate the performance of an advanced operating system, and file system.  There is a reason for the complexity!  There are 3 things I wanted to test: 1) does the sparse file support work as expected? 2) can mmap be used to easily modify large files? 3) can mmap be used to work on data structures that are larger than physical RAM?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-sparse-file-support&quot;&gt;1. Sparse File Support&lt;&#x2F;h2&gt;
&lt;p&gt;The basic tests above confirm that sparse file support works for an empty file, but what about a file that has some data every X bytes?  Below are the test results for creating a 10MB file, and writing data at various offset intervals.&lt;&#x2F;p&gt;
&lt;table border=&quot;0&quot; cellspacing=&quot;0&quot; frame=&quot;void&quot; rules=&quot;none&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width=&quot;93&quot; height=&quot;17&quot; align=&quot;left&quot;&gt;&lt;strong&gt;Offset (bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td width=&quot;94&quot; align=&quot;left&quot;&gt;&lt;strong&gt;File Size (KB)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;1024&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;2048&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;4096&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;9784&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;8192&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;4904&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;16384&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;2464&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;32768&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;1244&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;65536&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;632&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;1048576&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;60&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;2097152&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;40&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td height=&quot;17&quot; align=&quot;right&quot;&gt;4194304&lt;&#x2F;td&gt;
&lt;td align=&quot;right&quot;&gt;32&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;As soon as the offset was greater than the MMU page size (4KB), then the sparse file effect started to kick in and worked as expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-can-mmap-be-used-to-efficiently-modify-large-files&quot;&gt;2. Can mmap() be used to efficiently modify large files?&lt;&#x2F;h2&gt;
&lt;p&gt;The test here was to open a large file, make a small change in the middle, and then close it.  In this case a 100MB file was created with a data value of 1 written every 1MB, and then re-opened the same file and wrote a data value of 2 every 2MB.  The od utility was used to examine the file to verify the contents were correct.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time sparse_file_mmap_test_arm -s104857600 \
-o1048576 -d1
Sparse File mmap() test
Filesize = 104857600, offset = 1048576, data = 1
size = 102400 KB
size on disk (KB):
508     sparse-file
real    0m 1.10s
user    0m 0.00s
sys     0m 0.43s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time sparse_file_mmap_test_arm -s104857600 \
-o2097152 -d2 -m
Sparse File mmap() test
Filesize = 104857600, offset = 2097152, data = 2
size = 102400 KB
size on disk (KB):
508     sparse-file
real    0m 0.37s
user    0m 0.01s
sys     0m 0.05s

root@cm-x270:&#x2F;media&#x2F;mmcblk0p1# time od -x sparse-file
0000000     0002    0000    0000    0000    0000    0000    0000    0000
0000020     0000    0000    0000    0000    0000    0000    0000    0000
*
4000000     0001    0000    0000    0000    0000    0000    0000    0000
4000020     0000    0000    0000    0000    0000    0000    0000    0000

....
*
614000000     0001    0000    0000    0000    0000    0000    0000    0000
614000020     0000    0000    0000    0000    0000    0000    0000    0000
*
620000000
real    0m 12.93s
user    0m 7.33s
sys     0m 1.70s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creating and modifying large file-backed data structures is very fast and efficient, and takes on the order of 1 second for a 100MB file that contains data every 1MB.  Dumping the data with od took considerably longer (13 seconds) as 100MB of data needed to be processed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;possible-issues&quot;&gt;Possible Issues&lt;&#x2F;h2&gt;
&lt;p&gt;There are several things to watch out for when using sparse files and mmap()&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;With sparse files, there is the potential to run out of disk space as the files are using less space on disk than the file size.  It is a good idea to monitor disk space when working with sparse files, so you don’t use up all of the disk space.&lt;&#x2F;li&gt;
&lt;li&gt;mmap() requires virtual memory space for the size file it maps.  With embedded systems, this is less of an issue, because the physical RAM size tends to be much less than the 4GB virtual address space.  With a system that only has 64MB of RAM, mmap()’ing files in the 10’s of MB in size makes a lot of sense because it insures that you will not run the system out of memory, and yet there should be plenty of virtual address space to map in files of this size.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;mmap() and sparse file support provide a very convenient solution for dealing with large, file-backed data structures.  One example of this type of data structure is any type of large matrix such as maps used in mapping applications.  Writing a “from scratch” solution to solve this problem would be a fairly large and difficult task.  Processing large amounts of data efficiently is becoming more and more important in many embedded systems. This example provides another compelling reason why implementing modern, data-centric embedded systems using Linux makes a lot of sense.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MontaVista Linux 6 is based on OpenEmbedded Technologies</title>
        <published>2009-05-13T00:00:00+00:00</published>
        <updated>2009-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/"/>
        <id>https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/</id>
        
        <content type="html" xml:base="https://bec-systems.com/425/montavista-linux-6-is-based-on-openembedded-technologies/">&lt;p&gt;Very interesting news from MontaVista yesterday as they announced &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;product_detail_mvl6.phphttp:&#x2F;&#x2F;mvista.com&#x2F;product_detail_mvl6.php&quot;&gt;MontaVista Linux 6&lt;&#x2F;a&gt;.  It turns out they are using bitbake, which is the core of the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&quot;&gt;OpenEmbedded&lt;&#x2F;a&gt; build system.  Along with the adoption of OpenEmbedded in many leading Embedded Linux efforts (Beagleboard, Gumstix, Bug Labs, etc), this is a resounding affirmation that the OpenEmbedded way of building distributions is worthy of consideration.  It is a well known fact that OpenEmbedded has some deficiencies: a steep learning curve, the testing&#x2F;quality efforts could be improved, and the organisational aspects of the project are somewhat lacking.  That said, OpenEmbedded is still the most effective tool for building Embedded Linux distributions that I’ve found yet, and is a very viable solution if you are willing to spend some time to learn it, or hire a consultant to get your project set up and work through the rough spots.  MontaVista is attempting to address these difficulties with their MVL6 commercial offering.&lt;&#x2F;p&gt;
&lt;p&gt;Below are few a notes from watching a few videos on the MV web site:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mvista.com&#x2F;download&#x2F;playvideo.php?v=Discussion_with_Jim_Ready&quot;&gt;Discussion with Jim Ready&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;around 2006 things changed&lt;&#x2F;li&gt;
&lt;li&gt;Semiconductor vendors now porting Linux to all their CPUs, so MV has moved up the stack&lt;&#x2F;li&gt;
&lt;li&gt;MVL6 first embedded linux distro produced in post-victory phase (Linux has won)&lt;&#x2F;li&gt;
&lt;li&gt;very friendly with other open source pieces (I assume OpenEmbedded)&lt;&#x2F;li&gt;
&lt;li&gt;enable open source&lt;&#x2F;li&gt;
&lt;li&gt;The decision the use Linux is the right decision technically.  What is the right business decision to accompany the technical decision?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;download&#x2F;playvideo.php?v=MVL6_Demonstration&quot;&gt;MVL6 Demonstration&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;toolchains pre-packaged&lt;&#x2F;li&gt;
&lt;li&gt;sources are all downloaded from MV servers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mvista.com&#x2F;download&#x2F;playvideo.php?v=Interview_with_Joe_Green&quot;&gt;Interview with Joe Green&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;manager of developer tools team&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MLV6 is new approach&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;previous editions were consistent for all targets&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MLV6 more flexible model.  Market specific distros depending on market.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;source driven product.  Previous products based on binary RPMs.  MLV6 is a lot easier to build the whole environment.  Very customized&#x2F;fine-tuned distro.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;key problems MLV6 solves&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Complete starting point for target hardware&lt;&#x2F;li&gt;
&lt;li&gt;complete build system, so you have total control vs pre-canned distribution that sets all the rules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Integration platform based on Bitbake.  Working closely with community.  Enhanced in a number of ways.  Customers have the option of bringing in software developed by the OpenEmbedded community and bringing it into their project.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Gives you a system that you can configure at almost any level.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Enhancements to make it easy to make changes, as well as provide a pre-built starting point.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Features to control sources, and environment so the host environment does not contaminate your build.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Essentially hardening, and commercializing the bitbake and openembedded projects.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Why MVL6 vs roll-your-own.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Qualified starting point&lt;&#x2F;li&gt;
&lt;li&gt;Support.  Community or Semi-conductor vendor support is hit or miss.&lt;&#x2F;li&gt;
&lt;li&gt;Consistent environment accross multiple systems.&lt;&#x2F;li&gt;
&lt;li&gt;Includes devrocket graphical tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Overall, this seems like a very good approach.  I’m glad they are not re-inventing the wheel, but instead have chosen to build on top of a proven open source solution, and leverage the work that is being done by a very active community of OpenEmbedded developers.  The OpenEmbedded project currently has 61 developers (not all are active), and weekly contribution rate is very good.  This type of effort would be very difficult to match by any but the largest commercial organizations.  This should be a win-win situation for all involved.  As a common base technology, the Bitbake and OpenEmbedded projects should improve due to MV’s involvement.  Through the MVL6 product, the OpenEmbedded project and way of doing things will get a lot more exposure and there will be a lot more developers who understand how it works.  Developers who are familiar with the OpenEmbedded build system will be able to apply their knowlege to a greater number of projects.   And developers building products will have more options for getting the support and techology they need.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to set up a NFS root filesystem for embedded Linux development</title>
        <published>2009-05-11T00:00:00+00:00</published>
        <updated>2009-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/"/>
        <id>https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/</id>
        
        <content type="html" xml:base="https://bec-systems.com/418/how-to-set-up-a-nfs-rootfs/">&lt;p&gt;Although ssh and friends work really well for embedded systems, occasionally you want to set up a NFS root for development.  One of the scenarios where nfsroot is useful is if you are making a lot of rootfs changes, and you don’t want to spend the time to reprogram the flash on the target system.  Fortunately, the Linux kernel includes complete support for NFS root, and does not require any userspace changes.  This setup assumes the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;the target system has Ethernet support built into the kernel&lt;&#x2F;li&gt;
&lt;li&gt;the target system is on the same network as a Linux workstation&lt;&#x2F;li&gt;
&lt;li&gt;said network includes a DHCP server&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This configuration emphasises “simple” and does not require you to spend 4 hours trying to get a bootp server configured on a test network.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kernel-support&quot;&gt;Kernel Support&lt;&#x2F;h2&gt;
&lt;p&gt;Make sure you have the following options turned on in the kernel:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_IP_PNP_DHCP=y&lt;&#x2F;li&gt;
&lt;li&gt;CONFIG_ROOT_NFS=y&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Then, add the following to your kernel CMDLINE:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;ip=dhcp root=&#x2F;dev&#x2F;nfs nfsroot=&amp;lt;nfs server IP&amp;gt;:&#x2F;path&#x2F;to&#x2F;nfsroot
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;workstation-setup&quot;&gt;Workstation Setup&lt;&#x2F;h2&gt;
&lt;p&gt;The following setup is for Ubuntu.&lt;&#x2F;p&gt;
&lt;p&gt;apt-get install nfs-user-server&lt;&#x2F;p&gt;
&lt;p&gt;(edit &#x2F;etc&#x2F;exports to contain something like the following)&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;path&#x2F;to&#x2F;nfsroot 192.168.1.0&#x2F;255.255.255.0(no_root_squash,sync,rw)&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;init.d&#x2F;nfs-user-server restart&lt;&#x2F;p&gt;
&lt;p&gt;If you are using OpenEmbedded, then instruct OE to generate a rootfs tar image, and extract to your nfsroot directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cd &#x2F;path&#x2F;to&#x2F;nfsroot
sudo tar -xvf &amp;lt;path to OE images dir&amp;gt;&#x2F;Angstrom-image...rootfs.tar
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;and-the-result&quot;&gt;And the result&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
Sending DHCP requests ., OK
IP-Config: Got DHCP answer from 192.168.1.1, my address is 192.168.1.112
IP-Config: Complete:
     device=eth0, addr=192.168.1.112, mask=255.255.255.0, gw=192.168.1.1,
     host=192.168.1.112, domain=hq.bec-systems.com, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.11, rootpath=
Looking up port of RPC 100003&#x2F;2 on 192.168.1.11
Looking up port of RPC 100005&#x2F;1 on 192.168.1.11
VFS: Mounted root (nfs filesystem) readonly.
Freeing unused kernel memory: 220k freed
Write protecting the kernel text: 2792k
Write protecting the kernel read-only data: 788k
INIT: version 2.86 booting
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 kernel updated to 2.6.29 in OE</title>
        <published>2009-04-24T00:00:00+00:00</published>
        <updated>2009-04-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/"/>
        <id>https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/</id>
        
        <content type="html" xml:base="https://bec-systems.com/413/compulab-cm-x270-kernel-updated-to-2629-in-oe/">&lt;p&gt;The cm-x270 kernel support in OpenEmbedded has just been &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;commit&#x2F;&amp;amp;id=23ac197703f9cc49e7a69ea34e24e4c885e485a1&quot;&gt;updated&lt;&#x2F;a&gt; to version 2.6.29.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wi2Wi W2CBW003 Wifi&#x2F;Bluetooth module review</title>
        <published>2009-03-19T00:00:00+00:00</published>
        <updated>2009-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/387/wi2wi-wifi-bt-module-review/"/>
        <id>https://bec-systems.com/387/wi2wi-wifi-bt-module-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/387/wi2wi-wifi-bt-module-review/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.wi2wi.com&#x2F;wireless.php&quot;&gt;Wi2Wi W2CBW003&lt;&#x2F;a&gt; is a highly integrated module that provides both Wifi and Bluetooth radios for embedded designs.  This module is ideal for embedded designs, as it provides a lot of functionality in a small package and includes standard interfaces like SPI, SDIO and serial that connect with most embedded CPUs.  With the availability of modules like the W2CBW003 and standard drivers in the Linux kernel, including radio functionality in an embedded device is very doable, even for low volume products.  Wi2Wi provides an evaluation board for the W2CBW003 with a SDIO connector, UART connector, and BT Audio Connectors.  For this review, the eval board was connected to a Marvel PXA270 ARM processor, and evaluated with current Linux and associated software.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;w2cbw003-overview&quot;&gt;W2CBW003 Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The W2CBW003 module integrates both WiFi and Bluetooth functionality in a 12mm x 12mm x 1.6mm package.   The WiFi portion is based on the Marvell 88W8686, and the Bluetooth on the CSR BC04.  Both of these components are well supported by Open Source software.  Some other features include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Separate Antennas for WiFi and BT.&lt;&#x2F;li&gt;
&lt;li&gt;ROHS compliant&lt;&#x2F;li&gt;
&lt;li&gt;Single Supply at 3.3V&lt;&#x2F;li&gt;
&lt;li&gt;802.11g support (54Mbps)&lt;&#x2F;li&gt;
&lt;li&gt;Both SPI and SDIO interfaces for WiFi&lt;&#x2F;li&gt;
&lt;li&gt;UART interface for BT&lt;&#x2F;li&gt;
&lt;li&gt;PCM audio interface for BT&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Pictures of the module and the demo board are shown below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;03&#x2F;img_1798_small-1.jpg&quot; alt=&quot;img_1798_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;03&#x2F;img_1800_small-1.jpg&quot; alt=&quot;img_1800_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;evaluation-system-configuration&quot;&gt;Evaluation System Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;The test software included with the Wi2Wi eval board is for a Windows PC, is provided in binary format only, and was not used in this review.  For this review, I plugged the W2CBW003 demo board into a Compulab cm-x270 board (PXA270 cpu) running a 2.6.29-rc7 Linux kernel and a recent OpenEmbedded Angstrom distribution.   With the exception of the Marvell Wifi Firmware, all software in this setup is Open Source and is available in the Linux kernel, and as packages in the OpenEmbedded Project.&lt;&#x2F;p&gt;
&lt;p&gt;When booting the kernel, you will see the following messages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mmc0: new SDIO card at address 0001
libertas_sdio mmc0:0001:1: firmware: requesting sd8686_helper.bin
libertas_sdio mmc0:0001:1: firmware: requesting sd8686.bin
libertas: 00:19:88:06:0b:2e, fw 9.70.3p25, cap 0x00000303
eth2 (libertas_sdio): not using net_device_ops yet
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: PREP_CMD: command 0x00a3 failed: 2
libertas: eth2: Marvell WLAN 802.11 adapter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The “command 0x00a3 failed” messages are harmless, and have to do with features that are not supported.  After the system boots, you will now see a new ethX network device:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifconfig -a
...
eth2      Link encap:Ethernet  HWaddr 00:19:88:06:0B:2E
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:65902 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1758 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:13550002 (12.9 MiB)  TX bytes:251627 (245.7 KiB)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The “&lt;em&gt;iwlist eth2 scanning&lt;&#x2F;em&gt;” command will list available access points.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connecting-to-open-wifi-networks&quot;&gt;Connecting to Open WiFi Networks&lt;&#x2F;h2&gt;
&lt;p&gt;A connection to an open wifi network can be accomplished by placing the following in &#x2F;etc&#x2F;network&#x2F;interfaces:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;network&#x2F;interfaces:
iface eth1 inet dhcp
    wireless_mode managed
    wireless_essid any
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now execute “ifup eth2”:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifup eth2
udhcpc (v1.13.2) started
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
Sending discover...
Sending select for 192.168.1.115...
Lease of 192.168.1.115 obtained, lease time 86400
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
adding dns 208.67.222.222
adding dns 208.67.220.220

root@cm-x270:~# iwlist eth2
iwlist: unknown command `eth2&amp;#39; (check &amp;#39;iwlist --help&amp;#39;).
root@cm-x270:~# iwconfig eth2
eth2      IEEE 802.11b&#x2F;g  ESSID:&amp;quot;bec3&amp;quot;
          Mode:Managed  Frequency:2.437 GHz  Access Point: 00:18:39:C1:AD:4A
          Bit Rate:1 Mb&#x2F;s   Tx-Power=13 dBm
          Retry short limit:8   RTS thr=2347 B   Fragment thr=2346 B
          Encryption key:off
          Power Management:off
          Link Quality=84&#x2F;100  Signal level=-37 dBm  Noise level=-87 dBm
          Rx invalid nwid:0  Rx invalid crypt:14707457  Rx invalid frag:0
          Tx excessive retries:58  Invalid misc:3   Missed beacon:0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;wpa-secured-wifi-networks&quot;&gt;WPA Secured WiFi Networks&lt;&#x2F;h2&gt;
&lt;p&gt;The OpenEmbedded console image includes the WPA Supplicant packages which is used to manage wireless connections to secured networks.  To set up the system for WPA encryption, modify the following files:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;network&#x2F;interfaces:
iface eth2 inet dhcp
   wpa-conf &#x2F;etc&#x2F;wpa_supplicant&#x2F;wpa_supplicant.conf
   wpa-driver wext
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;etc&#x2F;wpa_supplicant&#x2F;wpa_supplicant.conf:
ctrl_interface=&#x2F;var&#x2F;run&#x2F;wpa_supplicant
ctrl_interface_group=0
eapol_version=1
ap_scan=1
fast_reauth=1

network={
      ssid=&amp;quot;bec&amp;quot;
      proto=WPA2
      key_mgmt=WPA-PSK
      pairwise=CCMP TKIP
      group=CCMP TKIP
      scan_ssid=1
      psk=&amp;quot;ascii passphrase&amp;quot;
      priority=10
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, execute “ifup eth2”, and you should see something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# ifup eth2
WPA: Configuring Interface
udhcpc (v1.13.2) started
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
Sending discover...
Sending select for 192.168.1.115...
Lease of 192.168.1.115 obtained, lease time 86400
run-parts: &#x2F;etc&#x2F;udhcpc.d&#x2F;00avahi-autoipd exited with code 1
adding dns 208.67.222.222
adding dns 208.67.220.220
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~# iwconfig eth2
eth2      IEEE 802.11b&#x2F;g  ESSID:&amp;quot;bec&amp;quot;
          Mode:Managed  Frequency:2.412 GHz  Access Point: 00:40:10:10:00:03
          Bit Rate:1 Mb&#x2F;s   Tx-Power=13 dBm
          Retry short limit:8   RTS thr=2347 B   Fragment thr=2346 B
          Encryption key:&amp;lt;too big&amp;gt;   Security mode:open
          Power Management:off
          Link Quality=64&#x2F;100  Signal level=-68 dBm  Noise level=-89 dBm
          Rx invalid nwid:0  Rx invalid crypt:-1463809279  Rx invalid frag:0
          Tx excessive retries:22524  Invalid misc:3   Missed beacon:0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;other-observations&quot;&gt;Other Observations&lt;&#x2F;h2&gt;
&lt;p&gt;With the above networks, the &lt;em&gt;bec&lt;&#x2F;em&gt; access point was much further away than the &lt;em&gt;bec3&lt;&#x2F;em&gt;AP, so you will notice the difference in link quality.  “&lt;em&gt;iwlist eth2 rate&lt;&#x2F;em&gt;” can be used to list the current connection rate.  When the network is idle, it sits at 1Mb&#x2F;s.  When downloading a large file, it will climb to 36 or 54Mb&#x2F;s, depending on link quality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;production-issues&quot;&gt;Production Issues&lt;&#x2F;h2&gt;
&lt;p&gt;The review demonstrates that it is fairly simple to set up a demo quality Embedded Linux system with WiFi.  Some of the issues that would likely need addressed for a production system include link management, test software for certification, and power management.&lt;&#x2F;p&gt;
&lt;p&gt;There are several ways to programatically control WPA Supplicant including linking to the wpa supplicant control interface, or using DBus.  There are several WiFi management applications available including &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;projects.gnome.org&#x2F;NetworkManager&#x2F;&quot;&gt;Gnome NetworkManager&lt;&#x2F;a&gt; (used in desktop systems), and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;v1.moblin.org&#x2F;projects&#x2F;projects_connman.php&quot;&gt;connman&lt;&#x2F;a&gt; which seems a little better suited for embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Unless you use a completely pre-certified module + antenna solution, you will likely need to do some level of agency certification.  As many products use a custom antenna, this is an important issue to consider and plan for.  While Marvell provides test software and firmware, it will likely require some work, as their software is designed to be used with their in-house drivers rather than the libertas driver which is available  with modern kernels.&lt;&#x2F;p&gt;
&lt;p&gt;Also, if you want to minimize the power usage, some work will be required to figure out the power modes supported, and how to implement&#x2F;control them.  With this module, the Wifi and BT portions run off the same crystal, so if you only want the BT active, you will need to actively power manage the Wifi portion to a low power state instead of completely disabling it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;TheW2CBW003 module is an attractive solution for products that need WiFi functionality.  With the availability of modules like this, and mainstream open source software, the technology is available to about anyone, including low volume manufacturers.  Standard interfaces such as SDIO make it possible to interface this module with about any modern ARM processor that can run Linux.  Software support in the Linux kernel, wpa supplicant, and the Linux wireless tools provide the needed software support to implement a very complex system with relatively little effort.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Memory Performance on various Embedded Systems</title>
        <published>2009-03-04T00:00:00+00:00</published>
        <updated>2009-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/380/memory-performance-on-various-embedded-systems/"/>
        <id>https://bec-systems.com/380/memory-performance-on-various-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/380/memory-performance-on-various-embedded-systems/">&lt;p&gt;Marcin just published an interesting &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;marcin.juszkiewicz.com.pl&#x2F;2009&#x2F;02&#x2F;20&#x2F;does-vortex86sx-based-devices-are-worth-something&#x2F;&quot;&gt;article&lt;&#x2F;a&gt; about memory performance on various embedded systems using the hdparm -T as a simple benchmarq.  This test gives a pretty good indicator of memory performance in the system.  From the hdparm man page:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Perform timings of cache reads for benchmark and comparison purposes.  For meaningful results, this operation should be repeated 2-3  times on an otherwise inactive system (no other active processes) with at least a couple of megabytes of free memory.  This displays the speed of reading directly from the Linux buffer cache without disk access.  This measurement is essentially an indication of the throughput  of  the processor, cache, and memory of the system under test.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A few results I find interesting:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;modern desktop systems have an order of magnitude more memory bandwidth than ARM systems.&lt;&#x2F;li&gt;
&lt;li&gt;the i.MX31 is the highest performing ARM device tested&lt;&#x2F;li&gt;
&lt;li&gt;the i.MX31 performs better than the OMAP3 in this test – why is this?  As the ratio is 2, I’m guessing the bus is twice as wide?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Who is using OpenEmbedded?</title>
        <published>2009-02-20T00:00:00+00:00</published>
        <updated>2009-02-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/372/who-is-using-openembedded/"/>
        <id>https://bec-systems.com/372/who-is-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/372/who-is-using-openembedded/">&lt;p&gt;Having used OpenEmbedded for a number of Embedded Linux projects over the past 5 years, it is interesting watching new users come on board.  The most recent &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;thread.gmane.org&#x2F;gmane.comp.handhelds.openembedded&#x2F;21188&quot;&gt;announcement came from Koan&lt;&#x2F;a&gt; that the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.kaeilos.com&#x2F;&quot;&gt;KaeilOS&lt;&#x2F;a&gt; distribution will be joining the OpenEmbedded project.  In the announcement, they summed up my thoughts well:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;We at KOAN wanted to avoid waste of energy converging KOAN efforts into a stable and solid Open Source project like OE is.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;“Avoid waste of energy” – isn’t this what OSS is all about?  Life is way too short to re-invent every wheel.  Considering OpenEmbedded has dozens of active contributors, it would be very difficult for any one company to replicate the functionality of OpenEmbedded. Although there are many ways to build embedded Linux distributions, and some tools do some things better than OE, there still does not seem to be any other embedded Linux build tool that fulfills the following requirements as well as OE:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;build from scratch on any x86 Linux system&lt;&#x2F;li&gt;
&lt;li&gt;large number of contributors&lt;&#x2F;li&gt;
&lt;li&gt;large number of packages&lt;&#x2F;li&gt;
&lt;li&gt;support a large number of architectures&lt;&#x2F;li&gt;
&lt;li&gt;Can modify images and integrate custom applications in a consistent way as part of the build system, and not a post processing hack.&lt;&#x2F;li&gt;
&lt;li&gt;Open Source&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some other companies using OpenEmbedded include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;TI&lt;&#x2F;li&gt;
&lt;li&gt;AMD&lt;&#x2F;li&gt;
&lt;li&gt;Intel (was OpenedHand)&lt;&#x2F;li&gt;
&lt;li&gt;Gumstix&lt;&#x2F;li&gt;
&lt;li&gt;Bug Labs&lt;&#x2F;li&gt;
&lt;li&gt;OpenMoko&lt;&#x2F;li&gt;
&lt;li&gt;Atmel&lt;&#x2F;li&gt;
&lt;li&gt;Techsol&lt;&#x2F;li&gt;
&lt;li&gt;Compulab&lt;&#x2F;li&gt;
&lt;li&gt;Toradex&lt;&#x2F;li&gt;
&lt;li&gt;4G-Systems&lt;&#x2F;li&gt;
&lt;li&gt;Dream Multimedia TV&lt;&#x2F;li&gt;
&lt;li&gt;M&amp;amp;N Solutions&lt;&#x2F;li&gt;
&lt;li&gt;emQbit&lt;&#x2F;li&gt;
&lt;li&gt;Siemens&lt;&#x2F;li&gt;
&lt;li&gt;Embedded Alley&lt;&#x2F;li&gt;
&lt;li&gt;and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;SuccessStories&quot;&gt;list goes on&lt;&#x2F;a&gt; …. (If you are using OpenEmbedded, please add your name to this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.openembedded.net&#x2F;index.php&#x2F;SuccessStories&quot;&gt;list&lt;&#x2F;a&gt;.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’m looking forward to seeing the KaeilOS improvements such as mdev, and boot time improvements.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sprint 598U USB Broadband Modem in Embedded Systems</title>
        <published>2009-02-07T00:00:00+00:00</published>
        <updated>2009-02-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/"/>
        <id>https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/353/sprint-598u-usb-broadband-modem-in-embedded-systems/">&lt;p&gt;One thing that works really well in Linux is support for USB Broadband modems.  While it usually takes a little fiddling with PPP scripts, it is generally not too difficult to get working.  One of the reasons for this is most modems implement a USB serial interface, and then the modem is controlled with standard AT commands.  A customer who currently supports a &lt;a href=&quot;&#x2F;203&#x2F;using-a-verizon-usb720-modem-in-an-embedded-linux-system&#x2F;&quot;&gt;Verizon USB modem&lt;&#x2F;a&gt; in their product wanted to add support for a Sprint modem.  After a little research, we settled on the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.sierrawireless.com&#x2F;product&#x2F;USB598.aspx&quot;&gt;598U from Sierra Wireless&lt;&#x2F;a&gt;.  Below is a picture of the 598U plugged into an industrial terminal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;02&#x2F;img_17721-1.jpg&quot; alt=&quot;sprint 598U modem&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-are-usb-broadband-modems-useful-in-embedded-systems&quot;&gt;Why are USB Broadband modems useful in Embedded Systems?&lt;&#x2F;h2&gt;
&lt;p&gt;As systems become more complex, and time to market is shrinking (thus less testing), it is becoming increasingly important to be able to remotely diagnose problems.  With a broadband modem like the Sprint 598U, developers can remotely log into a device using SSH, and debug problems.  This is a huge benefit.  The cost of the modem and a 1 year data plan becomes fairly insignificant when you consider the cost to fly a developer on-site to debug issues.  While there are other ways to remotely access an embedded system, such as &lt;a href=&quot;&#x2F;137&#x2F;remote-access-for-embedded-systems-behind-a-firewall&#x2F;&quot;&gt;reverse ssh&lt;&#x2F;a&gt;, the simplicity of the broadband modem is attractive as it bypasses the firewall issues.  Even with reverse ssh, I’ve run into paranoid sys admins who block the outgoing port 22 on their networks, which makes reverse ssh difficult.  Once you have the IP address of the broadband connection, you can connect to it directly with ssh from anywhere in the world.  I’ve accessed systems that were being field tested in New Zealand from the United States, and it worked great.&lt;&#x2F;p&gt;
&lt;p&gt;Increasingly, the value of complex embedded systems is shifting from control to data.  While the control aspect is as important as it ever was, access to data is what is giving many products and businesses the competitive edge.  Being able to collect data and visualize how the system is performing is becoming increasingly important to maximize performance.  And sometimes this data must be collected in real-time.  Scenarios where USB broadband modems might make sense:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;remote sites that do not have internet connectivity&lt;&#x2F;li&gt;
&lt;li&gt;mobile applications such as vehicle terminals&lt;&#x2F;li&gt;
&lt;li&gt;temporary installations where the system is only located in one place for a limited time&lt;&#x2F;li&gt;
&lt;li&gt;situations where it is very difficult to get administrators of the local network to cooperate in adding the embedded system to their network&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;finding-ppp-config-information&quot;&gt;Finding PPP Config information&lt;&#x2F;h2&gt;
&lt;p&gt;I usually develop as much as I can on x86 systems (vs. an embedded target) as it is a lot more convenient, so I plugged the modem into a Ubuntu 8.10 laptop.  While Ubuntu 8.10 recognizes and configures a UM150 Verizon modem, it does not automatically configure the 598U.  Typically, the next step is to google around for information on various support forums on how to set up the PPP config files, as most manufactures don’t provide support for Linux.  As I could not find any existing information for the 598U, I decided to see if Sierra Wireless published any information.  Was I ever suprised when I found &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sierrawireless.custhelp.com&#x2F;app&#x2F;answers&#x2F;detail&#x2F;a_id&#x2F;500#supported_devices&quot;&gt;this page&lt;&#x2F;a&gt;.  Sierra Wireless provides fairly comprehensive information on using the modem under Linux, and their PPP scripts actually worked – great job!  But in the end, when I plugged the 598U into the embedded device that already supported the Verizon modem, it just worked with my existing PPP scripts.  This is another indication of the value of using common code and interfaces in Linux.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-linux-advantage&quot;&gt;The Linux Advantage&lt;&#x2F;h2&gt;
&lt;p&gt;When you run Linux in an embedded system, using a USB broadband modem becomes fairly simple.  It is actually a little bit deceiving as to what all has to happen.  Different modems use different chipsets, and thus different drivers.  While they all eventually expose a USB serial interface, there are enough differences to require separate drivers.  As an example, the 598U uses the “sierra” USB-serial driver.  This driver is 782 lines, plus it utilizes a common USB serial framework that is many times this size.  On the application side, the pppd framework is used to manage the modem and the network connection.  Starting the connection is as simple as running “pppd call cdma” from your application.  The pppd application manages getting an IP address, setting up nameservers in &lt;em&gt;resolve.conf&lt;&#x2F;em&gt;, etc.  Because all broadband modems are supported by a common application interface and very similiar drivers, supporting multiple modem vendors is actually quite easy.  Contrast this to the Windows driver scenario where every vendor provides their “own” driver, and their “own” application user interface, and their “own” way to initiate an internet connection, and it is not obvious to me how you could easily control all this in a consistent, automated fashion in an embedded device.  The way we set it up is you plug the modem in, and a few seconds later the system is automatically connected to the internet.   There is nothing for the user to configure, initiate, etc.  &lt;a href=&quot;&#x2F;218&#x2F;printing-from-embedded-systems&#x2F;&quot;&gt;Printing from Linux in embedded applications&lt;&#x2F;a&gt; is similiar.&lt;&#x2F;p&gt;
&lt;p&gt;This is another example of how it is possible to leverage the work of many to add advanced functionality and features to a device with very little development cost.  Getting more done with less should be an attractive (and perhaps critical) way to operate for any company seeking to remain competitive.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Socketcan utils and test apps added to OpenEmbedded</title>
        <published>2009-01-28T00:00:00+00:00</published>
        <updated>2009-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/"/>
        <id>https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/346/socketcan-utils-and-test-apps-added-to-openembedded/">&lt;p&gt;The Socketcan test applications and utilities are &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;socketcan&#x2F;socketcan-utils-test_svn.bb&quot;&gt;now available in OpenEmbedded&lt;&#x2F;a&gt;.  The socketcan kernel modules &lt;a href=&quot;&#x2F;341&#x2F;socketcan-can-bus-drivers-added-to-openembedded&#x2F;&quot;&gt;already exist in OE&lt;&#x2F;a&gt;.  To build and deploy:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;get the latest version of OE metadata&lt;&#x2F;li&gt;
&lt;li&gt;bitbake socketcan-utils-test&lt;&#x2F;li&gt;
&lt;li&gt;scp &lt;oedir&gt;&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;&lt;machine&gt;&#x2F;socketcan-utils-test_0.0+svnr917-r0_armv5te.ipk root@&lt;target IP address&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And then on the target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg install socketcan-utils-test_0.0+svnr917-r0_armv5te.ipk&lt;&#x2F;li&gt;
&lt;li&gt;opkg files socketcan-utils-test&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;tst_bcm_rx_sendto
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_tx_sendto
&#x2F;usr&#x2F;bin&#x2F;canlogserver
&#x2F;usr&#x2F;bin&#x2F;tst_raw_filter
&#x2F;usr&#x2F;bin&#x2F;tst_raw
&#x2F;usr&#x2F;bin&#x2F;isotpsniffer
&#x2F;usr&#x2F;bin&#x2F;isotpsend
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_throttle
&#x2F;usr&#x2F;bin&#x2F;tst_packet
&#x2F;usr&#x2F;bin&#x2F;vcan
&#x2F;usr&#x2F;bin&#x2F;isotprecv
&#x2F;usr&#x2F;bin&#x2F;cansniffer
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_tx_read
&#x2F;usr&#x2F;bin&#x2F;tst_err
&#x2F;usr&#x2F;bin&#x2F;log2asc
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_single
&#x2F;usr&#x2F;bin&#x2F;tst_filter_master
&#x2F;usr&#x2F;bin&#x2F;canplayer
&#x2F;usr&#x2F;bin&#x2F;cangen
&#x2F;usr&#x2F;bin&#x2F;slcanpty
&#x2F;usr&#x2F;bin&#x2F;log2long
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_rtr
&#x2F;usr&#x2F;bin&#x2F;asc2log
&#x2F;usr&#x2F;bin&#x2F;slcan_attach
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_filter
&#x2F;usr&#x2F;bin&#x2F;cansend
&#x2F;usr&#x2F;bin&#x2F;canecho
&#x2F;usr&#x2F;bin&#x2F;tst_filter_server
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_cycle
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_dump
&#x2F;usr&#x2F;bin&#x2F;isotpdump
&#x2F;usr&#x2F;bin&#x2F;candump
&#x2F;usr&#x2F;bin&#x2F;tst_raw_sendto
&#x2F;usr&#x2F;bin&#x2F;isotptun
&#x2F;usr&#x2F;bin&#x2F;tst_bcm_server
&#x2F;usr&#x2F;bin&#x2F;tst_proc
&#x2F;usr&#x2F;bin&#x2F;canbusload
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An impressive array of utilities!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Socketcan CAN-bus drivers added to OpenEmbedded</title>
        <published>2009-01-26T00:00:00+00:00</published>
        <updated>2009-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/"/>
        <id>https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/341/socketcan-can-bus-drivers-added-to-openembedded/">&lt;p&gt;I just added a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;socketcan&#x2F;socketcan-modules_svn.bb&quot;&gt;recipe&lt;&#x2F;a&gt; to OpenEmbedded to build the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;developer.berlios.de&#x2F;projects&#x2F;socketcan&#x2F;&quot;&gt;Socketcan&lt;&#x2F;a&gt; kernel modules from the socketcan SVN.  So if you are using the latest OpenEmbedded metadata, you can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;bitbake socketcan-modules&lt;&#x2F;li&gt;
&lt;li&gt;scp &lt;oedir&gt;&#x2F;build&#x2F;angstrom-2008.1&#x2F;tmp&#x2F;deploy&#x2F;glibc&#x2F;ipk&#x2F;&lt;machine&gt;&#x2F;socketcan-modules_0.0+svnr917-r0_cm-x270.ipk  root@&lt;target IP address&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and then on the target system:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;opkg install socketcan-modules_0.0+svnr917-r0_cm-x270.ipk&lt;&#x2F;li&gt;
&lt;li&gt;opkg files socketcan-modules&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre&gt;&lt;code&gt;Package socketcan-modules (0.0+svnr917-r0) is installed on root and has the following files:
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-bcm.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;ems_pci.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-raw.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;sja1000.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;softing&#x2F;softing.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;ems_pcmcia.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;sja1000_platform.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;can-dev.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;softing&#x2F;softing_cs.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;sja1000&#x2F;pipcan.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;mcp251x.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;net&#x2F;can&#x2F;can-isotp.ko
&#x2F;lib&#x2F;modules&#x2F;2.6.27&#x2F;extra&#x2F;drivers&#x2F;net&#x2F;can&#x2F;vcan.ko
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then to use the modules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;depmod&lt;&#x2F;li&gt;
&lt;li&gt;modprobe mcp251x&lt;&#x2F;li&gt;
&lt;li&gt;modprobe can-bcm&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What is CAN?  Can stands for Controller-area network and is popular in industrial and automotive applications.  A convenient way to add CAN to your Embedded Linux system is with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.microchip.com&#x2F;wwwproducts&#x2F;Devices.aspx?dDocName=en010406&quot;&gt;Microchip MCP2515&lt;&#x2F;a&gt;.  This device connects to a SPI bus which means it can be interfaced with a number of popular SOC’s such as the PXA270, OMAP3, 91SAM9xxx, etc.&lt;&#x2F;p&gt;
&lt;p&gt;More on Socketcan later …&lt;&#x2F;p&gt;
&lt;p&gt;BTW, this recipe really illustrates how easy it is to compile kernel modules outside a kernel in OpenEmbedded:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;Socketcan kernel modules&amp;quot;
HOMEPAGE = &amp;quot;http:&#x2F;&#x2F;developer.berlios.de&#x2F;projects&#x2F;socketcan&#x2F;&amp;quot;
SECTION = &amp;quot;kernel&#x2F;modules&amp;quot;
LICENSE = &amp;quot;GPL&amp;quot;
DEPENDS = &amp;quot;virtual&#x2F;kernel&amp;quot;
PV = &amp;quot;0.0+svnr${SRCREV}&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;svn.berlios.de&#x2F;socketcan&#x2F;trunk;module=kernel;proto=svn&amp;quot;

S = &amp;quot;${WORKDIR}&#x2F;kernel&#x2F;2.6&amp;quot;

inherit module
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This recipe tells OE to download the source, cross-compile it against your target kernel build dir, and then package it for easy install on the device.  This is the way things should work – no messing around figuring out make options, kernel source paths, compiler env variables, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Intel Atom vs TI OMAP3</title>
        <published>2009-01-22T00:00:00+00:00</published>
        <updated>2009-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/326/intel-atom-vs-ti-omap3/"/>
        <id>https://bec-systems.com/326/intel-atom-vs-ti-omap3/</id>
        
        <content type="html" xml:base="https://bec-systems.com/326/intel-atom-vs-ti-omap3/">&lt;p&gt;As we look at new projects, both the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.intel.com&#x2F;technology&#x2F;atom&#x2F;index.htm&quot;&gt;Intel Atom&lt;&#x2F;a&gt; and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;focus.ti.com&#x2F;paramsearch&#x2F;docs&#x2F;parametricsearch.tsp?family=dsp&amp;amp;sectionId=2&amp;amp;tabId=2225&amp;amp;familyId=1526&amp;amp;paramCriteria=no&quot;&gt;TI OMAP3&lt;&#x2F;a&gt; processors generate considerable interest.  As &lt;a href=&quot;&#x2F;316&#x2F;gtk-performance-on-pxa270-vs-omap3&#x2F;&quot;&gt;we have already shown&lt;&#x2F;a&gt;, the OMAP3 does offer a considerable performance improvement over earlier generations of ARM CPUs.  The following &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=cnsaDc6criM&quot;&gt;video&lt;&#x2F;a&gt; I found on YouTube shows a similar comparison of a OMAP3 and Atom systems rendering web pages:&lt;&#x2F;p&gt;
&lt;p&gt;As one would expect, the Atom does perform better (about 14%), but considering the power differences, the OMAP does surprisingly well.  It is also unknown in this demo if the screen size would make a significant difference in the results.  Like most things, the choice depends on the application, and no two applications are the same, and each solution has advantages.  Some things to think about:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Power: OMAP3 platform consumes on the order of &amp;lt;1-2W while the Atom is more in the range of 2-5W.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;High Speed I&#x2F;O Interfaces: Atom supports PCI and PCI expansion interfaces where OMAP3 is limited to more special purpose user interfaces such as SD, Camera, Asynchronous bus, etc.  Both Atom and OMAP support High Speed USB.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Packaging: OMAP3 packaging is very aggressive with the stacked Package-on-Package.  To get an idea how much space an OMAP3 solution takes, check out the module from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;Gumstix&lt;&#x2F;a&gt;.  There are basically only two chips in the system: the OMAP3+stacked RAM&#x2F;Flash and a power management+I&#x2F;O chip.  This is very high integration!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Module availability: for many embedded systems with volumes in the 1000’s of units per year, a module solution is very attractive compared to a full custom design.  This drastically reduces the engineering effort and time to market.  A sampling of the modules available include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OMAP3:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;Gumstix Overo&lt;&#x2F;a&gt; ($117 for 3000 units)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.logicpd.com&#x2F;products&#x2F;som&#x2F;ti&#x2F;omap35x&quot;&gt;LogicPD OMAP35x SOM-LV&lt;&#x2F;a&gt; (Cost unknown)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Atom:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eurotech-inc.com&#x2F;single-board-computer-atom-com-catalyst-module.asp&quot;&gt;Eurotech Catalyst&lt;&#x2F;a&gt; (Cost unknown)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Software support:  TI and the open source community have done a remarkable job of supporting the OMAP3 with the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;beagleboard.org&#x2F;&quot;&gt;BeagleBoard&lt;&#x2F;a&gt; effort.  Gumstix maintains open source software for their devices, and has a very active development community.  Intel also has invested significantly in software with their &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;moblin.org&#x2F;&quot;&gt;Moblin&lt;&#x2F;a&gt; project.  Other factors to consider is the boot software (bootloader vs BIOS, is it open?), are there 3D graphics libraries available, etc.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Multimedia processing:  The OMAP3 is available with an on-chip DSP.  Intel has traditionally offered extensions for multimedia processing such as SIMD.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Tradeoffs!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GTK performance on PXA270 vs. OMAP3</title>
        <published>2009-01-21T00:00:00+00:00</published>
        <updated>2009-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/"/>
        <id>https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/</id>
        
        <content type="html" xml:base="https://bec-systems.com/316/gtk-performance-on-pxa270-vs-omap3/">&lt;p&gt;Several of my customers have built applications using the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.gtk.org&#x2F;&quot;&gt;GTK+&lt;&#x2F;a&gt; tookit.  While GTK+ works fairly well for what we have done, I have been wondering how the performance compares on the new &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;focus.ti.com&#x2F;general&#x2F;docs&#x2F;gencontent.tsp?contentId=36915&quot;&gt;Omap3&lt;&#x2F;a&gt; processors from TI. As we are evaluating the OMAP3 for several projects, I did a simple comparison with an existing application.  Below is a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=VKl5GRNLH4k&quot;&gt;video&lt;&#x2F;a&gt; that shows a fairly complex application running on both a PXA270, and a OMAP3530.  While the PXA270 gets the job done, the result on the OMAP3 is much more pleasing.  With that advent of a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gumstix.com&#x2F;store&#x2F;catalog&#x2F;product_info.php?products_id=211&quot;&gt;OMAP3 module available for $117 in volume&lt;&#x2F;a&gt;, it seems like the OMAP3 will be a popular solution for upcoming Embedded Linux projects.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fix for PXA270 MMC&#x2F;SD Controller Write Corruption</title>
        <published>2009-01-17T00:00:00+00:00</published>
        <updated>2009-01-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/"/>
        <id>https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/</id>
        
        <content type="html" xml:base="https://bec-systems.com/314/fix-for-pxa270-mmcsd-controller-write-corruption/">&lt;p&gt;During system verification for a customer, we noticed occasional failures when writing to a SD card using the Marvell PXA270 MMC&#x2F;SD controller.  The failure is a 4KB block of data is shifted on byte, where the first byte is duplicated and the last byte is dropped. The test app that found this problem is available &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dev.bec-systems.com&#x2F;redmine&#x2F;bec&#x2F;repositories&#x2F;browse&#x2F;miscsrc&#x2F;fs_stress_test&quot;&gt;here&lt;&#x2F;a&gt;.  This test app simulates an application that writes data to a SD card at a certain rate.  We found that typically in about 2000 - 10000 hours of simulated testing, we would see a failure.  Its very interesting that the field failure rates matched this rate as well.&lt;&#x2F;p&gt;
&lt;p&gt;This failure had all the signs of a hardware (likely DMA) problem, and sure enough there is a Marvell Eratta for this issue.  A patch has been developed and tested by several people and is available in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lists.arm.linux.org.uk&#x2F;lurker&#x2F;message&#x2F;20090117.220838.f9e6472f.en.html&quot;&gt;this mail thread&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing Ubuntu on a Core i7 DX58SO motherboard</title>
        <published>2009-01-15T00:00:00+00:00</published>
        <updated>2009-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/302/getting-linux-on-a-dx58so/"/>
        <id>https://bec-systems.com/302/getting-linux-on-a-dx58so/</id>
        
        <content type="html" xml:base="https://bec-systems.com/302/getting-linux-on-a-dx58so/">&lt;p&gt;&lt;strong&gt;UPDATE:  2009-03-17 – It appears that hard drive issues I encountered are likely due to the HW RAID formatting on the drive I tried.  I just tried a brand new hard drive, and Ubuntu 8.10 installed flawlessly, and everything works.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I’m not sure why computer upgrades are always such an epic struggle for me, but here I go again …&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to upgrade my aging AMD X2 system to a new Intel Core i7 system.  So after researching it a bit, I decided on the Intel &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.intel.com&#x2F;products&#x2F;desktop&#x2F;motherboards&#x2F;DX58SO&#x2F;DX58SO-overview.htm&quot;&gt;DX58SO&lt;&#x2F;a&gt; motherboard.  I liked the architecture, and have had good luck with Intel motherboards.  And since I don’t upgrade all that often, I try to get something good when I do.  As I learned later, I should have researched Linux compatibility a little more …&lt;&#x2F;p&gt;
&lt;p&gt;The plan was to simply replace the CPU&#x2F;MB&#x2F;RAM in my existing box as I already have a raid controller, decent case, etc.  However, the first challenge was the existing PS does not supply a EPS&#x2F;ATX12V8 pin connector – it only had the 4-pin version.  So, I got to upgrade my PS to a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.corsair.com&#x2F;products&#x2F;tx&#x2F;default.aspx&quot;&gt;Corsair CMPSU-650TX&lt;&#x2F;a&gt; which seems very nice, and quiet.&lt;&#x2F;p&gt;
&lt;p&gt;After I put everything together, the raid array (3ware 9500S-4LP PCI) was detected, but the system would not boot.  So I booted from a Ubuntu install disk and selected boot from 1st hard disk, and then it seemed to boot fine.  However, the Ethernet controller and CDROM don’t work under Ubuntu 8.04 (64-bit) which was currently installed on the raid array.  However, everything else works pretty well, and it is quite fast.  Because the core-i7 brought back hyperthreading, Linux now shows 8 cores.&lt;&#x2F;p&gt;
&lt;p&gt;Several days later in an attempt to get the system booting from the hard drive, I upgraded the BIOS to the latest version.  However, this broke booting from the raid array; even with a Ubuntu install disk.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, I decided to just rebuild the system by re-configuring the 4 hard drives currently in a hardware raid-5 array to two raid-1 software raid arrays.  As the raid card is only PCI, I think this would provide better performance and be simpler to maintain in the future.  So, I copy all my data off to a USB HD, and then try to install Ubuntu to a HD attached to the motherboard.  To my suprise, I can’t get MB attached hard drives to work.  Lots of messages like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[  361.943329] ata1.01: status: { DRDY ERR }
[  361.943332] ata1.01: error: { ABRT }
[  362.043760] ata1.01: configured for UDMA&#x2F;133
[  362.043771] ata1: EH complete
[  362.218194] ata1.01: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[  362.218200] ata1.01: BMDMA stat 0x45
[  362.218207] ata1.01: cmd c8&#x2F;00:08:00:00:00&#x2F;00:00:00:00:00&#x2F;f0 tag 0 dma 4096 in
[  362.218209]          res 51&#x2F;04:08:00:00:00&#x2F;04:00:1d:00:00&#x2F;f0 Emask 0x1 (device error)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I tried booting a 32-bit Ubuntu 8.10 live CD and I get the same thing when trying to fdisk a hard drive attached to the MB.  So for now, the only way to get this running is to go back to the old RAID controller.  Fortunately, Intel keeps old BIOS versions on their web site and after two tries, I was able to find one that works again with the HW RAID controller.&lt;&#x2F;p&gt;
&lt;p&gt;The Ethernet and CD ROM did work with the Ubuntu 8.10 32-bit live CD, so once I upgrade to 8.10, hopefully that will all work.  So for now, I’ll limp along with my raid controller and a USB-&amp;gt;Ethernet adapter for networking.&lt;&#x2F;p&gt;
&lt;p&gt;Anyone else have success with Linux on the DX58SO?&lt;&#x2F;p&gt;
&lt;p&gt;I’ve filed a &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;ubuntu&#x2F;+bug&#x2F;317607&quot;&gt;bug on launchpad&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Switching to Wordpress</title>
        <published>2009-01-13T00:00:00+00:00</published>
        <updated>2009-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/296/switching-to-wordpress/"/>
        <id>https://bec-systems.com/296/switching-to-wordpress/</id>
        
        <content type="html" xml:base="https://bec-systems.com/296/switching-to-wordpress/">&lt;p&gt;After using Joomla for several years, I’m switching my web site to wordpress.  As I mostly use my site for writing technical articles, it makes sense to use something that works very well for just that.  So far, I’m finding Wordpress very polished, and it has all the functionality I need built-in, so I don’t have to rely on 3rd party modules for very basic operations like tagging, RSS feeds, comments, etc.  Now I have no excuse for now writing more as Wordpress works so well.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono 2.2 RC1 added to Openembedded</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/"/>
        <id>https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/274/mono-2-2-rc1-added-to-openembedded/">&lt;p&gt;I recently added&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;packages&#x2F;mono&quot;&gt;Mono 2.2 RC1 to OpenEmbedded&lt;&#x2F;a&gt;.  The last usable version of Mono in Openembedded was 1.2.6, so this is a big step up.  Lots of interesting things have been happening since then (like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;tirania.org&#x2F;blog&#x2F;archive&#x2F;2008&#x2F;Nov-05.html&quot;&gt;Full Static Compilation&lt;&#x2F;a&gt;) that continue to make Mono interesting for embedded.  There is still plenty to do yet such as clean up the packaging, and update the other related recipes such as mono-xsp, and gtk-sharp.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using the Vala Programming Language in Embedded Systems</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/"/>
        <id>https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/277/using-the-vala-programming-language-in-embedded-systems/">&lt;p&gt;Recently I’ve been following the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;live.gnome.org&#x2F;Vala&quot;&gt;Vala programming language&lt;&#x2F;a&gt; and using it some in embedded systems.  Vala is a new programming language that aims to bring modern programming features to GNOME developers without imposing additional runtime requirements and without using a different ABI compared to applications and libraries written in C.  A few notes and observations about Vala:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;language syntax that resembles C#, so you can write code faster with less mistakes&lt;&#x2F;li&gt;
&lt;li&gt;Vala compiles to C, so it starts fast and runs fast like native applications&lt;&#x2F;li&gt;
&lt;li&gt;binaries are not platform independent  (like Mono or Java)&lt;&#x2F;li&gt;
&lt;li&gt;lots of bindings already exist, as it is very easy to write bindings to existing C libraries&lt;&#x2F;li&gt;
&lt;li&gt;easy to write programs that are mixed C and Vala&lt;&#x2F;li&gt;
&lt;li&gt;documentation is still a bit sparse, so you end up reading the binding files to figure out how to use the libraries&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Much of the core Vala functionality is built on top of Glib.  Having programmed extensively with Glib, I can say programming in Vala is a lot more fun, and a lot less tedious.  Vala also provides dynamic D-Bus bindings which makes if very nice for writing system daemons or other bits of software that need to implement a D-Bus server.&lt;&#x2F;p&gt;
&lt;p&gt;As far as real world experience, in a recent application, we ported a system monitoring application from C# to Vala.  There were no real serious problems with the original application, but it started slow (7 seconds or so), and the customer wanted to reduce the boot time of the system.  Once you get past the core language syntax, the libraries for Vala are all different than C#, so most of the library function calls needed tweaked a little.  Most of the functionality was implemented with Vala, but there were a few minor functions that were implemented in C.  It now starts fast, which is what we needed.&lt;&#x2F;p&gt;
&lt;p&gt;We are also using the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.freesmartphone.org&#x2F;?p=openmoko-gsoc2008.git;a=tree;f=fsod&quot;&gt;fsod&lt;&#x2F;a&gt; application from the OpenMoko project in a customer project.  This is an excellent example of a well written, advanced Vala project that uses features such as plugins and D-Bus.&lt;&#x2F;p&gt;
&lt;p&gt;Watching the releases from the Vala project, it is amazing the progress this language is making.  I’m sure we’ll be hearing more about Vala in the future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement an interrupt driven GPIO input in Linux</title>
        <published>2009-01-10T00:00:00+00:00</published>
        <updated>2009-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/"/>
        <id>https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux/">&lt;p&gt;With Linux, some of the things that seem like they should be easy are not – at least at first glance.  For example, how do you read an interrupt driven GPIO input in a Linux application?  With simpler microcontroller systems, this is straightforward, but with a system like Linux, you have to navigate through several layers of software (and for very good reasons).  You can’t handle interrupts directly in a Linux application, so this means you need a kernel component involved.  This operation of reading a GPIO resembles a key press, so the Linux input subsystem might be a good place to start looking.  Once we take that route, we discover the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.kernel.org&#x2F;?p=linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux-2.6.git;a=blob;f=drivers&#x2F;input&#x2F;keyboard&#x2F;gpio_keys.c&quot;&gt;gpio_keys&lt;&#x2F;a&gt; driver.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-the-gpio-keys-driver&quot;&gt;Configuring the gpio_keys driver&lt;&#x2F;h2&gt;
&lt;p&gt;The gpio_keys driver is configured with a few lines of code in your Linux board configuration file.  An example is below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;static struct gpio_keys_button svs_button_table[] = {
  { .code = KEY_RECORD,
    .gpio = PP_GPIO_MIC_EN,
    .active_low = 1,
    .desc = &amp;quot;MIC_EN&amp;quot;,
    .type = EV_KEY,
    .wakeup = 0,
  },
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this application, we are reading button presses on a cell phone style headset.  Once the gpio_keys driver is configured, a new entry will show up in &#x2F;dev&#x2F;input&#x2F;eventX.  An application can then do a blocking read on this device.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reading-the-gpio-in-an-application&quot;&gt;Reading the GPIO in an application&lt;&#x2F;h2&gt;
&lt;p&gt;To read the GPIO, we simply do a blocking read on the new &#x2F;dev&#x2F;input&#x2F;eventX device.  The read will block until there is a change in GPIO state.  An example is show below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#define MIC_INPUT_DEV  &amp;quot;&#x2F;dev&#x2F;input&#x2F;event0&amp;quot;

static gboolean mic_button_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
  struct input_event ev;
  int bytes_read;

g_io_channel_read_chars(source, (gchar *)&amp;amp;ev, sizeof(ev), &amp;amp;bytes_read, NULL);

if (bytes_read &amp;gt; 0) {
    if (bytes_read != sizeof(ev)) {
      s_debug(1, &amp;quot;warning, only read %i bytes from mic input&amp;quot;);
      return TRUE;
    }
  } else {
    return TRUE;
  }

if (ev.type != EV_SYN &amp;amp;&amp;amp; ev.value == 1) {
    &#x2F;* button pressed, do something ... *&#x2F;
  }

return TRUE;
}

void mic_button_init()
{
  GIOChannel * micbutton = g_io_channel_new_file(MIC_INPUT_DEV, &amp;quot;r&amp;quot;, NULL);

if (micbutton == NULL) {
    s_debug(TRUE, &amp;quot;Error initializing mic button&amp;quot;);
    return;
  }

g_io_channel_set_encoding(micbutton, NULL, NULL);

guint id = g_io_add_watch(micbutton, G_IO_IN, mic_button_callback, NULL);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above example also shows how to incorporate the GPIO read into a GLib mainloop so that you don’t need to create a separate thread. ( As a side, GLib mainloop programming is worth learning!)  Using this method, reading a GPIO interrupt is easy and requires very few lines of code.  This is typical of complex systems like Linux – if you know how to do something, it is relatively easy, but getting started down the right path is sometimes the challenge.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tips for reading a serial data stream in Python</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/"/>
        <id>https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/</id>
        
        <content type="html" xml:base="https://bec-systems.com/257/tips-for-reading-a-serial-data-stream-in-python/">&lt;p&gt;Interfacing with a RS232 serial device is a common task when using Python in embedded applications.  The easiest way to get python talking to serial ports is use the pyserial project found at  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;pyserial.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;pyserial.sourceforge.net&#x2F;&lt;&#x2F;a&gt;.  This module works on most platforms and is straightforward to use (see examples on project web site). However, getting the read function in this module to operate in an optimal way takes a little study and thought.  This article investigates how the pyserial module works, possible issues you might encounter, and how to optimize serial reads.&lt;&#x2F;p&gt;
&lt;p&gt;We start out with several goals as to how we want the application to behave in relation to the serial port:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;application must block while waiting for data.&lt;&#x2F;li&gt;
&lt;li&gt;for performance reasons, we want to read decent size chunks of data at a time if possible.  Python function calls are expensive, so performance will be best if we can read more than one byte at a time.&lt;&#x2F;li&gt;
&lt;li&gt;We want any data received returned in a timely fashion.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A key parameter in the pyserial &lt;em&gt;Serial&lt;&#x2F;em&gt; class is the &lt;em&gt;timeout&lt;&#x2F;em&gt; parameter.  This parameter is defined as:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; timeout=None,           #set a timeout value, None for waiting forever
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;em&gt;Serial&lt;&#x2F;em&gt; class &lt;em&gt;read&lt;&#x2F;em&gt; function also accepts a &lt;em&gt;size&lt;&#x2F;em&gt; parameter that indicates how many characters should be read.  Below is the source for the read function on Posix systems (Linux, etc):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;     def read(self, size=1):
        &amp;quot;&amp;quot;&amp;quot;Read size bytes from the serial port. If a timeout is set it may
           return less characters as requested. With no timeout it will block
           until the requested number of bytes is read.&amp;quot;&amp;quot;&amp;quot;
        if not self.fd: raise portNotOpenError
        read = &amp;#39;&amp;#39;
        inp = None
        if size &amp;gt; 0:
            while len(read) &amp;lt; size:
                #print &amp;quot;\tread(): size&amp;quot;,size, &amp;quot;have&amp;quot;, len(read)    #debug
                ready,_,_ = select.select([self.fd],[],[], self.timeout)
                if not ready:
                    break   #timeout
                buf = os.read(self.fd, size-len(read))
                read = read + buf
                if self.timeout &amp;gt;= 0 and not buf:
                    break  #early abort on timeout
        return read
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The easy way to use this module is to simply set the timeout to None, and read size to 1.  This will return any data received immediately.  But, this setup is very inefficient when transferring large amounts of data due to the Python processing overhead.&lt;&#x2F;p&gt;
&lt;p&gt;To meet our goal of reading multi-byte blocks of data at a time, we need to pass the read function a size greater than 1.  However, if timeout is set to None, the read will block until size bytes have been read, which does not meet the goal of returning any data read in a timely fashion.  The solution then is to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;set the read size high enough to get good performance&lt;&#x2F;li&gt;
&lt;li&gt;set the timeout low enough so that any data received is returned in a reasonable timeframe, but yet the application spends most of its time blocked if there is no data.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example, a size of 1000 and a timeout of 1 second seems to perform well.  When used this way, the pyserial module performs well and returns all data read quickly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Optimize Python reads for general data</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/"/>
        <id>https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/</id>
        
        <content type="html" xml:base="https://bec-systems.com/259/how-to-optimize-python-reads-for-general-data/">&lt;p&gt;The Python file object read() function acts a little differently than the standard read() found in C.  This article describes some of these differences and how to optimize reads for general continuous data streams such as reading data from a collection device through a pipe.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-read&quot;&gt;Python read()&lt;&#x2F;h2&gt;
&lt;p&gt;The Python read function seems to be optimized for reading files and text oriented streams.  By default, a read() call will block until a EOF is encountered.  This is very handy for reading files from a disk.  You can just slurp them up with one read() statement.  If you pass a size parameter to read(), it will block until size bytes have been received.  This is less than ideal for reading a continuous data stream where some of thye data may be stuck until the size threshhold is reached.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;non-blocking-read&quot;&gt;Non-blocking read()&lt;&#x2F;h2&gt;
&lt;p&gt;The way you get read to return with whatever data is available even if it is less than the read size parameter is to set the file object up in non-blocking mode.  This can be done using the fcntl module:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 		flags = fcntl.fcntl(fp, fcntl.F_GETFL)
            	fcntl.fcntl(fp, fcntl.F_SETFL, flags | os.O_NONBLOCK)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, now the application does not block while waiting for data and spins using CPU resources.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;select&quot;&gt;select()&lt;&#x2F;h2&gt;
&lt;p&gt;Enter the select call.  The Python select module does much the same thing as the C select() function.  In this case, it can be used to block waiting for data from a non-blocking file object with the added benefit of a timeout.  So the resulting code might look like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; 	fp = os.popen(&amp;lt;application that returns data to stdout&amp;gt;, &amp;#39;r&amp;#39;)

flags = fcntl.fcntl(fp, fcntl.F_GETFL)
    	fcntl.fcntl(fp, fcntl.F_SETFL, flags | os.O_NONBLOCK)

while 1:
		[i, o, e] = select.select([fp], [], [], 5)
		if i: s_ = fp.read(1000)
		else: s_ = &amp;#39;&amp;#39;

if s_:
			logging.debug(&amp;quot;received %i bytes of data, total = %i&amp;quot; % (len(s_), total))
			&amp;lt;do something with s_&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above select statement blocks until data is available from the fp object or times out after 5 seconds.  Reading continuous data streams in Python is very possible, but usually requires the file object to be set in non-blocking mode and a select used to block while waiting for data.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Implementing Asterisk</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/262/implementing-asterisk/"/>
        <id>https://bec-systems.com/262/implementing-asterisk/</id>
        
        <content type="html" xml:base="https://bec-systems.com/262/implementing-asterisk/">&lt;p&gt;Over the past month, we have been working on implementing Asterisk in our office.  Asterisk (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.asterisk.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.asterisk.org&#x2F;&lt;&#x2F;a&gt; ) is a complete software PBX (Private Branch Exchange) that runs on top of Linux.  Asterisk supports a number of features commonly found in a PBX including voicemail, hosted conferencing, call queuing, and many other features.  Having a real PBX provides many benefits for a business and has the potential to improve our service and lower our costs.  Over the next couple months we will be writing about our experiences implementing Asterisk, tips for setting it up etc.&lt;&#x2F;p&gt;
&lt;p&gt;One of the most amazing things about Asterisk is its flexibility.  You can mix and match IP phones, traditional analog phones, soft phones, traditional PSTN lines, and VOIP services in about any way you want.  Our setup is fairly simple – IP phones and connections to the outside world using our PSTN land line.  We are also evaluating several VOIP providers and trying to determine if VOIP is viable.  Stay tuned …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Implement a Web Application Framework in an Embedded Linux System</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/40/web-application-framework-embedded-linux/"/>
        <id>https://bec-systems.com/40/web-application-framework-embedded-linux/</id>
        
        <content type="html" xml:base="https://bec-systems.com/40/web-application-framework-embedded-linux/">&lt;p&gt;As devices are increasingly more networked, an embedded web server is becoming a standard way for users to interact with and configure an embedded device using a standard web browser.  As an example, most pieces of networking equipment (such as routers and wireless access points) are configured this way.  There are many ways to implement a web server.  One way is to just write a monolithic program that handles the requests and outputs HTML using print statements.  Without a lot of planning, you usually end up with something where logic is intermixed with presentation.  The disadvantage of such an approach is that it quickly becomes very difficult to maintain your web application as it grows and changes.  The current best practice with web application frameworks (such as Ruby on Rails) splits a web application into 3 distinct components (Model, View, Controller – MVC) so that changes to one component can be made with minimal impact to others.  This article details a solution used in a recent project to implement such an architecture  using the following open source components: SQLite, Clearsilver, and Python.  The challenge was to find a solution that performed acceptably on a resource constrained 130MHz ARM-Linux system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;components-used&quot;&gt;Components Used&lt;&#x2F;h2&gt;
&lt;p&gt;The requirements for the web application framework for this system are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Footprint must be fairly small – less than 10MiB.&lt;&#x2F;li&gt;
&lt;li&gt;Must enable us to implement a clean MVC type architecture.&lt;&#x2F;li&gt;
&lt;li&gt;Must support a high level language like python for rapid development.&lt;&#x2F;li&gt;
&lt;li&gt;Includes a database.&lt;&#x2F;li&gt;
&lt;li&gt;Reasonable performance – less than 1 second to render a typical page.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After researching and testing several options, the following components were chosen to implement the framework:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Web Server: Cherokee (1MiB)&lt;&#x2F;li&gt;
&lt;li&gt;Model: SQLite  (290KiB)&lt;&#x2F;li&gt;
&lt;li&gt;View: Clearsilver  (170KiB)&lt;&#x2F;li&gt;
&lt;li&gt;Controller: Python (2-3MiB)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;web_app_framework1-1.jpg&quot; alt=&quot;web_app_framework1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Total size for the above components is about 4MiB.&lt;&#x2F;p&gt;
&lt;p&gt;The following sequence occurs during a typical web transaction:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An HTTP request is received by Cherokee&lt;&#x2F;li&gt;
&lt;li&gt;If the request matches the URI for the web application, Cherokee forwards the request to the web application framework via CGI.&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver parses the HTTP headers (including CGI GET and POST parameters) and provides the data to python in a easy to access HDF format.&lt;&#x2F;li&gt;
&lt;li&gt;Python looks at the URI and dispatches the request to the appropriate function.  Data is extracted from the SQLite database and an HDF datastructure is created.&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver is called to render the appropriate template.  Data from the HDF datastructure is used in the template to provide the dynamic content in the page.&lt;&#x2F;li&gt;
&lt;li&gt;The rendered HTML is passed back to Cherokee, and is then returned to the user’s web browser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each component is discussed in more detail in the following sections.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h2&gt;
&lt;p&gt;One of the issues with modern web frameworks is that most require a lot of processing power.  Many frameworks are written in an interpreted language which tend to be not very efficient on embedded systems such as the 130MHz ARM-Linux system used in this project.  As most of the application development for this project is done in Python, I tried several other Python based solutions with the following results:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Django&lt;&#x2F;strong&gt;: takes &lt;strong&gt;10&lt;&#x2F;strong&gt; seconds to render a page&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;webpy&lt;&#x2F;strong&gt;: takes &lt;strong&gt;5&lt;&#x2F;strong&gt; seconds to render a page&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clearsilver&#x2F;Python&lt;&#x2F;strong&gt;: takes about &lt;strong&gt;1&lt;&#x2F;strong&gt; second to render a page&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Anything over 1 second is very slow for a web interface.  With fastcgi, webpy could probably have been sped up to be acceptably fast, but I don’t think there is much hope for frameworks like django on this type of system.  I have read of similar experiences trying to run Ruby-on-Rails on ARM-Linux systems.  As I’m currently just using a basic CGI interface, the Clearsilver solution could also be sped up significantly as well, if the Python portion could be kept running between requests with fastcgi or a similar mechanism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cherokee-web-server&quot;&gt;Cherokee Web Server&lt;&#x2F;h2&gt;
&lt;p&gt;A web application typically consists of a web server (like Apache) and a program that provides the dynamic web content.  Some of the functions of a web server are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;receives HTTP requests&lt;&#x2F;li&gt;
&lt;li&gt;handles the request by serving static files&#x2F;images or routes the request to a program that outputs dynamic content&lt;&#x2F;li&gt;
&lt;li&gt;authentication&lt;&#x2F;li&gt;
&lt;li&gt;encryption (SSL, TLS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are many web servers that can be used in embedded devices.  Some of them are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lighttpd (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.lighttpd.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.lighttpd.net&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;thttpd (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.acme.com&#x2F;software&#x2F;thttpd&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.acme.com&#x2F;software&#x2F;thttpd&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Appweb (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.appwebserver.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.appwebserver.org&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Boa (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.boa.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.boa.org&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;Cherokee (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.cherokee-project.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.cherokee-project.com&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;li&gt;SHTTPD (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;shttpd.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;shttpd.sourceforge.net&#x2F;&lt;&#x2F;a&gt; )&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cherokee was chosen for this application because it provides a good balance between the size and functionality I am looking for.  It is also included in the Openembedded (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt; ) build system I am using.  Other systems will have different requirements – use the one that fits your application best.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;clearsilver&quot;&gt;Clearsilver&lt;&#x2F;h2&gt;
&lt;p&gt;Clearsilver (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.clearsilver.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.clearsilver.net&#x2F;&lt;&#x2F;a&gt; ) is the real gem that was discovered during this exercise.   Clearsilver is a language-neutral HTML template system written in C.  It is used as the templating system for many high volume sites such as Google Groups 2.  Clearsilver also provides CGI handling functions and bindings to several languages including Python.  The fact that it is written in C and is fast for high volume sites also makes it &lt;em&gt;fast enough&lt;&#x2F;em&gt; on slower embedded systems.  Because Clearsilver is written in C, the templating system is already fast.  Parts or all of the application can also be moved to C as needed to get the required performance.  Having a performance upgrade path is nice.  Clearsilver also forces a strict separation of application logic and presentation templates, which keeps things in line with the MVC architecture.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sqlite&quot;&gt;SQLite&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.sqlite.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.sqlite.org&#x2F;&lt;&#x2F;a&gt; ) is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.  SQLite works as expected and also has bindings to a number of languages including Python.  A SQLite database is just a single file that requires no configuration, making it very easy to use.  The database engine runs in the same process as the application using it, which increases performance because there is no context switch when running database operations.   Because SQLite does not have its own process, it does not handle concurrency as well as other databases such as MySQL, but in an embedded system you seldom have more than one process using the database.  SQLite provides some support for concurrency with reader&#x2F;writer locks for the entire database.  If your application is not real busy, this is often adequate if you need two processes to share some data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python&quot;&gt;Python&lt;&#x2F;h2&gt;
&lt;p&gt;Python is the glue that ties things together in this web application framework.  It sits between Clearsilver and the database.  The advantages of using a language like Python are rapid development and an extensive library.  Python is considerably slower than C, but there is always the option to move parts of the application into C as needed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openembedded-build-system&quot;&gt;Openembedded Build System&lt;&#x2F;h2&gt;
&lt;p&gt;How does one put together a system with all these components?  The answer is the Openembedded Build System (OE) (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt;).  OE includes support for all of the components discussed in this article.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;The combination of Python, Clearsilver, and SQLite provides a compelling solution for a web application framework in an Embedded Linux System.  The solution is reasonably small, performs well, and provides a path to improve performance if needed.  We also get a clean architecture to create clean, maintainable web applications.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;About the author&lt;&#x2F;strong&gt; – Cliff Brake owns BEC Systems, a consulting operation that helps customers utilize modern computer technologies in their products.  BEC offers a range of services to make your embedded project a success including technology selection, development, troubleshooting, and training.  Please visit our website (&lt;a href=&quot;..&#x2F;..&#x2F;&quot;&gt;http:&#x2F;&#x2F;bec-systems.com&lt;&#x2F;a&gt; ) for more information and other free resources.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Do you have an Exit Strategy?</title>
        <published>2009-01-09T00:00:00+00:00</published>
        <updated>2009-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/73/do-you-have-an-exit-strategy/"/>
        <id>https://bec-systems.com/73/do-you-have-an-exit-strategy/</id>
        
        <content type="html" xml:base="https://bec-systems.com/73/do-you-have-an-exit-strategy/">&lt;p&gt;Some time ago, eWeek published in interesting article by Scott McNealy named “&lt;em&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eweek.com&#x2F;article2&#x2F;0,1895,1907211,00.asp&quot;&gt;Technology’s Barriers to Exit&lt;&#x2F;a&gt;”&lt;&#x2F;em&gt;.  In this article, Scott makes an interesting point about considering the cost of technology.  There are three costs to consider:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;cost of acquisition&lt;&#x2F;li&gt;
&lt;li&gt;ongoing cost&lt;&#x2F;li&gt;
&lt;li&gt;cost to exit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Scott states that most people analyze the first two costs fairly well.  What is not thought about as much is the the cost to exit – how do I move on to the next thing.  I think these basic questions apply very much to embedded technology decisions.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the time we carefully consider our requirements, think about ongoing manufacturing costs, etc.  There may be some thought given to upgrading (the exit), but we encounter several difficulties when planning for the future with complex embedded systems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we often can’t predict what technologies will be available in the future&lt;&#x2F;li&gt;
&lt;li&gt;if may be difficult to predict our product requirements in the future&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As an example, we may have a product with an ethernet networking interface, and two years after product launch we have an opportunity that requires a wireless network interface.  How much is it going to cost to add wireless support to our product?  If the product is based on technologies that do not fundamentally support wireless networking, we are looking at very costly exit strategy.  Another example is application-specific, off-the-shelf solutions.  While these are great for many problems and provide a quick way to get something working, what happens when we want to upgrade?  Do we have to re-implement the entire system?&lt;&#x2F;p&gt;
&lt;p&gt;How does one hedge against the unknowns in the future?  One way is to try to anticipate every possible requirement and design it in.  I think this is bad strategy because you usually end up spending a lot of time working on things you don’t really need and the quality of the product suffers.  A better approach is make sure your product does what it needs to do well and is based on a flexible platform where significant parts of your design and software can be re-used in future versions.  This approach has many parallels to recent trends in software development and manufacturing such as Agile Software Development, and Lean Manufacturing.&lt;&#x2F;p&gt;
&lt;p&gt;Follow Scott’s advice and make technology selection decisions with the following questions in mind:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Is the technology based on open standards?&lt;&#x2F;li&gt;
&lt;li&gt;Are programming interfaces and protocols open, published, and been adopted by industry?&lt;&#x2F;li&gt;
&lt;li&gt;Is there a community process behind the technology (not just one company)?&lt;&#x2F;li&gt;
&lt;li&gt;Can the same technology be sourced from multiple companies?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The use of Linux in embedded systems is an excellent example of a technology that meets the above criteria.  You can develop your prototype on a x86 PC.  Move it to an embedded ARM single board computer (SBC) for the first production run.  Switch to a different SBC or design your own board when you run into new product requirements.  Sure, it will cost you more to develop the product initially due to the complexity of a system like Linux, but you now have options to expand and change your product while directly re-using the work you have already done.&lt;&#x2F;p&gt;
&lt;p&gt;But wait, as long as I write my application in C, it is portable – right?  Most embedded systems support development in C so I will just port my application to a new platform when needed.  C is a great language and the &lt;em&gt;language&lt;&#x2F;em&gt; is more or less portable between systems.  But as systems get more and more complex, embedded engineers find themselves spending less time writing original code and spending more time putting together pieces that already exist.  A modern embedded application is often little more than some glue between various libraries and system functions.  The fact that you can develop in C for a particular system does not really mean a lot.  What about the threading model, driver model, library APIs, etc.  I just spent a significant amount of time recently porting a large C application from a proprietary platform to new hardware platform as the original system was going obsolete.  It was a huge amount of work.  The driver model was completely different, APIs were different.  Changing platforms can be very expensive.&lt;&#x2F;p&gt;
&lt;p&gt;It rarely pays to be short sighted when choosing technologies for complex embedded systems.  The best strategy is to stay flexible and choose a platform with a future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gumstix Overo Connector Spreadsheet</title>
        <published>2008-12-15T00:00:00+00:00</published>
        <updated>2008-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/"/>
        <id>https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/</id>
        
        <content type="html" xml:base="https://bec-systems.com/113/gumstix-overo-connector-spreadsheet/">&lt;p&gt;One of the first things I do when designing a system based on a processor module is create a spreadsheet listing all the connector I&#x2F;O.  This is the easiest way I’ve found to make sure nothing gets missed.  My first pass at a I&#x2F;O spreadsheet for the Gumstix Overo is available at:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&quot;&gt;http:&#x2F;&#x2F;redmine.bec-systems.com&#x2F;bec&#x2F;documents&#x2F;1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to disable SSH host key checking</title>
        <published>2008-12-12T00:00:00+00:00</published>
        <updated>2008-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/"/>
        <id>https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/</id>
        
        <content type="html" xml:base="https://bec-systems.com/220/how-to-disable-ssh-host-key-checking/">&lt;p&gt;This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxcommando.blogspot.com&#x2F;2008&#x2F;10&#x2F;how-to-disable-ssh-host-key-checking.html&quot;&gt;article&lt;&#x2F;a&gt; presents a very nice overview of options to disable ssh host key checking.  When working with embedded systems where you are constantly reloading the rootfs, it is really annoying to have to edit your &lt;em&gt;~&#x2F;.ssh&#x2F;known_hosts&lt;&#x2F;em&gt;every time you update the rootfs on the target device.  The solution is to simply disable host key checking for your local subnet by adding something like the following to the beginning of &lt;em&gt;&#x2F;etc&#x2F;ssh&#x2F;ssh_config&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Host 192.168.1.*
   StrictHostKeyChecking no
   UserKnownHostsFile=&#x2F;dev&#x2F;null
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anything not on the 192.168.1.* subnet is still checked.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2009-09-26:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Another place to put these config settings is: &lt;em&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Printing from Embedded Systems</title>
        <published>2008-12-02T00:00:00+00:00</published>
        <updated>2008-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/218/printing-from-embedded-systems/"/>
        <id>https://bec-systems.com/218/printing-from-embedded-systems/</id>
        
        <content type="html" xml:base="https://bec-systems.com/218/printing-from-embedded-systems/">&lt;p&gt;How does one implement support for printing in embedded systems? I recently had the opportunity to add printing support to an embedded Linux system.  The device is an industrial touch screen powered by a Compulab cm-x270 module (PXA270 CPU), and runs a GTK+ application.  The customer is implementing a device calibration system where customers bring their equipment in to get calibrated, and the system prints out a report on a local printer.  This article describes how components of Hewlett Packard’s HPLIP solution along with Cairo can be used to implement printer support in a non-desktop Linux system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;The requirements for this project were fairly basic – we needed to print a single page report that contained text and some elementary graphics.  We initially wanted to support several low-end Inkjet and Laser USB printers.  As the system was powered by a fairly slow ARM processor (slow compared to modern desktop systems), the solution needed to be efficient, and not require excessive amounts of memory.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;desktop-linux-print-flow&quot;&gt;Desktop Linux Print Flow&lt;&#x2F;h3&gt;
&lt;p&gt;With desktop Linux systems, the standard printing flow looks something like this:&lt;&#x2F;p&gt;
&lt;p&gt;Application -&amp;gt; PS output -&amp;gt; Ghostscript -&amp;gt; Rasterized output -&amp;gt; Printer Driver (filter) -&amp;gt; I&#x2F;O Backend -&amp;gt; Printer&lt;&#x2F;p&gt;
&lt;p&gt;CUPS is typically used to manage this flow, provide queuing, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;print-architecture&quot;&gt;Print Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;As the application is written in GTK+, we decided to generate the report using Cairo, which is a 2D graphics library.  Cairo is easy to use, and is well suited for this application.  With a Cairo generated report, we already had a raster image of the report, so it seemed that the PS output&#x2F;Ghostscript steps were not really needed and only added more processing to the data flow.  Also the PXA270 CPU does not have a FPU, and PostScript processing can be floating point intensive.  So the need was now to figure out how to get a Cairo generated raster image to a USB printer.&lt;&#x2F;p&gt;
&lt;p&gt;Hewlett Packard offers lots of interesting software for their printers.  Their APDK is a OS independent library in source code form.  However, implementing this would have required quite a bit of integration, and writing the I&#x2F;O layer.  It seemed like there should be something available that would work with a little less effort.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;hplipopensource.com&#x2F;&quot;&gt;HPLIP project&lt;&#x2F;a&gt; is a comprehensive set of software for Linux printing, and is used by desktop Linux systems.  It is not obvious at a glance how all the components of HPLIP fit together, but after spending some time digging through source code, and asking questions on several maillists&#x2F;forums, we were able to figure out that the basic flow is:&lt;&#x2F;p&gt;
&lt;p&gt;Ghostscript -&amp;gt; HPIJS (driver) -&amp;gt; HP backend -&amp;gt; Printer&lt;&#x2F;p&gt;
&lt;p&gt;In this application, we simply launched the HPIJS driver directly from our application instead of Ghostscript.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hplip&quot;&gt;HPLIP&lt;&#x2F;h3&gt;
&lt;p&gt;There were several challenges using HPLIP in our ARM system.  The HPLIP is not cross-compilation friendly out of the box, so we had to fix a few issues, and ended up disabling all the Python pieces as we only needed the HPIJS and backend components.  We also had to figure out the data flow from the application to HPIJS, and then to HP backend.  In a nutshell, the process is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;start the hp backend process by forking, and obtain a file handle to STDIN for the hp backend process&lt;&#x2F;li&gt;
&lt;li&gt;start the HPIJS process, send various parameters to it including the file handle for the backend STDIN&lt;&#x2F;li&gt;
&lt;li&gt;send HPIJS the print raster and tell it to print&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are some additional details such as handling margins, error conditions, cancel support, etc.  Some of the details can be gleaned from the Ghostscript source code, and the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linuxprinting.org&#x2F;ijs&#x2F;&quot;&gt;IJS reference implementation&lt;&#x2F;a&gt; provides some very useful library code for implementing the IJS client functionality in the application that is doing the printing.  When finished, our printing module was 403 source lines of code (SLOC) – not bad considering the functionality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-well-does-it-work&quot;&gt;How well does it work?&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, we are very pleased with the result.  With a simple industrial terminal, we can now support just about every USB printer made by HP with the exception of some of their very low end LaserJet printers that require a binary plugin.  The HP backend can be used to detect what printer is attached at run time, so everything is plug-n-play with &lt;em&gt;no&lt;&#x2F;em&gt; user configuration.  Let me repeat as this is significant – on a simple Industrial terminal, we can support about every HP USB printer available with no user configuration.  This is easier for users than their desktop as they simply need to buy a printer and plug it in!  Kudos to HP for their excellent open source software.  Because the source code is available, we were able to customize it for our application with very little support from HP.  Performance wise, the printing process is quite fast; the printer starts almost immediatly after the user initiates the print.  Now if I could just get HP to build a ARM version of their binary plugin for the few low end lasers we can’t support … but this is not a critical issue for this vertical application.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;future-direction&quot;&gt;Future Direction&lt;&#x2F;h3&gt;
&lt;p&gt;Hopefully, this type of solution can evolve into a standard printing solution for Embedded Linux systems.  Epson also supports the IJS driver model, so adding support for their printers should be possible.  It may eventually make sense to integrate portions of CUPS for queing, and other management tasks.  Some of the tasks I hope to implement in the future:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up the HPLIP build for inclusion in OpenEmbedded.&lt;&#x2F;li&gt;
&lt;li&gt;Clean up the IJS reference code library build and packaging in OpenEmbedded.&lt;&#x2F;li&gt;
&lt;li&gt;Figure out portions of CUPS that may make sense.&lt;&#x2F;li&gt;
&lt;li&gt;Keep conversations going with the Linux printing group so we can someday have a “standard” printing solution for embedded Linux systems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thanks to Matt Gessner for helping implement this solution, and for providing feedback on this article.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Things that work!</title>
        <published>2008-11-19T00:00:00+00:00</published>
        <updated>2008-11-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/250/things-that-work/"/>
        <id>https://bec-systems.com/250/things-that-work/</id>
        
        <content type="html" xml:base="https://bec-systems.com/250/things-that-work/">&lt;p&gt;Running a small business has a special set of challenges, and if you are not careful, the overhead can quickly consume you.  This article is a list of things that I use in my business that work well for me, and help me to be efficient when there is so much to do …&lt;&#x2F;p&gt;
&lt;p&gt;Entire article at: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;101&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;101&#x2F;9&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;asterisk&quot;&gt;Asterisk&lt;&#x2F;h3&gt;
&lt;p&gt;While I can’t say the same for VOIP proiders, the Asterisk PXB is a very solid product.  I run it on an ancient 1GHz celeron system, and use it for my office PBX.  In combination with a VOIP service, I can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;handle multiple calls at once&lt;&#x2F;li&gt;
&lt;li&gt;easily conference multiple callers&lt;&#x2F;li&gt;
&lt;li&gt;forward calls to my cell phone or other numbers&lt;&#x2F;li&gt;
&lt;li&gt;provide extensions for associates who are working with me&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and all at a very low cost.  To mitigate some of the reliability problems I’ve had with VOIP providers, I set the VOIP provider to use my cell phone as a backup if the VOIP link is down.  I also use multiple VOIP providers for outgoing calls so that if one is not working, I can usually use the backup.  Overall, I really like the features, and for my business the occasional hassle is worth it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sql-ledger&quot;&gt;SQL-Ledger&lt;&#x2F;h3&gt;
&lt;p&gt;SQL-Ledger is a web based accounting program that is open source.  It provides all the features I need to run my business, and offers the following advantages over more traditional programs such as Quickbooks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;web based so I can access it anywhere, even remotely.&lt;&#x2F;li&gt;
&lt;li&gt;subcontractors and associates can log time remotely directly in my accounting system.&lt;&#x2F;li&gt;
&lt;li&gt;granular permissions for different people who need to use it.&lt;&#x2F;li&gt;
&lt;li&gt;upgrades just work.&lt;&#x2F;li&gt;
&lt;li&gt;consistent, reliable operation that I expect from an accounting system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;openocd&quot;&gt;OpenOCD&lt;&#x2F;h3&gt;
&lt;p&gt;We finally have a low cost, open source JTAG solution that works reasonably well.  While there are still issues, it gets the job done for most of my projects, and offers my customers a low cost way to program their systems using JTAG.  Often customers are not doing extensive development, and it is nice to be able to provide a solution for the occasional need.  One customer fought with a very expensive commercial unit for weeks.  I finally shipped them a $50 Olimex unit that did everything they needed.  There can’t be enough said for everyone on a team using the same tools, and they only way this can happen easily is if the tools are fairly low cost.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tracks&quot;&gt;Tracks&lt;&#x2F;h3&gt;
&lt;p&gt;Tracks is a nice web-based task managment tool to help implement the GTD methodology.  The user interface is supurb and better than most native applications I’ve used.  I use the “starred” items for my “next action” on each project.  Very nice!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;printable-ceo-emergent-time-tracker&quot;&gt;Printable CEO Emergent Time Tracker&lt;&#x2F;h3&gt;
&lt;p&gt;I use David Seah’s handy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;davidseah.com&#x2F;blog&#x2F;the-printable-ceo-iii-emergent-task-timing&#x2F;&quot;&gt;form&lt;&#x2F;a&gt; for tracking my time during the day.  It forces me to use a pen and paper every day which is a pretty rare thing, and is a nice compromise between simplicity and automation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openembedded&quot;&gt;OpenEmbedded&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve written a lot about the &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;benefits&lt;&#x2F;a&gt; of OpenEmbedded.  It makes the huge task of creating a build system for Embedded Linux systems very manageable and repeatable.  When build systems are fully automated, things are so much easier.  As an example, I’ve been working on one project for over two years, and have built 313 releases.  We have had almost no image failures due to forgetting to put something in the image, or some other manual step you tend to find in build systems.  This is the power of a fully automated build system with _no_ manual steps.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ubuntu&quot;&gt;Ubuntu&lt;&#x2F;h3&gt;
&lt;p&gt;Once I become convinced that Ubuntu could do distro upgrades, I finally quit using Gentoo.  Between servers, workstations, and home computers, I now maintain about 10 Ubuntu systems.  Over the past several years, I’ve had very few problems using the distro upgrade mechanism.  Also, the fact that Ubuntu includes fairly recent Linux technology is a big plus for experimenting with components I use in embedded Linux systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dhl-ups-pickup&quot;&gt;DHL&#x2F;UPS Pickup&lt;&#x2F;h3&gt;
&lt;p&gt;Working from a small office where I do not regularly make shipments, it is really convenient to be able to schedule a pickup with shipping companies like DHL and UPS.   This can be done over the web in 15 minutes or so, and a shipping label then prints out on your printer.  The DHL website will also provide commercial invoices for overseas shipping.  This sure beats driving to the local UPS shipping place, filling out paper work with a pen, waiting in line, etc.  Just another thing that makes it easier for a small business to run efficiently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;intel-bare-bones-server&quot;&gt;Intel Bare Bones Server&lt;&#x2F;h3&gt;
&lt;p&gt;Last year, I was looking for a cost effective 1U rack server.  I selected a Intel SR1530 Bare Bones server.  I installed it over a year ago and have not touched it since.  Last time I checked, the uptime was 254 days.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-ware-raid-controllers&quot;&gt;3-ware Raid Controllers&lt;&#x2F;h3&gt;
&lt;p&gt;(I guess it is AMCC now …) They just work with Linux – currently running in two systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sandusky-cabinets&quot;&gt;Sandusky Cabinets&lt;&#x2F;h3&gt;
&lt;p&gt;Doing embedded system development means I get a lot of equipment from customers.  As some of the development stretches over several years with occasional ongoing support, its nice to be able to store this equipment and then find it efficiently. I’ve found the “Sandusky Standard Storage Cabinets” from Staples to work very well.  They are fairly cheap, yet durable enough for what I need, and keeps everything enclosed which looks neat, and keeps the dust problem under control.  And, Staples offers free delivery.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bob-pease-organization-system&quot;&gt;Bob Pease organization system&lt;&#x2F;h3&gt;
&lt;p&gt;Bob Pease had an &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;electronicdesign.com&#x2F;Articles&#x2F;Index.cfm?ArticleID=5385&quot;&gt;article&lt;&#x2F;a&gt; in Electronic Design some time ago about organizing things in his refrigerator.  He used small boxes to group things in his refrigerator.  I use the same method in my Sandusky cabinets and it makes it very easy to find something when I need it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_1-1.jpg&quot; alt=&quot;work_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gtd-labeling-system&quot;&gt;GTD Labeling System&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve slowing been adopting some of David Allen’s organization ideas from “Getting Things Done”.  One of his best ideas is to get a labeller.  I used to use a Brother handheld labeller, but lately, I’ve been using a Dymo LabelWriter 400 left over from a project.  The LabelWriter connects to your computer via USB, works well with Linux, and allows me to use my standard keyboard, and OpenOffice to create labels.  Note, the labels on the boxes in the above picture.  The high contrast black on white makes it much easier to find things versus hand writing notes on cardboard boxes, file folders, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gtd-filing-system&quot;&gt;GTD Filing System&lt;&#x2F;h3&gt;
&lt;p&gt;I used to use hanging file folders, but no more.  David Allen’s suggestion of simply using plain manila file folders with nice labels works very well. Once again the large, high contrast labels makes it easy to find things.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_2-1.jpg&quot; alt=&quot;work_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;snaketray-cable-management&quot;&gt;Snaketray Cable Management&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve already written about &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;73&#x2F;9&#x2F;&quot;&gt;my cable management system&lt;&#x2F;a&gt;.  A year later, I still like it and no longer dread digging through cables.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;steelcase-leap-chair&quot;&gt;Steelcase Leap Chair&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve sat in various chairs over the years – mostly the cheap office store variety that most companies buy. I must be getting old enough now that they no longer cut it.  I tried a Herman Miller Aeron for a week as that is what everyone recommends, but I found it too hard.  I then tried a Steelcase Leap chair and it works great for me.  I no longer even think about the chair I’m sitting in, even after a long day.  Expensive, but well worth it if you spend as much time sitting as I do.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tomboy-notes-gnome-do&quot;&gt;Tomboy Notes + gnome-do&lt;&#x2F;h3&gt;
&lt;p&gt;Tomboy notes is a Linux desktop note-taking application that is essentially a personal wiki.  It automatically tracks links to other pages, links to file locations, etc and organization is done mostly through links instead of hierarchy.  It is simply the best note taking system I have ever used.  Coupled with gnome-do, I can instantly bring up any note with only a few keystrokes.  In this day and age where information abounds, being able to take and recall notes efficiently is critical to being effective.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;konsole&quot;&gt;Konsole&lt;&#x2F;h3&gt;
&lt;p&gt;Being able to easily name the tabs in the KDE console application is very handy as I’ll typically have 5-10 named consoles going at one time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_3-1.png&quot; alt=&quot;work_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;8-port-usb-serial-expander&quot;&gt;8-port USB serial expander&lt;&#x2F;h3&gt;
&lt;p&gt;As I work with a lot of different devices, it is very handy to have lots of serial ports available.  The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.usbgear.com&#x2F;USB2-8COM-M.html&quot;&gt;SerialGear device&lt;&#x2F;a&gt; available from http:&#x2F;&#x2F;www.usbgear.com works out of the box with modern Linux distributions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;work_4-1.jpg&quot; alt=&quot;work_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;git&quot;&gt;Git&lt;&#x2F;h3&gt;
&lt;p&gt;I’m starting to really appreciate the benefits of distributed source control systems.  For commercial embedded development, it allows me to easily track upstream projects, yet have a local source control system for tracking project changes.  Having everything in one version control system makes it much easier to extract patches to push back upstream, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;redmine&quot;&gt;Redmine&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve been a happy &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;trac.edgewall.org&#x2F;&quot;&gt;trac&lt;&#x2F;a&gt; user for years, but have recently switched to using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.redmine.org&#x2F;&quot;&gt;Redmine&lt;&#x2F;a&gt; for project management.  Redmine offers some addition features such as multiple project support, and the user interface is a little more polished.  As all of my projects are accomplished with distributed teams, it is very important that there be clear visibility as to what is going on in the project.  It also helps to give customers the “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.unixwiz.net&#x2F;techtips&#x2F;be-consultant.html&quot;&gt;Warm Fuzzy Feeling&lt;&#x2F;a&gt; TM” as they have clear visibility into the project, and they can easily verify there is progress being made on the project.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Benefits of OpenEmbedded switching to Git</title>
        <published>2008-10-22T00:00:00+00:00</published>
        <updated>2008-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/"/>
        <id>https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/</id>
        
        <content type="html" xml:base="https://bec-systems.com/216/benefits-of-openembedded-switching-to-git/">&lt;p&gt;Recently the OpenEmbedded project has switched to the Git version control system.  This is good news for many reasons.  The obvious reasons are Git is faster than Monotone, handles branching better, has lots of nice features, larger user base, etc.  Monotone has served us well, but as new tools become available, it is time to change.  For those of us helping customers use OE for embedded projects, Git will make using OE much easier.  Companies want to be able to track OE with minimal effort and typically maintain a few minor tweaks to OE.  As most Embedded Linux projects now implement Git infrastructure for kernel development, the OE source tree can be maintained using the same infrastructure.  Branching is very natural in Git, so it is fairly easy to create a OE “topic branch” and periodically merge with upstream changes as needed.  The ability for easy repo hosting and branching allows OE users to lock down a version of OE for periods of project development, and still maintain a connection to the upstream OE repository for easily updating to new versions, or cherrypicking changes.  So a big thank you to all who helped make this change happen.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>more fun with git branches</title>
        <published>2008-08-26T00:00:00+00:00</published>
        <updated>2008-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/213/more-fun-with-git-branches/"/>
        <id>https://bec-systems.com/213/more-fun-with-git-branches/</id>
        
        <content type="html" xml:base="https://bec-systems.com/213/more-fun-with-git-branches/">&lt;p&gt;One thing you learn after using git for awhile is you get used to trying random things, and it will often just work.  For example, if I want to know the differences between Linus’s kernel tree, and the Wolfson dev branch for a particular directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cbrake@happy:&#x2F;build&#x2F;linux-2.6$ git diff --stat origin&#x2F;master..wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs
 sound&#x2F;soc&#x2F;codecs&#x2F;Kconfig       |  125 +++
 sound&#x2F;soc&#x2F;codecs&#x2F;Makefile      |   34 +
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1939.c      |  690 +++++++++++++++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1939.h      |   70 ++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1980.c      |  309 +++++++
 sound&#x2F;soc&#x2F;codecs&#x2F;ad1980.h      |   23 +
 sound&#x2F;soc&#x2F;codecs&#x2F;cs4251x.c     |  771 +++++++++++++++++
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another way to get similar information is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log origin&#x2F;master..wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If I’m working on a topic branch, and I want to see a summary of all the changes in my Topic branch:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log --stat origin&#x2F;master..origin&#x2F;my_topic_branch &amp;gt; my_topic_branch_changelog.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One of the neat things about git branches is you don’t have to be on a branch to interact with it.  You can diff, log, and checkout from branches other than the one you are currently in, and it is all very fast.  For instance, if I want to grab the latest copy of a file in the Wolfson dev branch, I can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git log checkout wolfson&#x2F;dev sound&#x2F;soc&#x2F;codecs&#x2F;wm9713.c
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not that this is a very good idea, but just to illustrate a point.  Git branches are amazing and make development work so much less tedious.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux Input Testing and Debugging</title>
        <published>2008-08-22T00:00:00+00:00</published>
        <updated>2008-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/209/linux-input-testing-and-debugging/"/>
        <id>https://bec-systems.com/209/linux-input-testing-and-debugging/</id>
        
        <content type="html" xml:base="https://bec-systems.com/209/linux-input-testing-and-debugging/">&lt;p&gt;The Linux input layer has made a lot of progress in recent years.  When writing a new input driver (such as keyboard, trackball, etc), it is useful to be able to monitor input events using a test application.  This article describes two ways to accomplish this using kernel input debugging, and the evtest utility.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kernel-input-debugging&quot;&gt;kernel input debugging&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux kernel includes some support for printing input events as debug messages.  To use, set the following in the kernel config:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_INPUT_EVBUG=y
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because the print messages are at the KERN_DEBUG level (7), we typically need to change the debug level:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;echo 8 &amp;gt; &#x2F;proc&#x2F;sys&#x2F;kernel&#x2F;printk
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, you will see messages like the following on the console:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 108, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 106, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 1, Code: 103, Value: 1
evbug.c: Event. Dev: gpio-keys&#x2F;input0, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 1
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 1
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 1, Code: 6, Value: 0
evbug.c: Event. Dev: &amp;lt;NULL&amp;gt;, Type: 0, Code: 0, Value: 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;evtest&quot;&gt;evtest&lt;&#x2F;h3&gt;
&lt;p&gt;The linux-input project (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxconsole.sourceforge.net&#x2F;input&#x2F;input.html&quot;&gt;http:&#x2F;&#x2F;linuxconsole.sourceforge.net&#x2F;input&#x2F;input.html&lt;&#x2F;a&gt;) includes a neat little tool named evtest that is very handy for testing input devices.  If you are using OpenEmbedded, simply:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bitbake linux-input
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you are not using OpenEmbedded, you can glean enough details about how to get and build the this package from the OE recipe:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gitweb.openembedded.net&#x2F;?p=org.openembedded.dev.git;a=blob;f=packages&#x2F;linux-input&#x2F;linux-input_cvs.bb&quot;&gt;http:&#x2F;&#x2F;gitweb.openembedded.net&#x2F;?p=org.openembedded.dev.git;a=blob;f=packages&#x2F;linux-input&#x2F;linux-input_cvs.bb&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Install the resulting package on your device.   To use, run evtest with a &#x2F;dev&#x2F;input&#x2F;eventx argument:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@machine1:~$ evtest &#x2F;dev&#x2F;input&#x2F;event0
Input driver version is 1.0.0
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: &amp;quot;gpio-keys&amp;quot;
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 103 (Up)
    Event code 105 (Left)
    Event code 106 (Right)
    Event code 108 (Down)
    Event code 116 (Power)
Testing ... (interrupt to exit)
Event: time 1009.433605, type 1 (Key), code 108 (Down), value 0
Event: time 1009.433737, -------------- Report Sync ------------
Event: time 1010.735605, type 1 (Key), code 108 (Down), value 1
Event: time 1010.735740, -------------- Report Sync ------------
Event: time 1011.075586, type 1 (Key), code 106 (Right), value 1
Event: time 1011.075720, -------------- Report Sync ------------
Event: time 1011.103379, type 1 (Key), code 108 (Down), value 0
Event: time 1011.103550, -------------- Report Sync ------------
Event: time 1011.333924, type 1 (Key), code 108 (Down), value 1
Event: time 1011.334058, -------------- Report Sync ------------
Event: time 1011.339880, type 1 (Key), code 106 (Right), value 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that evtest lists the keymap when it is initially run which is very handy, and then lists key events as they occur.  The key descriptions are also included with events so you don’t have to manually decode the keycodes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using a Verizon USB720 modem in an Embedded Linux system</title>
        <published>2008-06-02T00:00:00+00:00</published>
        <updated>2008-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/"/>
        <id>https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/</id>
        
        <content type="html" xml:base="https://bec-systems.com/203/using-a-verizon-usb720-modem-in-an-embedded-linux-system/">&lt;p&gt;&lt;img src=&quot;file:&#x2F;&#x2F;&#x2F;tmp&#x2F;moz-screenshot.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Verizon USB720 Cellular modem is a quick and easy way to add wireless internet connectivity to your embedded system.  Why might you want to add cellular  connectivity to your embedded device?  Remote access and diagnostics is a big reason.  One customer I have is planning to supply all their distributors with a USB720 so they can easily upload log files from devices in the field.  The alternative is copying the log files to a flash drive, finding a PC connected to the internet, and then uploading the files – too much hassle, therefore it does not get done.  Also, think about the cost of sending a field support person on-site to troubleshoot problems versus shipping them a USB720 and accessing the device remotely.&lt;&#x2F;p&gt;
&lt;p&gt;The USB720 is a fairly small device that plugs into the ubiquitous USB port.  This articles covers some of the details on how to configure an embedded Linux system to work with this device.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-is-the-usb720-a-good-fit-for-wireless-connectivity-in-embedded-systems&quot;&gt;Why is the USB720 a good fit for wireless connectivity in Embedded Systems?&lt;&#x2F;h3&gt;
&lt;p&gt;Some reasons the USB720 (or other USB based cellular modems) is an attractive option:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;fairly fast: provides typical download speeds of 600-1400kbps, and upload speeds of 500-800kbps&lt;&#x2F;li&gt;
&lt;li&gt;convenience: it plugs into a USB port.  No taking apart the box and installing an embedded module, etc.&lt;&#x2F;li&gt;
&lt;li&gt;affordable: with plans around $60&#x2F;mo, its a lot cheaper than sending field support people on-site to debug every problem.&lt;&#x2F;li&gt;
&lt;li&gt;uses standard PPP protocols for connection.  That means it works with Linux.&lt;&#x2F;li&gt;
&lt;li&gt;supported by the mainstream Linux kernel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;usb720_a-1.jpg&quot; alt=&quot;usb720_a&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kernel-configuration&quot;&gt;Kernel Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;The USB720 looks like a USB-serial device to the host system.  If you plug it into your Ubuntu desktop Linux system, all the needed kernel pieces are there and it will just work.  With your embedded system, you need to make sure a number of kernel options are enabled including:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_PPP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_DEFLATE=m
CONFIG_SLHC=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_OPTION=m
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The CONFIG_USB_SERIAL_OPTION selection enables a driver that is specifically optimized to work with the USB chip found in many cellular modems.  Once you enable the above modules, and if you are running udev, simply plugging in the device will cause the appropriate modules to load and a &#x2F;dev&#x2F;ttyUSB0 device will now appear.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ppp-scripts&quot;&gt;PPP Scripts&lt;&#x2F;h3&gt;
&lt;p&gt;The most difficult part of this exercise is figuring out how to configure the PPP scripts.  Verizon of course does not tell you how to configure their device and only supplies software for Windows and MAC.  There are a number of howtos available on the internet, but most of them are tailored to using kppp or wvdial. Neither are very practical for embedded systems. Fortunately, the standard pppd daemon is fairly easy to use, is easy to build for embedded systems (it is already included in OpenEmbedded), and seems to work very well.  The following scripts are needed:&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;noauth
connect &amp;quot;&#x2F;usr&#x2F;sbin&#x2F;chat -v -f &#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_chat&amp;quot;
defaultroute
usepeerdns
ttyUSB0
921600
local
usepeerdns
debug
-detach
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;peers&#x2F;verizon_chat&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#39;&amp;#39; &amp;#39;ATZ&amp;#39;
&amp;#39;OK&amp;#39; &amp;#39;ATDT#777&amp;#39;
&amp;#39;CONNECT&amp;#39; &amp;#39;&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;ppp&#x2F;chap-secrets
&#x2F;etc&#x2F;ppp&#x2F;pap-secrets&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;&amp;lt;phone number&amp;gt;@vzw3g.com&amp;quot;  *       &amp;quot;vzw&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, you can run &lt;em&gt;pppd call verizon&lt;&#x2F;em&gt; and you should see something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; root@cm-x270:~$ pppd call verizon
Serial connection established.
using channel 9
Using interface ppp0
Connect: ppp0 &amp;lt;--&amp;gt; &#x2F;dev&#x2F;ttyUSB0
Warning - secret file &#x2F;etc&#x2F;ppp&#x2F;pap-secrets has world and&#x2F;or group access
sent [LCP ConfReq id=0x1 &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0x539657b7&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
rcvd [LCP ConfReq id=0x0 &amp;lt;mru 1500&amp;gt; &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0xb9b652e5&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
sent [LCP ConfAck id=0x0 &amp;lt;mru 1500&amp;gt; &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0xb9b652e5&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
rcvd [LCP ConfAck id=0x1 &amp;lt;asyncmap 0x0&amp;gt; &amp;lt;magic 0x539657b7&amp;gt; &amp;lt;pcomp&amp;gt; &amp;lt;accomp&amp;gt;]
sent [CCP ConfReq id=0x1 &amp;lt;deflate 15&amp;gt; &amp;lt;deflate(old#) 15&amp;gt;]
sent [IPCP ConfReq id=0x1 &amp;lt;compress VJ 0f 01&amp;gt; &amp;lt;addr 192.168.1.119&amp;gt; &amp;lt;ms-dns1 0.0.0.0&amp;gt; &amp;lt;ms-dns3 0.0.0.0&amp;gt;]
rcvd [LCP DiscReq id=0x1 magic=0xb9b652e5]
rcvd [LCP ProtRej id=0x2 80 fd 01 01 00 0c 1a 04 78 00 18 04 78 00]
rcvd [IPCP ConfReq id=0x0 &amp;lt;addr 66.174.61.4&amp;gt;]
sent [IPCP ConfAck id=0x0 &amp;lt;addr 66.174.61.4&amp;gt;]
rcvd [IPCP ConfRej id=0x1 &amp;lt;compress VJ 0f 01&amp;gt;]
sent [IPCP ConfReq id=0x2 &amp;lt;addr 192.168.1.119&amp;gt; &amp;lt;ms-dns1 0.0.0.0&amp;gt; &amp;lt;ms-dns3 0.0.0.0&amp;gt;]
rcvd [IPCP ConfNak id=0x2 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
sent [IPCP ConfReq id=0x3 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
rcvd [IPCP ConfAck id=0x3 &amp;lt;addr 70.210.82.191&amp;gt; &amp;lt;ms-dns1 66.174.95.44&amp;gt; &amp;lt;ms-dns3 66.174.92.14&amp;gt;]
not replacing default route to eth0 [192.168.1.1]
local  IP address 70.210.82.191
remote IP address 66.174.61.4
primary   DNS address 66.174.95.44
secondary DNS address 66.174.92.14
Script &#x2F;etc&#x2F;ppp&#x2F;ip-up started (pid 2303)
Script &#x2F;etc&#x2F;ppp&#x2F;ip-up finished (pid 2303), status = 0x0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ ifconfig
ppp0      Link encap:Point-to-Point Protocol
          inet addr:70.210.82.191  P-t-P:66.174.61.4  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:64 (64.0 B)  TX bytes:94 (94.0 B)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You are connected :-)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-the-oe-ppp-package&quot;&gt;Using the OE ppp package&lt;&#x2F;h3&gt;
&lt;p&gt;Add ppp support to your image using OE is fairly straightfoward:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;add the kernel modules to your image&lt;&#x2F;li&gt;
&lt;li&gt;add&lt;em&gt;ppp&lt;&#x2F;em&gt; to your image&lt;&#x2F;li&gt;
&lt;li&gt;add a custom package that includes the configuration scripts listed above&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One thing that may trip you up is the ppp scripts are expecting resolv.conf to be in the following location: &#x2F;var&#x2F;run&#x2F;resolv.conf.  The reason for this is we want resolv.conf in a RAM file system to prevent unneeded flash wear.  Therefore, &#x2F;etc&#x2F;resolv.conf should be configured in your rootfs as a soft link to &#x2F;var&#x2F;run&#x2F;resolv.conf.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux kernel support for USB720 and the pppd package offer a quick, robust way to add cellular network connectivity to about any embedded Linux system that has a USB host port.  As systems become more complex, it will be increasingly important to be able to remotely access systems in the field to troubleshoot problems, help users with configuration, etc.  The USB720 offers a quick way to provide this type of connection without going through the expense of designing cellular connectivity into your product.  One thing I usually encourage all my customers to do when designing new products is expose a USB host port, even though they may not see any immediate use for it.  This is one of those reasons.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a picture of a USB720 connected to a Compulab cm-x270 development system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;usb720_b-1.jpg&quot; alt=&quot;usb720_b&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Autotools quick reference</title>
        <published>2008-05-03T00:00:00+00:00</published>
        <updated>2008-05-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/121/autotools-quick-reference/"/>
        <id>https://bec-systems.com/121/autotools-quick-reference/</id>
        
        <content type="html" xml:base="https://bec-systems.com/121/autotools-quick-reference/">&lt;p&gt;At some point, most Linux developers need to master Autotools.  For most of us, this is a fairly painful process, but like any good tool, Autotools is extremely useful and well worth learning.  For example, if your program is set up correctly using Autotools, it will cross compile with almost zero effort in OpenEmbedded, or with slight effort manually.  Compare this to the tedious effort of manually referencing toolchain locations, cross toolchain library and header file locations, etc.  Despite first impressions, Autotools will make your life easier.  This article contains a collection of tips on how to do standard operations using Autotools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimal-autotools-files-required-for-a-simple-c-application&quot;&gt;Minimal Autotools files required for a simple C application&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_INIT([fooprog], [1.0], [email@company.com])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC

AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bin_PROGRAMS = foo
foo_SOURCES = foo.c
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above files will create a binary name foo (compiled from foo.c) when you run the following steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;touch NEWS AUTHORS ChangeLog&lt;&#x2F;li&gt;
&lt;li&gt;autoreconf -i&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure&lt;&#x2F;li&gt;
&lt;li&gt;make&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;how-to-add-libraries-to-the-link-step&quot;&gt;How to add libraries to the link step&lt;&#x2F;h2&gt;
&lt;p&gt;For example, if you want to link in the pthread library to your application, add the following line to Makefile.am:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo_LDADD = -lpthread
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-add-compiler-options&quot;&gt;How to add compiler options&lt;&#x2F;h2&gt;
&lt;p&gt;You can easily add compiler options using the foo_CFLAGS or foo_CPPFLAGS variables.&lt;&#x2F;p&gt;
&lt;p&gt;foo_CFLAGS = -DMY_DEFINE&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-use-pkg-config-in-autotools&quot;&gt;How to use pkg-config in Autotools&lt;&#x2F;h2&gt;
&lt;p&gt;pkg-config is a helper tool that gives you library and include file information for various libraries installed.  For example, to link to alsa and glib in your project:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PKG_CHECK_MODULES(PACKAGE, alsa glib-2.0)
AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAG_LIBS)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;foo_CFLAGS = @PACKAGE_CFLAGS@
foo_LDADD = @PACKAGE_LIBS@
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-add-a-command-line-option-to-the-configure-script&quot;&gt;How to add a command line option to the configure script&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;AC_ARG_ENABLE(option-foo,
    [  --enable-option-foo  help for option foo],
    [CFLAGS=&amp;quot;$CFLAGS -DOPTION_FOO_DEFINE&amp;quot;], [])
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above example sets a define on the compiler command line if configure is run with the &lt;em&gt;--enable-option-foo&lt;&#x2F;em&gt; command line option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disable-shared-libraries-in-your-project&quot;&gt;Disable shared libraries in your project&lt;&#x2F;h2&gt;
&lt;p&gt;Add the following to configure.ac:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_DISABLE_SHARED
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;pass-a-variable-from-configure-ac-to-makefile-am&quot;&gt;Pass a variable from configure.ac to Makefile.am&lt;&#x2F;h2&gt;
&lt;p&gt;Often there is a need to pass a variable in configure.ac to a Makefile.  This is done with the AC_SUBST macro:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;configure.ac&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AC_SUBST(VAR_FOO)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;foo2 = @VAR_FOO@&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-data-files&quot;&gt;Installing data files&lt;&#x2F;h2&gt;
&lt;p&gt;By default, Autotools will install executables built when you run “make install”.  To install other non-executable files, you need to tell autotools explicitly about those files.  The standard place to install data files for an application is in $(datadir)&#x2F;appname.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;fooextradir = $(datadir)&#x2F;@PACKAGE@
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;fooextra_DATA = \
	foo_data1.txt \
	foo_data2.txt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above will install the &lt;em&gt;foo_data1.txt&lt;&#x2F;em&gt; and &lt;em&gt;foo_data2.txt&lt;&#x2F;em&gt; files in the &lt;em&gt;$(datadir)&#x2F;fooprog&lt;&#x2F;em&gt; directory. $(datadir) is typically &#x2F;usr&#x2F;share&#x2F; or &#x2F;usr&#x2F;local&#x2F;share, but it can be anything.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-my-program-know-where-datadir-is-located&quot;&gt;How does my program know where $(datadir) is located&lt;&#x2F;h2&gt;
&lt;p&gt;Because $(datadir) can be anywhere in the system, we need some way to tell the program where it was specified to be at time of compilation so that it can locate foo_data1.txt and foo_data2.txt.  This can be done by passing a define at compile time:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Makefile.am&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;AM_CFLAGS = -DDATADIR=\&amp;quot;$(datadir)\&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-to-install-data-files-during-development-without-cluttering-up-my-system-directories&quot;&gt;How to install data files during development without cluttering up my system directories&lt;&#x2F;h2&gt;
&lt;p&gt;If you use the above method to install data files needed by your project, you may run into a case during development where you want to run the program from the build directory, but the program needs the data files at run time.  Since, the program is looking for them in the location specified by the DATADIR define, they need to be installed.  You could just run “make install”, but this would install them into &#x2F;usr&#x2F;local&#x2F;share, require you to run as root, and clutter up your system directories.  A much more elegant solution is to specify the install prefix at configure time to be a temporary “install” directory in your source tree.  The --prefix option for configure requires an absolute directory, so the `pwd` trick is used to figure out what the current directory is.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;.&#x2F;configure --prefix=`pwd`&#x2F;install
make install
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your project will now be installed in a directory in your source tree named .&#x2F;install.  This is also a nice way to test that the install for the project is working correctly as you can easily see everything that gets installed.  Now, the program has been compiled to reference extra files in .&#x2F;install and will run just fine from the build directory.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Linux kernel container_of macro</title>
        <published>2008-04-02T00:00:00+00:00</published>
        <updated>2008-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/115/the-linux-kernel-container_of-macro/"/>
        <id>https://bec-systems.com/115/the-linux-kernel-container_of-macro/</id>
        
        <content type="html" xml:base="https://bec-systems.com/115/the-linux-kernel-container_of-macro/">&lt;p&gt;The Linux kernel contains a very useful macro named “container_of” that is used extensively in back-casting a data structure to its containing data structure.  This article includes a simple program that illustrates how this macro is used, and explains why it is so useful.&lt;&#x2F;p&gt;
&lt;p&gt;If you do a lot of C programming, this program is worth figuring out :-).&lt;&#x2F;p&gt;
&lt;p&gt;The program source can also be downloaded from the following location: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;svn&#x2F;pub&#x2F;container_of&#x2F;linux_container_of_example.c&quot;&gt;&#x2F;linux&#x2F;linux_container_of_example.c&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* test code to illustrate use of Linux kernel container_of macro
 *
 * Copyright (c) 2008 Cliff Brake, BEC Systems LLC
 *
 * This program is free software; you can redistribute it and&#x2F;or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *&#x2F;

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

&#x2F;* This program illustrates how the container_of macro works.
 * The container of macro is very useful in multi layered
 * software systems where you have progressivly more detailed
 * software layers.  Below is an example of a bus layer,
 * and then a device layer where a number of different
 * devices might register with the bus.
 * The device registers itself with the bus subsystem, and
 * then the bus subsystem makes a callback into the device.
 * Normally if there are multiple devices registered, the
 * bus subsystem must store and pass a device structure
 * when making callbacks.  With the container_of macro, this is
 * no longer necessary, and the bus subsystem only has to
 * know about one generic device structure, and does not need visibility
 * into lots of different device structures, or do tricks
 * by casting void pointers, etc.  With the container_of macro
 * we can backcast from the generic data structure, to the containing
 * datastructure.  This forces good separation of code in that
 * that bus layer cannot modifiy data structures that are specific
 * to the device layer.
 *
 *&#x2F;

&#x2F;**
 * (from Linux kernel source)
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:	the pointer to the member.
 * @type:	the type of the container struct this is embedded in.
 * @member:	the name of the member within the struct.
 *
 *&#x2F;
#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)-&amp;gt;member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &amp;amp;((TYPE *)0)-&amp;gt;MEMBER)

&#x2F;*==========================================================
 * BUS layer code
 *==========================================================*&#x2F;

&#x2F;* generic bus device structure *&#x2F;
struct bus_device
{
	int general_device_param_a;
	int general_device_param_b;
	void (*device_callback)(struct bus_device * bd);
};

&#x2F;* the following is a global list of
 * devices that have registered with the
 * bus subsystem.  Normally this would
 * be something like a dynamic linked list.
 *&#x2F;
struct bus_device * bd_list[5];

&#x2F;* function to register a device with the bus *&#x2F;
void register_with_bus(struct bus_device * bd)
{
	&#x2F;* since this example only deals with one
	 * device, will put it in slot 0
	 *&#x2F;

bd_list[0] = bd;
}

void start_bus()
{
	int i;
	struct bus_device * bd;

&#x2F;* make callbacks to all devices on bus *&#x2F;
	for (i=0;i&amp;lt;sizeof(bd_list)&#x2F;sizeof(bd_list[0]);i++) {
		bd = bd_list[i];
		if (!bd) continue;
		&#x2F;* call device callback with generic
		 * bus device structure
		 *&#x2F;
		bd-&amp;gt;device_callback(bd);
	}
}

&#x2F;*==========================================================
 * device X specific code
 * this would normally be in a different module
 *==========================================================*&#x2F;

&#x2F;* structure that holds device X specific stuff, as well as
 * generic bus_device structure
 *&#x2F;
struct device_x
{
	int device_x_specific_param_a;
	int device_x_specific_param_b;
	struct bus_device bd;
};

void device_x_callback(struct bus_device * bd)
{
	&#x2F;* if we know the structure type that contains the bus_device structure,
	 * we can extract a pointer to the containing structure using the container_of
	 * macro
	 *&#x2F;

&#x2F;*                                   ptr       type       member  *&#x2F;
	struct device_x * devx = container_of(bd, struct device_x, bd);

&#x2F;* the above statement expands to
	 * struct device_x * devx = (
	 * {
	 *   const typeof( ((struct device_x *)0)-&amp;gt;bd ) *__mptr = (bd);
	 *   (struct device_x *)( (char *)__mptr - ((size_t) &amp;amp;((struct device_x *)0)-&amp;gt;bd) );
	 * }
	 * );
	 *&#x2F;

printf(&amp;quot;device_x_callback called!, device_x_specific_param_a = %i\n&amp;quot;,
			devx-&amp;gt;device_x_specific_param_a);
}

void device_x_init()
{
	&#x2F;* dynamically allocate structures *&#x2F;
	struct device_x * devx = malloc(sizeof(*devx));
	memset(devx, 0, sizeof(*devx));

&#x2F;* set a parameter in the device_x structure so
	 * we can test for this in the callback
	 *&#x2F;
	devx-&amp;gt;device_x_specific_param_a = 1001;

&#x2F;* set up callback function *&#x2F;
	devx-&amp;gt;bd.device_callback = device_x_callback;

&#x2F;* we register the generic bus device structure
	 * as the bus layer does not need to know
	 * about the device_x stucture.  Note, the
	 * devx structure is not stored anywhere, yet
	 * its location is being preserved without
	 * specifically passing it to the bus
	 * layer.
	 *&#x2F;
	register_with_bus(&amp;amp;devx-&amp;gt;bd);
}

int main()
{

&#x2F;* test the above system *&#x2F;

&#x2F;* first, initialize device_x *&#x2F;
	device_x_init();

&#x2F;* now, start the bus.  This should make
	 * a callback into the device_x
	 *&#x2F;
	start_bus();
}

&#x2F;* when run, this program returns:
 * device_x_callback called!, device_x_specific_param_a = 1001
 *&#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Should you be using monotonic timers?</title>
        <published>2008-03-19T00:00:00+00:00</published>
        <updated>2008-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/201/should-you-be-using-monotonic-timers/"/>
        <id>https://bec-systems.com/201/should-you-be-using-monotonic-timers/</id>
        
        <content type="html" xml:base="https://bec-systems.com/201/should-you-be-using-monotonic-timers/">&lt;p&gt;In a &lt;a href=&quot;&#x2F;175&#x2F;how-to-implement-realtime-periodic-tasks-in-linux-applications&#x2F;&quot;&gt;previous article&lt;&#x2F;a&gt;, I covered some of the basics of Linux timers.  Any time you are doing any type of fixed time delay in a program, you should really be using monotonic times, so the delay will not be affected by system time changes.  In an effort to save cost, some embedded systems today do not have a battery backed up RTC, and instead get the time via GPS, NTP servers, or other clever means.  What this means is your applications had better be able to handle the system time changing as the system time may not be set until well after the unit boots.  This article describes how you can quickly test your system for timer problems.&lt;&#x2F;p&gt;
&lt;p&gt;There are two cases where delays may fail if you are using non-monotonic timers.  The first is if the time advances forward by a large amount.  Delays will expire immediately in this case.  The other case is if the time advances backward by a large amount.  Delays will never expire in this case.  To test for these situations, write a simple test application (sample included below) that rapidly changes the time and then test your application while the time is changing.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main()
{
  time_t system_time;
  static int count = 0;

printf(&amp;quot;Starting test application...\n&amp;quot;);
  while(1)
  {
    &#x2F;&#x2F; Sleep for 0.01 seconds
    usleep(10 * 1000);

system_time = time(NULL);
    system_time += 30;
    stime(&amp;amp;system_time);
    printf(&amp;quot;Cycle %d - system date&#x2F;time set to %s&amp;quot;, ++count, ctime(&amp;amp;system_time));
  }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 kernel update to 2.6.24</title>
        <published>2008-02-29T00:00:00+00:00</published>
        <updated>2008-02-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/"/>
        <id>https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/</id>
        
        <content type="html" xml:base="https://bec-systems.com/199/compulab-cm-x270-kernel-update-to-2624/">&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.24&#x2F;cm-x270&quot;&gt;kernel support&lt;&#x2F;a&gt; in OpenEmbedded for the Compulab cm-x270 has been updated to version 2.6.24.  The 2.6.24 kernel opens up several possibilities including better real time and &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;199&#x2F;compulab-cm-x270-kernel-update-to-2624&#x2F;content&#x2F;view&#x2F;78&#x2F;9&#x2F;&quot;&gt;high resolution timer&lt;&#x2F;a&gt; functionality, an improved SD Card driver, and a full SDIO stack with support for &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;199&#x2F;compulab-cm-x270-kernel-update-to-2624&#x2F;content&#x2F;view&#x2F;89&#x2F;9&#x2F;&quot;&gt;SDIO Wifi devices&lt;&#x2F;a&gt;.  Also included is a patch to set the default framebuffer depth to 16 for several commonly used displays.  Xfbev really does not like when you give it a 8-bit framebuffer when it is expecting 16, and typically returns a very unhelpful error message like: “error: Invalid argument”.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GESBC-9302E kernel update to 2.6.24, and reboot fix</title>
        <published>2008-02-18T00:00:00+00:00</published>
        <updated>2008-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/"/>
        <id>https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/</id>
        
        <content type="html" xml:base="https://bec-systems.com/111/gesbc-9302e-kernel-update-to-2624-and-reboot-fix/">&lt;p&gt;I recently updated the GESBC-9302 machine support in OpenEmbedded to include the 2.6.24 released kernel.  Also, Glomation has kindly provided me with a patch for the software reboot problem which I have integrated into the OpenEmbedded build for the GESBC.   The patch files are part of the OpenEmbedded dev branch or can be obtained here:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-2.6.24&#x2F;gesbc-9302&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux-2.6.24&#x2F;gesbc-9302&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Other related OpenEmbedded bits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux_2.6.24.bb&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;recipes&#x2F;linux&#x2F;linux_2.6.24.bb&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;conf&#x2F;machine&#x2F;gesbc-9302.conf&quot;&gt;http:&#x2F;&#x2F;cgit.openembedded.net&#x2F;cgit.cgi?url=openembedded&#x2F;tree&#x2F;conf&#x2F;machine&#x2F;gesbc-9302.conf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Future features to be integrated include RTC driver configuration, and support for loading Initramfs images from NOR flash.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Glomation GESBC-9302E Review</title>
        <published>2008-01-29T00:00:00+00:00</published>
        <updated>2008-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/107/glomation-gesbc-9302e-review/"/>
        <id>https://bec-systems.com/107/glomation-gesbc-9302e-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/107/glomation-gesbc-9302e-review/">&lt;p&gt;Recently, I’ve had the opportunity to work with a Glomation GESBC-9302E single board computer.  This SBC contains a Cirrus Logic EP9302 ARM processor and options for plenty of RAM and Flash memory which means you have many options for writing your applications including high level languages like C# and Python.  In this review, I’ll cover some of basic features of this board and where this board might be useful.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-the-gesbc-9302&quot;&gt;Why the GESBC-9302?&lt;&#x2F;h3&gt;
&lt;p&gt;One of the most attractive features of the GESBC-9302E is cost.  The base model with 32MB of RAM, and no NAND flash costs $95 at quantities of 1 unit.  For a model with 64MB of RAM, and 128MB of flash, the cost is $120.  Looking at the board, its simplicity is very evident.  There is basically a CPU, flash, ram, a few linear power supplies, and a very limited amount of support circuitry.  There really is not much to it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;gesbc_9302e_1-1.jpg&quot; alt=&quot;gesbc_9302e_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We are helping a customer use the GESBC-9302E in a project where it is functioning as a gateway between a local Zigbee wireless network, and a server located on the internet.  The customer had originally considered using a Linksys NSLU2 for the gateway device during the alpha testing, but upon consideration it seemed like the GESBC-9302E is a better choice in this application for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the GESBC does not cost a lot more than a NSLU2&lt;&#x2F;li&gt;
&lt;li&gt;you can buy the GESBC with plenty of NAND flash.&lt;&#x2F;li&gt;
&lt;li&gt;the GESBC provides two serial ports&lt;&#x2F;li&gt;
&lt;li&gt;the GESBC provides many signals on headers than can be used with cables or a daughter card.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Having raw NAND flash on the board is a significant advantage in my opinion.  I’ve run into considerable hassles with consumer grade flash devices in the past (SD, USB Flash, etc).  Although there are industrial grade flash devices, they tend to be more expensive.  My preference at this point for reliable storage in an embedded Linux system is JFFS2 on a 64-128MB raw NAND flash device.  With 128MB of NAND flash, there is &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;&quot;&gt;plenty of space&lt;&#x2F;a&gt; for a full featured Linux distribution.&lt;&#x2F;p&gt;
&lt;p&gt;With 2 USB ports, plenty of general pupose I&#x2F;O pins (GPIO), and lots of memory, there is not a lot you can’t do with the GESBC in your typical headless control or gateway type application.  Being able to interface to a number of USB peripherals, and support for high level languages makes this SBC+Linux ideal for implementing a device that may need to talk web services or other complex network protocols.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software-support&quot;&gt;Software Support&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the GESBC functionality is fairly well supported in the mainstream Linux kernel.  Simply configure the kernel for the EDB9302 machine and most things will just work.  There are several pieces missing from the mainstream kernel for the GESBC that are useful: NAND flash support, and a change needed to make the Ethernet work.  For the NAND flash, I extracted a MTD driver from the Glomation kernel source code.  The Ethernet change is a small tweak to the platform files.  These changes are available for the 2.6.24 kernel in a public git repository at: http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;linux-2.6-gesbc-9302.git.&lt;&#x2F;p&gt;
&lt;p&gt;The GESBC uses Redboot for the bootloader.  No complaints with the bootloader so far – it does everything I need including loading images from a TFTP server.  The bootloader does not support writing images to NAND flash, so to load an OS image into NAND flash you typically have to boot a Linux OS from NOR flash, USB flash, or NFS root, and then use the userspace mtdutils to write an image into NAND flash.&lt;&#x2F;p&gt;
&lt;p&gt;Glomation provides a sample Linux image, but I prefer to use images generated by OpenEmbedded so that I have support for things &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;87&#x2F;9&#x2F;&quot;&gt;like C#&lt;&#x2F;a&gt; , Python, and thousands of other packages.  Support for the GESBC has been added to OpenEmbedded and I’m in the process of updating the kernel support to 2.6.24.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Overall I’m very pleased with this SBC.  Glomation has been very responsive to requests and has been a good company to work with. I still need to apply a fix for a known soft reboot issue with the 2.6 kernel and enable a driver for the RTC on the SBC.    Future articles will detail how to load Linux images built with OpenEmbedded on this device.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Marvell Embedded SDIO Wifi Success</title>
        <published>2008-01-09T00:00:00+00:00</published>
        <updated>2008-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/"/>
        <id>https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/</id>
        
        <content type="html" xml:base="https://bec-systems.com/197/marvell-embedded-sdio-wifi-success/">&lt;p&gt;As detailed in the article I wrote back in September of 2007 (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;75&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;75&#x2F;9&#x2F;&lt;&#x2F;a&gt;), getting  embedded wifi modules functioning is not a simple task.  However, due to recent advances in the Linux kernel, it looks like a viable solution for low-mid volume products is emerging.  This article provides a few details on how to get a Zcomax (Zcom) XG-180MU module working with a PXA270 processor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-setup&quot;&gt;System Setup&lt;&#x2F;h3&gt;
&lt;p&gt;The setup used includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Zcomax XG-180MU SDIO Wifi module&lt;&#x2F;li&gt;
&lt;li&gt;Compulab cm-x270 + sb-x270 system (includes the PXA270 processor)&lt;&#x2F;li&gt;
&lt;li&gt;Linux kernel 2.6.24-rc5&lt;&#x2F;li&gt;
&lt;li&gt;OpenEmbedded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Support for the Marvell 8385 and 8686 based Wifi chipsets is now included in the mainstream Linux kernel 2.6.24 release candidate source code.  To use this driver, enable the CONFIG_LIBERTAS_SDIO option.  I also had to enable the CONFIG_WIRELESS_EXT option to prevent a compile error, but this is probably required anyway to build a functioning wireless system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;firmware&quot;&gt;Firmware&lt;&#x2F;h3&gt;
&lt;p&gt;The firmware for the Marvell SDIO wifi solutions is downloaded at runtime, so the next challenge is to find firmware files.  I am working on a project that has access to a driver from Marvell, so I was able to extract this firmware from their source code header files.  I’m sure there are other places where this firmware is available.   The firmware files must be placed in the following location:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ ls &#x2F;lib&#x2F;firmware&#x2F;sd*
&#x2F;lib&#x2F;firmware&#x2F;sd8385.bin         &#x2F;lib&#x2F;firmware&#x2F;sd8385_helper.bin
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The version of udev used in OpenEmbedded determines the location of the firmware files.  The Libertas Linux driver requests these firmware files, and a userspace component of udev provides these files to the kernel.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;success&quot;&gt;Success&lt;&#x2F;h3&gt;
&lt;p&gt;The following kernel modules are required:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ lsmod
Module                  Size  Used by
pxamci                  7008  0
libertas_sdio           8488  0
mmc_core               46868  2 pxamci,libertas_sdio
libertas               85288  1 libertas_sdio
ieee80211              29956  1 libertas
ieee80211_crypt         4768  1 ieee80211
root@cm-x270:~$
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the result:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@cm-x270:~$ modprobe pxamci
root@cm-x270:~$ mmc0: new SDIO card at address 0001
libertas: eth1: Marvell WLAN 802.11 adapter
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;ifconfig -a
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;eth1      Link encap:Ethernet  HWaddr 00:60:B3:34:77:66
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very nice!&lt;&#x2F;p&gt;
&lt;p&gt;So it looks like there is finally an embedded Wifi solution for products that sell less than 500,000 units per year.  I also briefly tried this on a AT91SAM9260 system, but it did not work.  So there is still some work to do on the Linux SDHC driver for the AT91SAM9260.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>C# on embedded ARM Linux systems is now practical</title>
        <published>2007-12-15T00:00:00+00:00</published>
        <updated>2007-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/"/>
        <id>https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/</id>
        
        <content type="html" xml:base="https://bec-systems.com/191/c-on-embedded-arm-linux-systems-is-now-practical/">&lt;p&gt;&lt;strong&gt;Update&lt;&#x2F;strong&gt;: Michael Dominic K. has kindly provided feedback on this article and has some additional &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lists.ximian.com&#x2F;pipermail&#x2F;mono-list&#x2F;2007-December&#x2F;037362.html&quot;&gt;points&lt;&#x2F;a&gt; about Mono and embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Mono has included support for ARM systems for some time, but with the release of Mono 1.2.6, and its inclusion in OpenEmbedded, it is now practical and easy to build and run C# applications on your everyday ARM Linux system.  Several ARM issues in 1.2.5 have been fixed, and thus far it seems the average program runs quite well.  In this article, we’ll explore what advantages C# offers over more traditional languages such as C or Python, and how OpenEmbedded simplifies adding C# support to your embedded system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-c&quot;&gt;Why C#&lt;&#x2F;h3&gt;
&lt;p&gt;Why is C# an attractive language for embedded Linux systems?  There are many reasons including memory protection and exception handling, native types, good threading support, extensive library, and developer productivity.  In the past, I’ve typically used C or Python for implementing large applications on embedded Linux systems.  This section will compare C# to my experiences with both languages.&lt;&#x2F;p&gt;
&lt;p&gt;A typical experience when implementing a large application in an embedded system is to deploy the system for field testing (before it is ready) and start getting reports that the application is crashing.  Somewhere in the mass of C code your team just wrote there is a stray pointer clobbering something it should not.  Of course this does not happen in the lab where you have access to the machine, but in some piece of industrial equipment many miles away.  And, you cannot reproduce the problem in the lab because with embedded systems, simulating a real world situation is challenging because it is difficult to simulate real I&#x2F;O.  This is less of a problem with desktop applications where you are less dependent on external I&#x2F;O.  Sound familiar?  Even if you can reproduce the problem on a machine you have access to (perhaps even &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;58&#x2F;9&#x2F;&quot;&gt;remotely&lt;&#x2F;a&gt;), the problem can be caused by a stray pointer corrupting data in a completely unrelated piece of code.  So while the debugger may tell you what got clobbered, you still don’t know exactly who did it.  If you have lots of time and a team to do lots of testing, this is less of an issue, but available resources and time to market sometimes don’t give you all you need to do the job right before it gets to the field.  One solution to this problem is use a language that has exception handling (I’ve used Python a lot &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&quot;&gt;in the past&lt;&#x2F;a&gt;), and log all exceptions.  If something bad happens in the field, I ask for the log.  With the stack trace in the log, and some focused testing I can usually find the problem relatively quickly.  Add in the memory protection and things get a lot easier.  For small applications this is not so much of an issue, but lets face it, now that we &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;70&#x2F;9&#x2F;&quot;&gt;have access to very capable hardware at a low cost&lt;&#x2F;a&gt;, applications in embedded systems tend to get large and complex.  C# gives you exception handling and memory protection that makes problems much easier to find and debug; especially during field testing.&lt;&#x2F;p&gt;
&lt;p&gt;While its hard to beat Python or Ruby for developer productively and ease of use, there are performance issues like threading support, and support for static types that must be weighed in the balance.  With Python, everything is an object or a reference.  The checking is done at run time to make sure a variable is of the correct type.  With C#, this is done at compile time (much like C).  While it is generally more work to write code in C# than Python, the compiler tends to catch more errors for you.  There is probably also a performance advantage to being able to implement simple variables statically.  Threading support is another consideration and is often critical in embedded systems because you are usually tending to I&#x2F;O, processing data, running a user interface, etc.  This type of problem is well suited to a threaded application.  Threading in Python is implemented using a global interpreter lock mechanism that is inefficient in some situations.  C# threading support is more similar to C.  While it may require you to do more manual locking than Python, it gives you more control.&lt;&#x2F;p&gt;
&lt;p&gt;When it comes to developer productivity, in my experience C# is more work to write than Python or Ruby, but less work than C.  So it seems to fall somewhere in the middle of the spectrum.&lt;&#x2F;p&gt;
&lt;p&gt;So, C# seems to fall nicely into the middle ground between C and very high level languages such as Python and Ruby.  It offers many of the advantages at both ends of the spectrum and seems to be a nice balance for programming embedded systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mono&quot;&gt;Mono&lt;&#x2F;h3&gt;
&lt;p&gt;What is Mono?  From the Mono &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Main_Page&quot;&gt;web site&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Mono provides the necessary software to develop and run .NET client and server applications on Linux, Solaris, Mac OS X, Windows, and Unix.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mono includes all the necessary components to build and run C# applications on Linux systems including embedded ARM Linux systems.   The Mono source tree is fairly clean and is nicely segmented between native and managed code.  This is critical when it comes to cross compiling.  The Mono team has also stuck with traditional build tools such as autotools which makes the project a lot easier to cross compile for an embedded target.&lt;&#x2F;p&gt;
&lt;p&gt;Mono includes a very extensive C# library that is comparable to Microsoft’s implementation.  Most of what you might ever need is built right into the Mono class library; much like Python or Java.  With C or C++, you typically need to add a number of additional libraries to the system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mono-support-in-openembedded&quot;&gt;Mono Support in OpenEmbedded&lt;&#x2F;h3&gt;
&lt;p&gt;OpenEmbedded includes comprehensive support for Mono including crosscompiling support, granular packaging of the Mono class library, and automatic run-time dependency generation for Mono applications.  In this section, we’ll see how OpenEmbedded can make your life a lot easier.&lt;&#x2F;p&gt;
&lt;p&gt;Mono is typically cross compiled in two &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Mono:ARM&quot;&gt;steps&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The managed portions are generated by compiling Mono for the host machine architecture.  A very nice feature of the Mono build process is that it can bootstrap itself.&lt;&#x2F;li&gt;
&lt;li&gt;The native only portion of Mono is then cross compiled over top of the above output and the native host binaries will then get replaced with the cross compiled target binaries.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To implement this, there are two recipes implemented in OpenEmbedded.  The &lt;em&gt;mono-mcs-intermediate&lt;&#x2F;em&gt; is used to generate all the managed binaries, while the &lt;em&gt;mono&lt;&#x2F;em&gt; recipe builds only the native portion of Mono.  The first step when building the &lt;em&gt;mono&lt;&#x2F;em&gt; cross recipe is to extract the results of the &lt;em&gt;mono-mcs-intermediate&lt;&#x2F;em&gt; in the install directory and then proceed to overlay the native binaries produced by the &lt;em&gt;mono&lt;&#x2F;em&gt; recipe in that same directory.  As mentioned before, the use of standard tools like autotools makes all this work pretty well.  All of this is automated in OpenEmbedded and happens when you run “bitbake mono”.&lt;&#x2F;p&gt;
&lt;p&gt;One issue with embedded systems is you typically have limited flash&#x2F;disk space.  So you only want to include that pieces of Mono in your target image that your application needs.  The OE build of Mono makes this very easy by packaging up the Mono class library into a number of different packages.  The dependencies between packages is automatically tracked so that if you add a Mono package to an OE build, its dependencies will automatically be included with no extra work on your part.  This mechanism uses the &lt;em&gt;monodis&lt;&#x2F;em&gt; tool to figure out what each Mono library provides and the dependencies of each library.  This saves a huge amount of very tedious manual work to have all this automated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;building-and-running-your-mono-application&quot;&gt;Building and Running your Mono application&lt;&#x2F;h3&gt;
&lt;p&gt;Now that we have Mono running on our target system, there are a number of ways to build Mono applications to run on the target.  The quick-n-dirty method is to simply build the mono binary on any system, copy it to your embedded system and run it.  Building and running your applications is easy as Mono binaries are platform independent and will run on any system that supports Mono.  So, you don’t need to worry about cross compiling, toolchains, etc.&lt;&#x2F;p&gt;
&lt;p&gt;The quick-n-dirty method works well for getting started, experimenting, etc, but there are several advantages to integrating your Mono application into an OpenEmbedded build, even though you technically don’t need to worry about cross compiling.  The first reason is packaging.  A very simple OpenEmbedded recipe provides an easy way to automatically fetch your project from a separate version control system, build it, and package it properly into the OS image for your target.  It also gives you the ability to deploy updates to target systems using the ipkg package manager.   The second reason is automatic run-time dependencies.  If you inherit the &lt;em&gt;mono&lt;&#x2F;em&gt; OpenEmbedded class, all of the Mono components your application needs are automatically added to the image.  An example OpenEmbedded recipe for a Mono application is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DESCRIPTION = &amp;quot;My Application&amp;quot;

DEPENDS = &amp;quot;mono&amp;quot;

SRCREV = &amp;quot;${AUTOREV}&amp;quot;
PV = &amp;quot;1.0+svnr${SRCREV}&amp;quot;
PR = &amp;quot;r1&amp;quot;

SRC_URI = &amp;quot;svn:&#x2F;&#x2F;svn.mycompany.com&#x2F;svn&#x2F;myproject&#x2F;;module=myapplication;proto=https&amp;quot;

S = ${WORKDIR}&#x2F;myapplication
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;inherit autotools mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above recipe assume you have set up your application to be built with autotools, which is a good idea.  This &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Guidelines:Application_Deployment&quot;&gt;page&lt;&#x2F;a&gt; provides lots of good information on building Mono applications using autotools.  You can also look at a number of open source applications such as &lt;em&gt;Tomboy&lt;&#x2F;em&gt; for additional clues about how to use autotools with Mono.  For a simple application that I built, the following run time dependencies where automatically determined by OpenEmbedded: *mono, libmono0, libmono2.0-cil, libmono-corlib2.0-cil.*Each of these dependencies may have additional dependencies, and in this case a dozen or so mono packages ended up being installed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;As embedded systems become larger and more capable, we can expect that higher level languages such as C# and Java will start to become more common.  In the past, the focus on embedded systems programming was often efficiency, minimizing resource utilization, etc.  Now that &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;70&#x2F;9&#x2F;&quot;&gt;very capable hardware is becoming cheaper&lt;&#x2F;a&gt;, the focus in some systems is shifting to features and time to market.  Operating systems like Linux and languages like C# help us reach those goals and develop competitive products     quickly with small teams.  C# provides the features needed to rapidly develop, deploy, and debug complex applications that still perform reasonably well.  OpenEmbedded provides a way to manage builds, so that you can focus on real work instead of tedious build issues.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono 1.2.6 added to OpenEmbedded</title>
        <published>2007-12-14T00:00:00+00:00</published>
        <updated>2007-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/194/mono-126-added-to-openembedded/"/>
        <id>https://bec-systems.com/194/mono-126-added-to-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/194/mono-126-added-to-openembedded/">&lt;p&gt;I recently updated the Mono recipes in OpenEmbedded to include the Mono 1.2.6 version.  Several critical bugs that were present in 1.2.5 have been fixed, and its looking very good.  More on this later …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded Linux development on Windows???</title>
        <published>2007-11-30T00:00:00+00:00</published>
        <updated>2007-11-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/189/embedded-linux-development-on-windows/"/>
        <id>https://bec-systems.com/189/embedded-linux-development-on-windows/</id>
        
        <content type="html" xml:base="https://bec-systems.com/189/embedded-linux-development-on-windows/">&lt;p&gt;From &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.embedded.com&#x2F;design&#x2F;opensource&#x2F;204300381&quot;&gt;http:&#x2F;&#x2F;www.embedded.com&#x2F;design&#x2F;opensource&#x2F;204300381&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Host platform&lt;&#x2F;strong&gt;
Although everything I will describe can be also done on a Windows host, I recommend using Linux. It’s more convenient, and more tools and utilities are available. And if you rely on a few Windows applications such as Word and Outlook, you can still run them on Linux in emulation using VirtualBox, Wine, or other commercial package. If you’re new to Linux, using a Linux host will also force you to learn the new platform faster.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;How true.  Those who think they can do embedded Linux development without learning the basics of using a Linux desktop computer are in for a long hard road, and they are missing out on a valuable opportunity to learn a lot about embedded Linux development.  This is the primary advantage of embedded Linux – there are many things in common with desktop and server systems.  There is a tremendous amount of reuse.  Things can be easily prototyped on your desktop Linux system before deploying to an embedded system.  Instead of viewing the suggested that a Linux workstation be used for embedded Linux development as stumbling block, it should be viewed as a huge advantage.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab EM-X270 Review</title>
        <published>2007-11-07T00:00:00+00:00</published>
        <updated>2007-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/94/compulab-em-x270-review/"/>
        <id>https://bec-systems.com/94/compulab-em-x270-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/94/compulab-em-x270-review/">&lt;p&gt;The EM-X270 is a full featured computer board from Compulab (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.compulab.co.il&#x2F;x270em&#x2F;html&#x2F;x270-em-datasheet.htm&quot;&gt;http:&#x2F;&#x2F;www.compulab.co.il&#x2F;x270em&#x2F;html&#x2F;x270-em-datasheet.htm&lt;&#x2F;a&gt;) designed for handheld&#x2F;mobile applications.  The board includes options for about anything you might need in a portable system including a PXA270 processor, GSM radio, GPS, Wifi, Bluetooth, Audio, SD&#x2F;MMC, USB, battery circuitry, and the list goes on.  The EM-X270 is designed to give you a big head start in designing a handheld computing device, and can significantly reduce time to market and design costs.  This article provides a high level overview of this product, how it might be used, and lots of photos.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;em-x270-overview&quot;&gt;EM-X270 Overview&lt;&#x2F;h3&gt;
&lt;p&gt;The EM-X270 is a computer board about the size of a display you might find in a typical PDA.  While the size is probably a little large to be used in consumer devices like phones and PDAs, it seems like a nice size for slightly larger products used in vertical industries.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_1-1.jpg&quot; alt=&quot;em-x270_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As already mentioned, the EM-X270 includes about all the base features you might need in a mobile computing device.  An expansion connector is also included that allows you to easily add custom circuitry to the system.  The stack-up between the EM-X270 and an expansion board is shown below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_2-1.jpg&quot; alt=&quot;em-x270_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The EM-X270 differers from most other embedded computer modules in that it is a little more application specified, and quite a bit more circuitry is included in the design such as power supplies, battery charging circuitry, radios, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-em-x270&quot;&gt;Why EM-X270?&lt;&#x2F;h3&gt;
&lt;p&gt;Why are we interested in the EM-X270?  If all you need is a generic handheld computer, there are plenty of options from PDAs to off-the-shelf industrial handhelds.  However, if you need a handheld that provides some additional features not typically found in existing devices, then you can use the EM-X270 plus a custom baseboard and packaging to add your high value features.  Depending what you need to add, the expansion board can be a simple 4 layer board which is very easy to design and manufacture.  All of the complex PCB design and assembly is already done for you on the EM-X270 module.  This allows low to moderate volume manufactures design products where they would not otherwise have the time and budget for designing a full custom processor board.   Some example applications might be handheld products for the medical, industrial, and test and measurement industry.&lt;&#x2F;p&gt;
&lt;p&gt;Compulab’s pricing model is also very interesting.  Compulab will custom build EM-X270 modules with just the options you need.  The base price without any extra features (such as radios) is $122 for 1000 pieces.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-eb-x270-evaluation-kit&quot;&gt;The EB-X270 Evaluation Kit&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides a EB-X270 Evaluation kit for getting started with EM-X270 development.  Like their other Evaluation klits, is is very full featured and very well done.   An extender board is provided that adds Ethernet, JTAG, and several other useful connectors for development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_3-1.jpg&quot; alt=&quot;em-x270_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The eval kit also includes all necessary cables, a display, battery, etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_4-1.jpg&quot; alt=&quot;em-x270_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software-for-the-em-x270&quot;&gt;Software for the EM-X270&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides software support for both Windows CE and Linux.  This includes very up-to-date support for kernel version 2.6.23.  EM-X270 machine support has also been included in the OpenEmbedded project for building full featured Linux images.  This combination will drastically reduce development costs compared to solutions provided by many other vendors.  All too often, single board computer vendors provide an ancient kernel, a hacked up root file system and call it a “Linux BSP”.  Actually, any time the term “Linux BSP” is used, you should probably be a bit wary.  A much more attractive solution for those of us building products using Linux is for processor and module vendors to say “our products are supported in the mainstream kernel and OpenEmbedded sources”.  Compulab is doing it right.&lt;&#x2F;p&gt;
&lt;p&gt;OpenEmbedded provides many interesting options for devices like the EM-X270.  One of the most interesting might be the ability to run the OpenMoko software on industrial devices.&lt;&#x2F;p&gt;
&lt;p&gt;Compulab provides a Linux demo image built with OpenEmbedded that runs the GPE Palmtop Environment.  The method for loading this image is interesting, and similar to the method I have been using for some time with systems based on the cm-x270 module (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;82&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;82&#x2F;9&#x2F;&lt;&#x2F;a&gt;) in that it used mtd-utils from a running Linux system to erase and write to the NAND flash.  The bootloader in the EM-X270 is able to boot a kernel and rootfs directly from a USB Flash disk.  This “LiveDisk” image, as Compulab calls it, contains a small utility that programs an image from the USB flash disk directly into NAND flash.&lt;&#x2F;p&gt;
&lt;p&gt;As with any modern Linux based embedded system, there is a lot going on in a very small package.  Managing this complexity effectively requires some amount of experience.  Stay tuned for future articles that discuss using OpenEmbedded to build software for the EM-X270.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;additional-photos&quot;&gt;Additional Photos&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_5-1.jpg&quot; alt=&quot;em-x270_5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_6-1.jpg&quot; alt=&quot;em-x270_6&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;em-x270_7-1.jpg&quot; alt=&quot;em-x270_7&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux 2.6.23 for the Compulab cm-x270</title>
        <published>2007-10-22T00:00:00+00:00</published>
        <updated>2007-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/"/>
        <id>https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/187/linux-2623-for-the-compulab-cm-x270/">&lt;p&gt;Updated 2.6.23 kernel patches for the Compulab cm-x270 are now available in OpenEmbedded:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.23&#x2F;cm-x270&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;linux-2.6.23&#x2F;cm-x270&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The cm-x270 support in OpenEmbedded has undergone a lot of clean-up in recent weeks.  Now is a good time to give OpenEmbedded a try if you need a full featured Linux distribution for the cm-x270.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 NAND flash eraseblock sizes</title>
        <published>2007-10-08T00:00:00+00:00</published>
        <updated>2007-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/"/>
        <id>https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/</id>
        
        <content type="html" xml:base="https://bec-systems.com/181/compulab-cm-x270-nand-flash-eraseblock-sizes/">&lt;p&gt;If you are having trouble mounting a JFFS2 file system on a Compulab cm-x270 module, you may have a device that has a NAND flash with 16KiB eraseblocks.  All of the devices I have personally used to date have had 128KiB eraseblocks, but I just helped a cm-x270 user through some flash issues and after much pain discovered the eraseblock size was 16KiB on his module.  A variable has been added to the cm-x270.conf file in OE to set the eraseblock size that can be overridden in your local.conf file if you are using OpenEmbedded to generate jffs2 images:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;git.openembedded.net&#x2F;?p=openembedded.git;a=blob;f=conf&#x2F;machine&#x2F;cm-x270.conf;h=3c21c546b1320914c9b5d2c44e7332782fc58748&quot;&gt;http:&#x2F;&#x2F;git.openembedded.net&#x2F;?p=openembedded.git;a=blob;f=conf&#x2F;machine&#x2F;cm-x270.conf;h=3c21c546b1320914c9b5d2c44e7332782fc58748&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Howto load Openembedded on the Compulab cm-x270 computer module</title>
        <published>2007-10-08T00:00:00+00:00</published>
        <updated>2007-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/"/>
        <id>https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/</id>
        
        <content type="html" xml:base="https://bec-systems.com/183/howto-load-openembedded-on-the-compulab-cm-x270-computer-module/">&lt;p&gt;There are quite a few people using (or would like to use) OpenEmbedded on the Compulab cm-x270.  The cm-x270 is a high performance, low cost computer module that can be used with a custom baseboard in embedded systems (see &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&lt;&#x2F;a&gt; for a review).  I get a lot of questions on how to load OpenEmbedded on this system, so this howto attempts to detail a procedure that can be used to load OpenEmbedded.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-nand-flash-wrinkle&quot;&gt;The NAND Flash wrinkle&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux solution provided by compulab includes a proprietary NAND flash driver.  Most developers are interested in using standard Linux MTD drivers with the JFFS2 filesystem, but its not readily obvious how to flash a JFFS2 NAND image using the cm-x270 bootloader.  Fortunately, you can boot a small Linux image stored in NOR flash, and then use standard MTD utilities to then flash the NAND jffs2 image.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-the-needed-images&quot;&gt;Creating the needed images&lt;&#x2F;h3&gt;
&lt;p&gt;For this method, you need to generate two images: a small image to run from NOR flash, and a larger full featured image that will run from NAND flash.  Because you only have about 2.3MB of NOR flash, you want to use uclibc in the NOR image as it is much smaller.  A base Linux image that will boot into a shell using uclibc and contains a few utilities is about 1MB in size, which leaves plenty of space for custom apps should you need them in this partition.  The local.conf settings to build this image are:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;MACHINE = &amp;quot;cm-x270&amp;quot;
DISTRO = &amp;quot;angstrom-2008.1&amp;quot;
ANGSTROM_MODE = &amp;quot;uclibc&amp;quot;
IMAGE_FSTYPES = &amp;quot;jffs2 tar cpio.gz&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, “bitbake angstrom-minimal-image-with-mtd-utils”, and OE will generate a “minimalist-image-mtdutils-cm-x270.cpio.gz” image that can be programmed into the NOR ramdisk partition using the cm-x270 bootloader, and tftp download.  A kernel will also be built that should be programmed into the kernel partition.&lt;&#x2F;p&gt;
&lt;p&gt;To build the NAND image, simply remove the ANGSTROM_MODE line, and “bitbake angstrom-console-image”.  This will generate a “console-image-cm-x270.rootfs-summary.jffs2” that can be programmed into NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;programming-images&quot;&gt;Programming Images&lt;&#x2F;h3&gt;
&lt;p&gt;Loading the software onto the cm-x270 is a multi-step process.  The first step is to the load the kernel image and the minimalist-image into NOR flash using the cm-x270 bootloader and tftp.  After this is accomplished, run the following commands to boot into the NOR flash rootfs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ramdisk on&lt;&#x2F;li&gt;
&lt;li&gt;bootos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If successful, you will be presented with a prompt – log in as user root, and no password.&lt;&#x2F;p&gt;
&lt;p&gt;You now need to download the jffs2 NAND image into RAM on the cm-x270.  One way to do this is to use the tftp download feature in busybox:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;tftp -g -r console-image-cm-x270.rootfs-summary.jffs2 &amp;lt;tftp server IP&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point you can program the jffs2 image into NAND flash:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;flash_eraseall -j &#x2F;dev&#x2F;mtd3&lt;&#x2F;li&gt;
&lt;li&gt;nandwrite &#x2F;dev&#x2F;mtd3 console-image-cm-x270.rootfs-summary.jffs2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After programming completes, reboot the system and enter the following in the cm-x270 bootloader:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ramdisk off (this will disable the initramfs in NOR flash)&lt;&#x2F;li&gt;
&lt;li&gt;bootos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At this point, your system should boot into the main NAND rootfs.  With a little imagination, it should be obvious that you can do a lot of neat things with this type of setup by extending the functionality in the NOR rootfs including field upgrades and system recovery.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mono support in OpenEmbedded and Openmoko packages</title>
        <published>2007-10-04T00:00:00+00:00</published>
        <updated>2007-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/"/>
        <id>https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/</id>
        
        <content type="html" xml:base="https://bec-systems.com/179/mono-support-in-openembedded-and-openmoko-packages/">&lt;p&gt;&lt;em&gt;Original article published&lt;&#x2F;em&gt;2007-10-04&lt;&#x2F;p&gt;
&lt;p&gt;As of today, the Mono build in OpenEmbedded is working pretty well.  Mono support for ARM and other embedded architectures should add some interesting capabilities for embedded Linux devices.  Having written a number of large embedded Linux applications, I can really appreciate the advantages of high level languages for exception handling.  It is also interesting to note that Java support in OpenEmbedded is making progress as well (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;jalimo.org&#x2F;wiki&#x2F;doku.php&quot;&gt;http:&#x2F;&#x2F;jalimo.org&#x2F;wiki&#x2F;doku.php&lt;&#x2F;a&gt;).  Windows CE developers have already taken to the .net compact framework in a big way, so its nice to see similar capabilities for embedded Linux systems.&lt;&#x2F;p&gt;
&lt;p&gt;A feed has been set up for installing mono packages on your Openmoko phone.  Add the following line to a &#x2F;etc&#x2F;ipkg&#x2F;*-feed.conf file:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;src&#x2F;gz mono-armv4t http:&#x2F;&#x2F;dev.bec-systems.com&#x2F;feed&#x2F;openmoko&#x2F;mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ipkg update
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;ipkg install mono
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The packaging is fairly granular, so look at the listing in the above URL to see a complete list of what is available.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to implement realtime periodic tasks in Linux applications</title>
        <published>2007-09-25T00:00:00+00:00</published>
        <updated>2007-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/"/>
        <id>https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/175/how-to-implement-realtime-periodic-tasks-in-linux-applications/">&lt;p&gt;(see also &lt;a href=&quot;&#x2F;201&#x2F;should-you-be-using-monotonic-timers&#x2F;&quot;&gt;should you be using monotonic timers?&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Have you ever wondered what is the best way to implement periodic tasks in Linux applications – something better than usleep()?  This article covers a number of issues related to this subject including real-time tasks, the different timers available, timer resolution, and how to implement periodic tasks accurately so that error is not accumulated.  The recent inclusion of the high-resolution timers in the mainstream kernel makes this a very interesting subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;high-resolution-timers&quot;&gt;High Resolution Timers&lt;&#x2F;h3&gt;
&lt;p&gt;Historically Linux has done all timing off the OS timer tick which is usually between 1ms and 10ms.  While this is adequate for many tasks, it is really nice to have a high resolution timer for timing tasks.  With the integration of the high resolution timers into the mainstream Linux source tree, this is now possible.  From a user space perspective, there are no API changes.  The only difference you will notice is that now you can sleep for less than OS timer tick period.  clock_getres() can be used to check the timer resolution and will tell you instantly if you have high resolution timer support.  If the clock resolution is 1ns, you have high res timer support.  Realistically, you can’t delay for 1ns in a Linux application, but delays in the range of 100us should be possible, and depending on the configuration, much better performance is possible.  The kernel config entry for high resolution timers is CONFIG_HIGH_RES_TIMERS.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-difference-between-clock-realtime-and-clock-monotonic&quot;&gt;The difference between CLOCK_REALTIME and CLOCK_MONOTONIC&lt;&#x2F;h3&gt;
&lt;p&gt;Some of the Linux timer functions take a &lt;em&gt;clockid_t&lt;&#x2F;em&gt; argument that can be specified as CLOCK_REALTIME, or CLOCK_MONOTONIC.  The big difference between these two is that changing the system time will have an affect on CLOCK_REALTIME, thus affecting your timers.  Changing the system time will have no affect on CLOCK_MONOTONIC – it will always count upward.  For periodic tasks, CLOCK_MONOTONIC may be more applicable.  The best way to get burned using CLOCK_REALTIME is when your application takes a timestamp, does something, takes another time stamp and then compares them.  If you are using CLOCK_REALTIME, and the system time gets changed between the two timestamps, your comparison will not be valid.  For most timeouts and relative timekeeping in Linux, use CLOCK_MONOTONIC.  This issue becomes more important as many systems now have a process that periodically sets the time automatically from network time servers, and you have no idea when this might happen.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preemption&quot;&gt;Preemption&lt;&#x2F;h3&gt;
&lt;p&gt;Kernel preemption (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;69&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;69&#x2F;9&#x2F;&lt;&#x2F;a&gt; ) makes a huge difference in the performance of real time applications by allowing the kernel to be preempted by higher priority application processes.  Historically, any kernel code that was runnable ran before the kernel returned control to applications.  This all changes with kernel preemption.  Kernel preemption has been available in mainline kernels for some time now (I think since 2.6.16).  The worst offender I’ve found for locking the kernel for long periods of time have been flash drivers – especially proprietary ones.  But, even jffs2 can cause problems in realtime applications without kernel preemption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-preempt-rt-patch&quot;&gt;The PREEMPT_RT patch&lt;&#x2F;h3&gt;
&lt;p&gt;Much of the realtime work being done for Linux is maintained in the PREEMPT_RT patch.  Bits of this patch have already been merged into the mainline kernel, but there is still a lot of very useful functionality in the patch and it should be considered if you are doing any type of realtime work.  More details will be presented in a future article.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;absolute-vs-relative-timekeeping&quot;&gt;Absolute vs Relative timekeeping&lt;&#x2F;h3&gt;
&lt;p&gt;When implementing a periodic task, you really want to base your timekeeping off an absolute time, versus relative delays such as usleep().  It is not possible to achieve precise periodic activation with a relative sleep such as usleep().  The reason for this is you must first get the current time, make a calculation to determine how long to sleep, and then call the relative sleep function.  If your process gets preempted between the time you acquire the timestamp, and the sleep, your relative sleep time will probably be wrong.  This problem is solved by using the clock_nanosleep() function.  clock_nanosleep() can be called with the TIMER_ABSTIME value in the flags argument.  If  the TIMER_ABSTIME flag is set, then clock_nanosleep() will sleep until the absolute timer value is reached.  It does not matter if you get preempted between the time you take a timestamp, and the sleep function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;In summary, if you want to implement accurate, realtime, periodic tasks in a Linux application, consider the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use high resolution timers.  Although Linux is still limited in its response time, at least the scheduling resolution is now quite high.&lt;&#x2F;li&gt;
&lt;li&gt;Enable kernel preemption.  This makes sure long kernel processes don’t get in the way of your real-time application process.&lt;&#x2F;li&gt;
&lt;li&gt;Use the CLOCK_MONOTONIC for relative timekeeping.  You don’t want your application to lock up due to the system time changing.&lt;&#x2F;li&gt;
&lt;li&gt;use the clock_nanosleep() function instead of relative delays like usleep().  This is the only way to accurately schedule periodic tasks.&lt;&#x2F;li&gt;
&lt;li&gt;if needed, apply the PREEMPT_RT patch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The clock_nanosleep man page also includes a lot of useful information about timer functions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Embedded WiFi module Quest</title>
        <published>2007-09-19T00:00:00+00:00</published>
        <updated>2007-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/90/the-embedded-wifi-module-quest/"/>
        <id>https://bec-systems.com/90/the-embedded-wifi-module-quest/</id>
        
        <content type="html" xml:base="https://bec-systems.com/90/the-embedded-wifi-module-quest/">&lt;p&gt;&lt;em&gt;original article written in Sept, 2007&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;How does one implement WiFi functionality in vertical, low volume portable products?  This is a good question, and one I’ve been struggling with for the past 3 months.  I have a customer who is designing a portable data acquisition system based on a AT91SAM9260 processor, and needs WiFi functionality.  The fundamental problem is that no one has time to deal with low volume customers, and the task of implementing WiFi functionality is obviously complex.  At volumes of 5000 units a year or less, it makes a lot of sense to go with a WiFi module rather than trying to integrate the WiFi chipset on the board.  This article covers some of the options we have looked at and some of the possible solutions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-is-wifi-done-on-x86-systems&quot;&gt;How is WiFi done on x86 systems?&lt;&#x2F;h3&gt;
&lt;p&gt;With desktop Windows, most devices are well supported by device manufacturers.  With x86 Linux some of the devices are well supported by OSS drivers, but these tend to be PCI or USB devices.  Some of the devices that are not supported can still be used by running the Windows NDIS drivers inside of ndiswrapper, which allows you to run the Windows driver on a x86 Linux system, but this obviously does not work very well on non-x86 processors such as ARM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wifi-solutions-for-portable-embedded-systems&quot;&gt;WiFi solutions for portable, embedded systems&lt;&#x2F;h3&gt;
&lt;p&gt;While there are many off-the-shelf solutions for PCs, Notebooks, etc, the current solutions are generally in the USB formfactor.  The ideal solution for portable systems running non-x86 processors are the small modules that connect to the host processor using the SDIO or SPI bus – like the modules you would find in newer cell phones and PDAs.  Older modules tend to use the Compact Flash interface, but these modules tend to be larger and are not packaged as nicely for deeply embedded applications.  So Ideally we want:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a modules with a SDIO or SPI interface&lt;&#x2F;li&gt;
&lt;li&gt;packaging options such as solder down for robust packaging&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The scope of this article is limited to modules that implement a SPI or SDIO interface.  Why are we interested in modules?  Putting a WiFi chip down on a custom PCB is a lot of work.  Because the WiFi silicon includes a processor, if things do not work, it may be very difficult to debug.  There is also the issue of factory calibration which usually requires proprietary PC based tools that can communicate directly with the WiFi silicon.  If the WiFi silicon is buried in your product, getting all this to work can be a challenge.  The test equipment required for calibration is expensive.  Add to this the difficulty in getting support from anyone who makes WiFi silicon …&lt;&#x2F;p&gt;
&lt;h3 id=&quot;complexity&quot;&gt;Complexity&lt;&#x2F;h3&gt;
&lt;p&gt;It should be noted that WiFi modules are fairly complex devices.  They are typically based on a highly integrated IC that includes an ARM processor, Flash memory, and radio circuitry.  The fact that these modules include a significant amount of firmware on the module contributes significantly to the complexity of getting WiFi solutions to work properly.  Hopefully no bugs are encountered in the module firmware, because I can only imagine how difficult it would be to get these fixed for a small customer.   The fact that the module firmware is involved in many of the WiFi functions like authentication further complicates the problem with the abundance of authentication and encryption options available for WiFi.   The worst possible problem is the case where you must design an embedded WiFi system that must operate at the enterprise level in every environment.  It is one thing to design a system that works most of the time in most environments where WiFi is more of a convenience (like a Cell phone or PDA).  It is another thing to design an industrial grade system where it must work all the time and in all environments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-fundamental-problems-with-low-volume-embedded-wifi&quot;&gt;The Fundamental Problems with low volume embedded WiFi&lt;&#x2F;h3&gt;
&lt;p&gt;I have never worked with a technology with so many dead ends as embedded WiFi modules.  Many of the companies I email or call never even bother to return emails and phone calls.  This is certainly true of the chipset manufactures.  From what I can gather, the fundamental problems are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;WiFi implementation is difficult; therefore, a manufacturer’s scarce resources are dedicated to high volume customers.  Low volume customers are a significant distraction.&lt;&#x2F;li&gt;
&lt;li&gt;WiFi companies are very busy right now – they are not hungry for business from small customers.&lt;&#x2F;li&gt;
&lt;li&gt;WiFi solutions are very competitive and highly proprietary.  Many companies are very secretive and will not release driver source code.  This is certainly true at the module firmware level.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are many WiFi module manufacturers and resellers out there, but very few of them offer any type of driver solution for Windows CE or Linux other than binary modules that are supposed to work on perhaps one reference platform.  Sorry, this is not going to cut it.  So, with plenty of hardware available, the gating item is the availability of software drivers and knowledge of how to use the software.  It would seem to me that this is the perfect opportunity for chipset vendors to open source some drivers and develop vibrant support communities so that their modules can be used without a lot of hand-holding by the chipset vendors.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;so-what-are-the-options&quot;&gt;So What are the options?&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;atheros-ar6001&quot;&gt;Atheros AR6001&lt;&#x2F;h4&gt;
&lt;p&gt;The Atheros AR6001 seems like a nice solution.  The driver situation for the AR6001 is progressing.  For Windows CE, there is an opensource WinCE 6.0 driver available at:  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.codeplex.com&#x2F;CEWifiDriverAR6000&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.codeplex.com&#x2F;CEWifiDriverAR6000&#x2F;&lt;&#x2F;a&gt;.  Unfortunately, this project appears to be a snapshot of code and does not have any significant amount of community activity or development.  Perhaps once more AR6001 modules are available, this will change.&lt;&#x2F;p&gt;
&lt;p&gt;For Linux, there are several options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Atheros has released a driver that is available:  &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;project&#x2F;showfiles.php?group_id=186068&quot;&gt;http:&#x2F;&#x2F;sourceforge.net&#x2F;project&#x2F;showfiles.php?group_id=186068&lt;&#x2F;a&gt;.  There are several issues with this driver in that it is written for a SDIO stack that will likely never be part of the mainstream kernel.&lt;&#x2F;li&gt;
&lt;li&gt;A driver is being developed as part of the OpenMoko project.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Embedded Works supplies Atheros based modules and development boards: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.embeddedworks.net&#x2F;wlan&#x2F;oem_sdio_80211g.html&quot;&gt;http:&#x2F;&#x2F;www.embeddedworks.net&#x2F;wlan&#x2F;oem_sdio_80211g.html&lt;&#x2F;a&gt;.    AR6001 development boards are also available from Cardaccess: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.cardaccess-inc.com&#x2F;products&#x2F;index.php?a=wlan_sdio&quot;&gt;http:&#x2F;&#x2F;www.cardaccess-inc.com&#x2F;products&#x2F;index.php?a=wlan_sdio&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;marvell&quot;&gt;Marvell&lt;&#x2F;h4&gt;
&lt;p&gt;The Marvell 88W8385 seems to be a very popular IC in WiFi modules available from a number of different companies.  OSS Linux drivers are in progress and are reportedly somewhat functional at this point, so it is probably just a matter of time before these devices are well supported in Linux.  This chipset&#x2F;driver is often referred to as “libertas”.  The SDIO stack being developed for the Linux mainline (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;242747&#x2F;&quot;&gt;http:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;242747&#x2F;&lt;&#x2F;a&gt;) is where support for this device is being developed.&lt;&#x2F;p&gt;
&lt;p&gt;For Windows CE, it seems the only option is to get the drivers from Marvell, which is a very difficult and time consuming process – at least for low volume customers.  First you have to find a module reseller that can get you the source code from Marvell, and then the process takes about 3 months.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;other-options&quot;&gt;Other Options&lt;&#x2F;h4&gt;
&lt;p&gt;There are a number of other WiFi Silicon manufacturers and module vendors, but the driver options from them seem to be very limited in the form of binary only drivers that will only work with certain processors&#x2F;operating systems.  As noted before there is almost no hope of getting anyone to even talk with you if your volumes are low.  So your only hope is finding a module vendor that can do any driver work for a NRE fee, obtain the source from the silicon manufacturer, or use OSS drivers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The Embedded WiFi situation is changing fast, so by the time you read this, it is probably already out of date.  We are currently at the phase where it is very difficult to deeply embedded WiFi in low volume products.  I expect this will change during the next year.  Eventually, WiFi modules re-sellers will figure out that supplying hardware is just one side of the equation.  As things get more and more complex, the software availability and support is becoming the gating item.&lt;&#x2F;p&gt;
&lt;p&gt;Many thanks to James Nahra, Dave Anders, and Erik Strack for sharing information and their WiFi experiences with me over the past few months.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The correct way to add packages to an OpenEmbedded Image</title>
        <published>2007-08-30T00:00:00+00:00</published>
        <updated>2007-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/"/>
        <id>https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/</id>
        
        <content type="html" xml:base="https://bec-systems.com/177/the-correct-way-to-add-packages-to-an-openembedded-image/">&lt;p&gt;&lt;strong&gt;Update 2007-10-14: use IMAGE_INSTALL in image recipe&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-10-22: a few corrections, added full path for include and comments&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2010-06-07: use recipes instead of packages directory&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As more and more OpenMoko developers are coming on-line, it is becoming obvious that my previous post (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;59&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;59&#x2F;9&#x2F;&lt;&#x2F;a&gt;) about adding packages to OpenEmbedded could use some improvements.  This post suggested using the DISTRO_EXTRA_RDEPENDS variable, which was intended to only be used in distro.conf files.  A better approach is to create a custom image recipe that includes the packages you want.  This article covers how to create a custom image recipe.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-are-the-problems-with-the-distro-extra-rdepends-approach&quot;&gt;What are the problems with the DISTRO_EXTRA_RDEPENDS approach?&lt;&#x2F;h3&gt;
&lt;p&gt;As detailed by Marcin Juszkiewicz in his blog post “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;blog.haerwu.biz&#x2F;2007&#x2F;08&#x2F;23&#x2F;why-using-of-distromachine-variables-in-localconf-is-wrong&#x2F;&quot;&gt;Why using of DISTRO&#x2F;MACHINE variables in local.conf is wrong&lt;&#x2F;a&gt;”, and from discussions with OE developers, the following issues surfaced:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You have to remember to rebuild task-base every time you update the DISTRO_EXTRA_RDEPENDS variable.&lt;&#x2F;li&gt;
&lt;li&gt;The image is no longer angstrom-console-image or whatever you have extended, so when asking for support, other developers do not realize exactly what you are building.  If it is a custom image, then that is obvious by the image name.&lt;&#x2F;li&gt;
&lt;li&gt;Changing DISTRO_EXTRA_RDEPENDS in local.conf requires that you bitbake reparse the entire recipe tree (which takes minutes).  Changing a custom image recipe only requires one file to be reparsed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;creating-a-custom-image-file&quot;&gt;Creating a custom image file&lt;&#x2F;h3&gt;
&lt;p&gt;Creating a custom image file is quite easy, and works much better than modifying DISTRO_EXTRA_RDEPENDS in your local.conf file.  A custom image is created by simply copying or including an image file closest to what we want to use, and then adding additional packages to IMAGE_INSTALL variable.  In the following example, we require angstrom-console-image.bb and extend it with a few lines:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;require recipes&#x2F;images&#x2F;console-image.bb

IMAGE_INSTALL += &amp;quot;\
        xset xserver-kdrive-fbdev xinit \
        kernel \
        kernel-module-mmc-block \
        kernel-module-mmc-core \
        kernel-module-pxamci \
        kernel-module-ac97-bus \
	&amp;quot;

export IMAGE_BASENAME = &amp;quot;my-custom-image&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note, this method requires your custom image file to be in the same location as the original image recipe. If you use a bbcollections overlay, then you may want to copy the original recipe.&lt;&#x2F;p&gt;
&lt;p&gt;Note the use of a full path specified in the require statement.  This allows you to have your custom image recipe in a bbcollections overlay, and bitbake will still find the required recipe in the main OE tree.&lt;&#x2F;p&gt;
&lt;p&gt;Thats it!  With the many advantages to this method, there is no reason not to create your own image recipes – it works better.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Howto use a Git topic branch to maintain a patchset, and isolate problems</title>
        <published>2007-08-16T00:00:00+00:00</published>
        <updated>2007-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/247/howto-use-a-git-topic-branch/"/>
        <id>https://bec-systems.com/247/howto-use-a-git-topic-branch/</id>
        
        <content type="html" xml:base="https://bec-systems.com/247/howto-use-a-git-topic-branch/">&lt;p&gt;The more I use Git, the more I am really impressed with some of its capabilities.  What is Git?  Git is a very advanced distributed source code control system that can do some very neat things.  For the average developer using open source software, we are mainly concerned about maintaining patch sets (often called a topic branch).  Git includes a rebase capability that is very useful for a number of different operations related to maintaining a branch of code including moving a branch forward, moving a branch around on an upstream branch to look for breakage, and merging changesets to create patch files.  This article provides a brief overview of some of these operations and several tips.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-in-doubt-make-a-branch&quot;&gt;When in doubt, make a branch&lt;&#x2F;h3&gt;
&lt;p&gt;The most important concept to understand when working with Git is to get used to creating and destroying branches.  This is different than most other SCMs where all branches are stored on a central repository, and you don’t want to clutter the branch namespace.  With Git, get used to branching without even thinking about it.  For example, the following are the branches in a Git repository I use to maintain patch sets for the Compulab cm-x270:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; git branch
  cmx270
  cmx270_2.6.20
  cmx270_2.6.21
  cmx270_2.6.22
  master
  svs
* test
  v2.6.20_test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Most of the names are self explanatory.   The cmx270 branch is where I track the latest kernel version.  The svs branch is for a customer platform based off the Compulab cm-x270.  To view the changes on any particular branch:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-log cmx270_2.6.22
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;an Git will start showing you a list of changes on that branch.  This works even if you are not working on that branch, so it is very handy for seeing what changes are in other branches.  With Git is also very easy to move changes between branches using &lt;em&gt;git-cherry-pick&lt;&#x2F;em&gt;.  For example, if we are working on the cmx270 branch, and we want to pull the 3rd changeset from the HEAD of the cmx270_2.6.22 branch into the cmx270 branch, we would do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-cherry-pick  cmx270_2.6.22~2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;git-is-really-good-at-maintaining-patch-sets&quot;&gt;Git is really good at maintaining patch sets&lt;&#x2F;h3&gt;
&lt;p&gt;Many developers use quilt to maintain patch sets.  Once you understand how Git works, Git is even better at maintaining patch sets.  Although there are some add-on tools available for maintaining patch files in a git repository like Patchy GIT and Stacked GIT, I’ve found that core Git works well enough.  Actually the Patchy GIT maintainer has quit working on Patchy GIT because core GIT now meets his needs.  The fundamentals are you simply export each Git commit as a patch using the git-format-patch command as shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-format-patch -o tmp&#x2F; master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;Produces the following files (all of the commits since the branch has left the master):
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;tmp&#x2F;0001-cm-x270-base2.patch
tmp&#x2F;0002-cm-x270-match-type.patch
tmp&#x2F;0003-cm-x270-ide.patch
tmp&#x2F;0004-cm-x270-it8152.patch
tmp&#x2F;0005-cm-x270-pcmcia.patch
tmp&#x2F;0006-ramdisk_load.patch
tmp&#x2F;0007-mmcsd_large_cards-r0.patch
tmp&#x2F;0008-cm-x270-nand-simplify-name.patch
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pretty slick!  HEAD~8 means to back up 8 revisions from the current HEAD and then start outputting changes as patch files.  The name of the patch file is the commit comment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;moving-your-patch-set-forward-in-time&quot;&gt;Moving your patch set forward in time&lt;&#x2F;h3&gt;
&lt;p&gt;If you are maintaining a patch set for the Linux kernel, you might want to move your patchset up to the latest version for testing, and also maintain patchsets for each stable version of the kernel.  Lets say we already have a patch set for the 2.6.20 version.  The first thing we need to do is create a branch.  In this example, I am maintaining a patch set for the Compulab cm-x270 computer module.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-branch cmx270_2.6.20 v2.6.20  (branch name, tag name in repository)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;git-checkout cmx270_2.6.20
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, I would manually apply each patch, and then commit each patch as its own changeset.  Now, I want to move the changeset forward to kernel version 2.6.21.  The easiest way to do this is create a new branch, and simply rebase your patchset to the new kernel version.  Make sure you create a new branch first, or your existing branch will be moved!&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-checkout -b cmx270_2.6.21 cmx270_2.6.20
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;git-rebase --onto v2.6.21 master (tag point to relocate branch, upstream branch)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The upstream branch is required to be specified so that Git knows where our branch changes start – specifically where the cmx270_2.6.21 branch diverges from the master branch.&lt;&#x2F;p&gt;
&lt;p&gt;There may be a few things to clean up along the way if changes don’t apply cleanly.  The most critical thing to know is that if you want to skip a patch, you must run “&lt;em&gt;git-reset --hard&lt;&#x2F;em&gt;” before running “&lt;em&gt;git-rebase --skip”&lt;&#x2F;em&gt;.  This is often handy if you have an especially troublesome patch that you don’t want to apply now.  You can skip it and then cherry-pick it later.  Otherwise the process is fairly straightforward.  After you are finished, you can now export a set of patch files that can be applied to the 2.6.21 kernel.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bisecting-the-master-branch-to-determine-when-things-broke&quot;&gt;Bisecting the master branch to determine when things broke&lt;&#x2F;h3&gt;
&lt;p&gt;You may run into a situation where something broke on the main branch, and you don’t know where.  Most of the time, you would just run &lt;em&gt;git-bisect&lt;&#x2F;em&gt; to do a binary search to find where things broke.  This does not work so well if the platform you are testing is not supported in the main branch – the changes in your topic branch are required to make the system run.  Once again, &lt;em&gt;git-rebase&lt;&#x2F;em&gt; to the rescue.  The first thing we must do is find the mid-point between the known good and bad points.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-rev-list --bisect v2.6.20 v2.6.21
13f7e5acc8b329080672c13f05f252ace5b79825
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, rebase out changes to the above rev and test.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git rebase --onto 13f7e5acc8b329080672c13f05f252ace5b79825 master
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The build failed, so now we have a new “bad” point and can continue our binary search.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git-rev-list --bisect v2.6.20 13f7e5acc8b329080672c13f05f252ace5b79825
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you can build working kernels from the main tree, then you can directly use git-bisect – another good reason to get your changes into the mainstream source, but this is not always possible.&lt;&#x2F;p&gt;
&lt;p&gt;Another option for doing this type of binary search is to use git-bisect, and then cherry pick your changes at each bisect point.  It may also be possible to use git-merge, but I have not figured out how yet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;That is it for now.  Git is very useful for maintaining multiple patch sets for different versions of an open source project, and is just another thing that makes working with open source projects a real pleasure.  Future articles will cover how to further manipulate patches such as how to combine two patch files.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux 2.6.22 for the Compulab cm-x270</title>
        <published>2007-08-13T00:00:00+00:00</published>
        <updated>2007-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/"/>
        <id>https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/168/linux-2-6-22-for-the-compulab-cm-x270/">&lt;p&gt;I just completed porting the cm-x270 Linux kernel patches to the 2.6.22 kernel.  Kernel build is available in OpenEmbedded.  Patches are available in the OE tree:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;compulab-pxa270-2.6.22&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;filebrowser&#x2F;org.openembedded.dev&#x2F;packages&#x2F;linux&#x2F;compulab-pxa270-2.6.22&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Shortly I will be making 2.6.22 the default kernel for the cm-x270 in OpenEmbedded and posting instructions on how to use JFFS2 with the NAND flash on the cm-x270.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Design tips for your embedded Linux product</title>
        <published>2007-07-20T00:00:00+00:00</published>
        <updated>2007-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/"/>
        <id>https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/</id>
        
        <content type="html" xml:base="https://bec-systems.com/159/design-tips-for-your-embedded-linux-product/">&lt;p&gt;When designing a system that runs embedded Linux, there are number of things you can do to make your life a lot easier and provide for future expansion to cover cases you did not anticipate.  Following these simple guidelines can drastically improve the efficiency of developing the system, and troubleshooting problems during field testing, and provide the flexibility needed in todays products.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-have-a-dedicated-serial-console&quot;&gt;#1 Have a dedicated serial console&lt;&#x2F;h3&gt;
&lt;p&gt;This is the single most important interface to provide.  A serial console is your gateway into the system, and allows you at any time to poke around at the internals of the system, debug problems, run applications, change configuration, etc.  A serial console does not have to be a big DB9 connector accessible outside the system.  It can can be a simple 3 pin header and you make a special cable to connect to a PC.  Also, do put the RS232 level translators on the board.  This saves so much hassle during the development and testing cycle.  You can always not populate them later, but you will probably find that the debug console is so useful, you will leave it in – even in production.&lt;&#x2F;p&gt;
&lt;p&gt;Another consideration is to make sure you use a serial port provided by the processor if possible.  The advantage of this is very little hardware has to be working for the serial console to work.  If you use a serial port off an external UART, then the bus interface between the processor and the UART, the UART and the processor need to be working.  If something is wrong with the system, you are less likely to get debug messages out the serial console which will help you debug the system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-implement-a-usb-host-port&quot;&gt;#2 Implement a USB Host port&lt;&#x2F;h3&gt;
&lt;p&gt;A USB host port is so useful it should be considered for about any system.  Some of the things USB can be used for include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keyboard and mouse if you are designing a display based system&lt;&#x2F;li&gt;
&lt;li&gt;USB networking&lt;&#x2F;li&gt;
&lt;li&gt;Wifi networking&lt;&#x2F;li&gt;
&lt;li&gt;extra serial ports&lt;&#x2F;li&gt;
&lt;li&gt;WAN modems&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Many embedded processors that can run Linux include a USB Host interface, so assuming you have one of these, it is very cheap to provide this interface as it only requires two wires, and a 5V power supply.&lt;&#x2F;p&gt;
&lt;p&gt;Once again, you don’t have to put a full size USB connector in your device – a simple header wired to a connector might work in most situations.&lt;&#x2F;p&gt;
&lt;p&gt;I can’t begin to describe how useful a USB keyboard was on a recent touchscreen based product.  The product is used in agricultural vehicles, so anytime in the field we can connect a USB keyboard and look at logs, run commands, and other operations that are very difficult to do though a touch interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-implement-a-network-interface&quot;&gt;#3 Implement a Network Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Working on any Linux system is very painful without a networking interface.  Even if you don’t plan to use Ethernet in the final product, make sure a networking interface is available for development.  Some reasons why a network interface is critical:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;can easily log into the system remotely for development and debugging&lt;&#x2F;li&gt;
&lt;li&gt;easily copy files to and from the device quickly&lt;&#x2F;li&gt;
&lt;li&gt;install software updates easily during the development process&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Trust me on this one.  The neat thing about Linux, is if you have a USB Host interface, and a reasonably modern kernel, you can use off-the-shelf USB-&amp;gt;Network devices for Ethernet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-provide-a-fast-way-for-the-bootloader-to-download-sw-updates&quot;&gt;#4 Provide a fast way for the bootloader to download SW updates&lt;&#x2F;h3&gt;
&lt;p&gt;This is important.  Don’t depend on JTAG or a serial port for programming large OS images.  Some options for BL image download include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;network (preferred)&lt;&#x2F;li&gt;
&lt;li&gt;MMC&#x2F;SD&lt;&#x2F;li&gt;
&lt;li&gt;USB Client&lt;&#x2F;li&gt;
&lt;li&gt;USB Host (using a USB Mass storage device)&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA&#x2F;CF&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The good news is if you did steps #2 &amp;amp; #3, this might be taken care of – just make sure you check what the bootloader actually supports.  One project I worked on recently only had a serial interface and a USB client interface that the BL did not support.  We ended up creating a mini rootfs that included just enough smarts to download the main rootfs over the USB Client interface.  So, there are ways to work around some of these issues, but its a lot easier if you do a little planning up front.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;There is a lot to be said for using industry standard interfaces and components like Linux, USB, and Ethernet.   When you design a system using standard building blocks, your product will have the flexibility to implement features you never thought of when the product was originally designed.  And, your development and testing will go so much smoother.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Open JTAG debugging tool for the PXA270</title>
        <published>2007-07-10T00:00:00+00:00</published>
        <updated>2007-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/"/>
        <id>https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/</id>
        
        <content type="html" xml:base="https://bec-systems.com/242/open-jtag-debugging-tool-for-the-pxa270/">&lt;p&gt;Looking for a low cost, high functionality JTAG solution for the PXA270?  As of several weeks ago, the openocd project now works with the Intel&#x2F;Marvell PXA270 processor.  There are a number of USB based JTAG debuggers available for under $100, so the cost is minimal.  This article provides a brief overview of JTAG, suggestions for your hardware design, and how to use OpenOCD (Open On-chip-debugger) with the PXA270.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openocd&quot;&gt;OpenOCD&lt;&#x2F;h3&gt;
&lt;p&gt;Over the past 8 years, I’ve used a number of JTAG solutions for programming and debugging embedded processor systems.  At the low end, there are JTAG solutions for flash programming only that just wiggle pins on a PC parallel port which in turn wiggle pins on the scan chain of the processor.  This way of doing things works, but is very slow because you have to fabricate the bus cycles in software and clock the entire jtag chain just to change the state of one pin.  The jtag tools from the openwince project on Sourceforge fall into this category.&lt;&#x2F;p&gt;
&lt;p&gt;More advanced JTAG tools use the debugging capability of a processor to speed up flash programming and add debugging features.  This typically involves downloading a tiny bit of code into the cache or internal SRAM in the CPU.  This bit of code then can receive blocks of data or instructions and run bus cycles directly through the memory controller in the device.  This makes flash programming very fast as most of the work is being done by the CPU, instead of manually controlling CPU pins using a jtag chain.&lt;&#x2F;p&gt;
&lt;p&gt;In past years, there have been various attempts at creating an open source JTAG solution, but none of them have gotten very far.  When I had a project that needed to get done quickly, I simply bought or upgraded a BDI2000 debugger – which is an excellent tool.  The OpenOCD project now provides much of the same functionality as a BDI2000, but as in the case of the PXA270, it sometimes takes some work to get it all working.&lt;&#x2F;p&gt;
&lt;p&gt;OpenOCD was created by Dominic Rath as part of a diploma thesis (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openocd.berlios.de&#x2F;web&#x2F;&quot;&gt;http:&#x2F;&#x2F;openocd.berlios.de&#x2F;web&#x2F;&lt;&#x2F;a&gt;).  It provides support for a wide range of target processors and JTAG debuggers.  OpenOCD includes functionality for On-Chip Debugging, In-System Programming, and Boundary-Scan Testing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hardware-design-considerations&quot;&gt;Hardware design considerations&lt;&#x2F;h3&gt;
&lt;p&gt;Although openocd has worked with other Xscale parts for some time, functionality for the PXA270 has not worked until recently.  The primary reason for this is the way the power supplies are sequenced in most PXA270 designs.  There is one supply to the PXA270 that is always on (VCC_BATT).  All of the other supplies are often kept off until reset to the processor is de-asserted and the SYS_EN and PWR_EN signals go active.  Because of this, some special considerations need to be taken during the sequencing of the reset signals, and the setting of the hold_rst bit in the PXA270 DCSR register.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure you power the JTAG connection (Pin #1 of your JTAG connector) with VCC_BATT or some power that is always active.  If you power the JTAG connector with a power supply that is controlled by the SYS_EN or PWR_EN signal, then you will loose JTAG power during the connection process and things obviously will not work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jtag-debugger-hardware&quot;&gt;JTAG Debugger Hardware&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the JTAG debugger debuggers used with OpenOCD are based on the FTDI FT2232 USB chip.   The debugger I used is the arm-usb-ocd device from Olimex.  At a cost of $80, you can’t afford not to have one.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;olimex-1.jpg&quot; alt=&quot;olimex&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openocd-installation&quot;&gt;OpenOCD Installation&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD can use two different libraries that provide access to the FTDI chip: an open source library named &lt;em&gt;libftdi&lt;&#x2F;em&gt;, and a closed source library from FTDI named &lt;em&gt;libftd2xx&lt;&#x2F;em&gt;.  I could not get the opensource libftdi library to work, so I suggest you use the FTDI library for now.  Otherwise, installation is pretty straightforward.  Find yourself a reasonably modern Linux computer and follow instructions on the following page: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openfacts.berlios.de&#x2F;index-en.phtml?title=Building_OpenOCD&quot;&gt;http:&#x2F;&#x2F;openfacts.berlios.de&#x2F;index-en.phtml?title=Building_OpenOCD&lt;&#x2F;a&gt; .  Make sure you use the &lt;em&gt;--enable-ft2232_ftd2xx&lt;&#x2F;em&gt; option when running &lt;em&gt;configure&lt;&#x2F;em&gt;.  On Ubuntu 7.04:&lt;&#x2F;p&gt;
&lt;p&gt;Install the FTDI library:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;wget http:&#x2F;&#x2F;www.ftdichip.com&#x2F;Drivers&#x2F;D2XX&#x2F;Linux&#x2F;libftd2xx0.4.13.tar.gz&lt;&#x2F;li&gt;
&lt;li&gt;mkdir libftd2xx; cd libftd2xx; tar -xzf ..&#x2F;libftd2xx0.4.13.tar.gz&lt;&#x2F;li&gt;
&lt;li&gt;sudo cp *.h &#x2F;usr&#x2F;local&#x2F;include&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;sudo cp libftd2xx.so.0.4.13 &#x2F;usr&#x2F;local&#x2F;lib&lt;&#x2F;li&gt;
&lt;li&gt;cd &#x2F;usr&#x2F;local&#x2F;lib&#x2F;; ln -s libftd2xx.so.0.4.13 libftd2xx.so; sudo ln -s libftd2xx.so.0.4.13 libftd2xx.so.0&lt;&#x2F;li&gt;
&lt;li&gt;cd &#x2F;usr&#x2F;lib; ln -s &#x2F;usr&#x2F;local&#x2F;lib&#x2F;libftd2xx.so.0.4.13 libftd2xx.so.0&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Install OpenOCD:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;sudo apt-get install build-essential&lt;&#x2F;li&gt;
&lt;li&gt;sudo apt-get install automake&lt;&#x2F;li&gt;
&lt;li&gt;sudo apt-get install autoconf&lt;&#x2F;li&gt;
&lt;li&gt;svn checkout svn:&#x2F;&#x2F;svn.berlios.de&#x2F;openocd&#x2F;trunk openocd&lt;&#x2F;li&gt;
&lt;li&gt;cd openocd&lt;&#x2F;li&gt;
&lt;li&gt;.&#x2F;configure  &lt;em&gt;--enable-ft2232_ftd2xx&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;make&lt;&#x2F;li&gt;
&lt;li&gt;sudo make install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;openocd-configuration&quot;&gt;OpenOCD Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD is configured using a configuration file.  An example is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# config for Intel PXA270
# not, as of 2007-06-22, openocd only works with the
# libftd2xx library from ftdi.  libftdi does not work.

telnet_port	3333
gdb_port	4444

interface ft2232
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15BA 0x0003
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG&amp;quot;
jtag_speed 0
# set jtag_nsrst_delay to the delay introduced by your reset circuit
# the rest of the needed delays are built into the openocd program
jtag_nsrst_delay 260
# set the jtag_ntrst_delay to the delay introduced by a reset circuit
# the rest of the needed delays are built into the openocd program
jtag_ntrst_delay 0

#use combined on interfaces or targets that can&amp;#39;t set TRST&#x2F;SRST separately
reset_config trst_and_srst separate

#jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 7 0x1 0x7f 0x7e

#target configuration
daemon_startup reset

target xscale little reset_halt 0 pxa27x

# maps to PXA internal RAM.  If you are using a PXA255
# you must initialize SDRAM or leave this option off
working_area 0 0x5c000000 0x10000 nobackup

run_and_halt_time 0 30

#flash bank &amp;lt;driver&amp;gt; &amp;lt;base&amp;gt; &amp;lt;size&amp;gt; &amp;lt;chip_width&amp;gt; &amp;lt;bus_width&amp;gt;
# works for P30 flash
flash bank cfi 0x00000000 0x1000000 2 4 0
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;programming-flash&quot;&gt;Programming Flash&lt;&#x2F;h3&gt;
&lt;p&gt;After OpenOCD is installed, copy the above config file contents to a file name openocd.cfg, and run openocd in the same directory as your configuration file.&lt;&#x2F;p&gt;
&lt;p&gt;Currently, there is an issue in that the openocd is expecting a debug handler file at a specific relative path from the openocd binary.  The easiest way to get around this for now is to to run openocd from the src directory in the openocd source code.&lt;&#x2F;p&gt;
&lt;p&gt;If you get the following message:  Error:   ft2232.c:1338 ft2232_init_ftd2xx(): unable to open ftdi device: 2, there is a permissions problem with the USB device.  To get around this, run openocd using sudo, or add the appropriate rules to udev to allow the usb device to be used by any user.&lt;&#x2F;p&gt;
&lt;p&gt;OpenOCD runs as a daemon waiting for telnet or GDB connections.  After openocd starts, you can connect to it by running the following command:  telnet localhost 3333&lt;&#x2F;p&gt;
&lt;p&gt;At this point you should be presented with a OpenOCD prompt.  The following is an example of how to program a bootloader into flash memory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; flash probe 0
flash &amp;#39;cfi&amp;#39; found at 0x00000000
&amp;gt; flash protect 0 0 5 off
cleared protection for sectors 0 through 5 on flash bank 0
&amp;gt; flash erase 0 0 5 off
erased sectors 0 through 5 on flash bank 0 in 4s 615249us
&amp;gt; flash write 0 &#x2F;build&#x2F;tmp&#x2F;u-boot-holon.bin 0
wrote 121832 byte from file &#x2F;build&#x2F;tmp&#x2F;u-boot-holon.bin to flash bank 0 at offset 0x00000000 in 6s 138592us (19.381735 kb&#x2F;s)
&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h3&gt;
&lt;p&gt;In this example, OpenOCD waits for GDB connections on port 4444.  To debug code running on the target, you would use gdb in the same way you would use a BDI2000, or most any other hardware debugger with GDB.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;OpenOCD is a robust, full-featured JTAG debug solution that supports many processors and low cost JTAG debuggers.  There are still a few rough edges to clean up with PXA270 support, but OpenOCD is already a very useful tool for embedded software development.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to control the cable nightmare</title>
        <published>2007-06-20T00:00:00+00:00</published>
        <updated>2007-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/235/how-to-control-the-cable-nightmare/"/>
        <id>https://bec-systems.com/235/how-to-control-the-cable-nightmare/</id>
        
        <content type="html" xml:base="https://bec-systems.com/235/how-to-control-the-cable-nightmare/">&lt;p&gt;Do you ever wonder if there is a better way to manage cables in your lab?  I typically have have 5-10 embedded systems on the bench powered up at any give time.  When you start thinking of all the cables required to connect these systems (every one requires at least power, serial console, and network), it starts to add up.  I recently ran across a product called snaketray (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;snaketray.com&#x2F;products&#x2F;wall.html&quot;&gt;http:&#x2F;&#x2F;snaketray.com&#x2F;products&#x2F;wall.html&lt;&#x2F;a&gt; ) and decided it might be the solution to my rats-nest of cables.  This article includes a few pictures of my implementation, and some ideas.  I’m quite pleased with the result and have high hopes that I’ll keep my sanity for a while longer.&lt;&#x2F;p&gt;
&lt;p&gt;I’m sure there are many solutions to cable management.  The IT folks managing racks of computers no doubt have lots of good solutions.  There are lots of different cable ties available, etc.  But, the needs of a developer are a little different in that you need a solution that can easily be changed.  You need something that is not permanent where you can quickly add, change, and re-route cables as needed.  Most cable management solutions are more permanent solutions not designed for flexibility.  Then I read the following article: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;BionicOffice.html&quot;&gt;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;BionicOffice.html&lt;&#x2F;a&gt;.  It occurred to me that snaketray might be the perfect solution for an embedded systems development lab.  The idea of snaketray is very simple as shown in the picture below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_1-1.jpg&quot; alt=&quot;snaketray_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I installed two runs about 1.5 feet above my lab work space.  There are power strips along the back of each lab surface.  All cables now run in the snaketray.  The idea is cables go straight into the snaketray and exit exactly where the are needed.  If the cable is too long, I loop it back in the snaketray.  The result is pretty amazing when you compare it to what it was before.  My wife is not real impressed with how it looks – apparently she has not spend enough time under tables untangling cables :-)&lt;&#x2F;p&gt;
&lt;p&gt;Some of the benefits I’ve discovered so far:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;even though it still looks pretty messy, I’m finding it very easy to pull cables out of the tray and re-route them – even network cables which are notorious for getting hung up due to the little plastic clip on the connector.  I think the reason is the cables are always running orthogonal – in the tray and the come out at a 90 degree angle where they are needed.  So if cables are not crossing each other they do not get tangled.&lt;&#x2F;li&gt;
&lt;li&gt;bench space is not used for cables, so I have lots of space for more systems&lt;&#x2F;li&gt;
&lt;li&gt;I’ll be more likely to try builds routinely on more targets.  One of my goals is to routinely do OpenEmbedded builds for a variety of embedded systems to keep my finger on the OE pulse, and help with QA.  Obviously crawling around on the floor untangling cables to connect various systems is a negative motivator for such activities.&lt;&#x2F;li&gt;
&lt;li&gt;I have a place to put cables when I’m not using them – just put them in the tray.  Before, they were left on my lab bench taking space, or falling on the floor.  Now I have a few extra network and serial cables waiting in the tray for when I need them.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The bottom line is this makes me more efficient at what I do, so that I can better serve my customers and the projects I work on.  I imagine snaketray would also be very useful in factory setups and other situation where you routinely need to change cabling.&lt;&#x2F;p&gt;
&lt;p&gt;What you you found that works in your lab?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_2-1.jpg&quot; alt=&quot;snaketray_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_3-1.jpg&quot; alt=&quot;snaketray_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;snaketray_4-1.jpg&quot; alt=&quot;snaketray_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Atmel AT32AP7000 development board review</title>
        <published>2007-06-09T00:00:00+00:00</published>
        <updated>2007-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/162/atmel-at32ap7000-development-board-review/"/>
        <id>https://bec-systems.com/162/atmel-at32ap7000-development-board-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/162/atmel-at32ap7000-development-board-review/">&lt;p&gt;I recently purchased an Atmel NGW100 development board which includes an Atmel AT32AP7000 CPU.  This CPU is based on the new Atmel AVR32 architecture, and is capable of running full Linux.  This review covers the basics of this development board, the AVR32 architecture, options for building Linux for this system, as well as opinions on how a new architecture can succeed in a field of well established architectures like ARM and MIPS.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-is-avr32&quot;&gt;What is AVR32?&lt;&#x2F;h3&gt;
&lt;p&gt;The AVR32 architecture defined by Atmel is a 32-bit RISC load&#x2F;store architecture. There are several different versions of the core.  Atmel currently supplies two classes of AVR32 cpus:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;UC3 Flash MCUs - low end devices with integrated RAM and flash, no MMU, and look similar in capability to ARM7 microcontroller type devices.&lt;&#x2F;li&gt;
&lt;li&gt;AP7 Application Processors - faster devices, include MMU, seem similar in capability and speed to ARM9 application processors such as Atmel’s AT92SAM devices.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As I am most interested in CPUs that can run Linux, this review will focus on the AP7 (AVR32 AP) class devices.&lt;&#x2F;p&gt;
&lt;p&gt;It seems that AVR32 is Atmel’s answer to ARM Cortex.  Some features of the AP7 devices:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;good code density&lt;&#x2F;li&gt;
&lt;li&gt;DSP instructions that execute in a single cycle&lt;&#x2F;li&gt;
&lt;li&gt;Full MMU&lt;&#x2F;li&gt;
&lt;li&gt;Instruction and Data caches&lt;&#x2F;li&gt;
&lt;li&gt;SIMD extensions&lt;&#x2F;li&gt;
&lt;li&gt;dynamic branch prediction&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The MMU in the AP7 devices is interesting in that page tables are handled in software similar to a MIPS device.  In a ARM CPU, the page tables are located in physical RAM and are strictly defined by the ARM architecture and page faults are handled in hardware.  With MIPS (at least some devices) and AVR32, the MMU basically consists of a TLB (Translation Lookaside Buffer) that maps virtual addresses to physical address.  As the TLB is limited in size, any misses are handled in software.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ngw100-development-board&quot;&gt;NGW100 Development board&lt;&#x2F;h3&gt;
&lt;p&gt;The NGW100 development board is available from a number of distributors (including Digikey) for about $70.  The board includes the following major components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Atmel AT32AP7000 CPU&lt;&#x2F;li&gt;
&lt;li&gt;32MB of SDRAM (MT48LC16M16A2)&lt;&#x2F;li&gt;
&lt;li&gt;8MB Parallel NOR Flash (AT49BV642D-70TU)&lt;&#x2F;li&gt;
&lt;li&gt;8MB Serial NOR Flash (AT45DB642D)&lt;&#x2F;li&gt;
&lt;li&gt;2 Ethernet ports&lt;&#x2F;li&gt;
&lt;li&gt;SD&#x2F;MMC slot&lt;&#x2F;li&gt;
&lt;li&gt;RS232 port&lt;&#x2F;li&gt;
&lt;li&gt;USB Client port&lt;&#x2F;li&gt;
&lt;li&gt;Microcontroller for board control (ATtiny24-20SSU)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;ngw100-1.jpg&quot; alt=&quot;ngw100&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-support&quot;&gt;Linux Support&lt;&#x2F;h3&gt;
&lt;p&gt;Atmel is directly supporting the development effort for the AP7 processors.  They seem to be doing it right in that they are pushing support directly into the mainstream kernel.  Currently, Atmel provide patches for GCC and uClibc.  There is already efforts underway to provide AVR32 support in Openembedded, which will enable developers to quickly build full featured Linux distributions for AVR32 based products.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;It will be interesting to see how the AVR32 based products work out.  On one hand, one could argue that a custom architecture like AVR32 can’t succeed as it does not have an extensive ecosystem of tool vendors in place like ARM and MIPS.  But, the availability of open source software such as GCC and Linux is rapidly lowering the barrier to entry for creating tools for new architectures.  No longer do you need to wait for commercial tool vendors to provide software support.  The model for software development is changing.&lt;&#x2F;p&gt;
&lt;p&gt;In comparison to Atmel’s AT91SAM parts, its difficult initially to see what the AVR32 parts offer over the SAM parts.  For one, they are lacking a USB Host port which is becoming increasingly important to have in embedded Linux systems.   Perhaps they offer other advantages such as lower cost and power.  As we gain experience with these parts, I’m sure we’ll find applications where they are an excellent fit.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Embedded Industry Transformation</title>
        <published>2007-06-09T00:00:00+00:00</published>
        <updated>2007-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/82/the-embedded-industry-transformation/"/>
        <id>https://bec-systems.com/82/the-embedded-industry-transformation/</id>
        
        <content type="html" xml:base="https://bec-systems.com/82/the-embedded-industry-transformation/">&lt;p&gt;I just ran across an interesting article written by Doug Gaff titled “&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linuxdevices.com&#x2F;articles&#x2F;AT2891246233.html&quot;&gt;Is the embedded industry dead?&lt;&#x2F;a&gt;”.  The article points out the transformation that is happening in the “embedded” industry.  For many systems, we are no longer constrained by minimal resources (&#x2F;web&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;).  Embedded Systems are no longer isolated systems, but parts of larger systems.&lt;&#x2F;p&gt;
&lt;p&gt;A few of my own observations:&lt;&#x2F;p&gt;
&lt;p&gt;There is more to modern embedded systems than control and logic.  We now have to worry about data.  In the past the task might be to get a microcontroller to run a state machine, control motors, etc.  Today, we need to present a calendar to the user through a web interface, collect information about the location of the Sun, upload statistics to a remote server, support a rich GUI application on a VGA color display.  The control aspect is suddenly the small part of the problem, and managing data is often the primary concern.&lt;&#x2F;p&gt;
&lt;p&gt;Embedded system development now encompasses many disciplines including OS development, web services, advanced application development in high level languages, and the traditional hardware debugging and low level coding tasks.  It is becoming less about writing code and more about integration of the right pieces.  As Embedded Systems become more complex, access to specialized knowledge is becoming more important.  There is just too much for one person (or even one company) to know.  Companies developing competitive products in the future will be the ones who have access to experts.
Is your company taking advantage of this transformation?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Can you afford not to use Linux in your product?</title>
        <published>2007-05-29T00:00:00+00:00</published>
        <updated>2007-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/"/>
        <id>https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/</id>
        
        <content type="html" xml:base="https://bec-systems.com/156/can-you-afford-not-to-use-linux-in-your-product/">&lt;p&gt;How much does hardware capable of running Linux cost?  Recently, I priced components for a fairly minimal system.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Atmel AT91SAM9260 (&amp;lt; $10)&lt;&#x2F;li&gt;
&lt;li&gt;32MBytes of SDRAM ($6)&lt;&#x2F;li&gt;
&lt;li&gt;256MBytes of NAND flash ($6)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These are prices for relatively low volumes on the order of 1000 pieces.  So, you can get a processor, RAM, and flash that is more than capable of running Linux for about $20.  Think about the possibilities.  The AT91SAM9260 is a rather impressive part and includes interfaces for about anything including USB, SD&#x2F;MMC, Ethernet, and the list goes on.  It also includes that capability to boot from NAND flash which eliminates a dedicated NOR boot flash and reduces cost.  If you don’t want to do a full processor design, processor modules can be obtained for &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;less than $100&lt;&#x2F;a&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;So, at this price you have to ask: can I afford not to embed Linux in my product?  Can I afford not to take advantage of standard interfaces like Ethernet and USB?  Can I afford not to take advantage of 1000’s of high quality applications and drivers?  Can I afford to not implement a system with virtually &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;content&#x2F;view&#x2F;67&#x2F;9&#x2F;&quot;&gt;unlimited storage&lt;&#x2F;a&gt; and capability for expansion?  Think about this carefully because your competitors are.  Have questions or need help getting started?  &lt;a href=&quot;https:&#x2F;&#x2F;bec-systems.com&#x2F;156&#x2F;can-you-afford-not-to-use-linux-in-your-product&#x2F;component&#x2F;option,com_contact&#x2F;Itemid,3&#x2F;&quot;&gt;Contact us&lt;&#x2F;a&gt; – we can help.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Is Linux ready for real-time applications?</title>
        <published>2007-05-12T00:00:00+00:00</published>
        <updated>2007-05-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/152/is-linux-ready-for-real-time-applications/"/>
        <id>https://bec-systems.com/152/is-linux-ready-for-real-time-applications/</id>
        
        <content type="html" xml:base="https://bec-systems.com/152/is-linux-ready-for-real-time-applications/">&lt;p&gt;Have you ever wondered about the real-time response of Linux and how well it performs?  I recently developed a system where I had the requirement to send a packet of data out a serial port every 30ms.  This article describes how stock Linux can be used to accomplish this and solutions to several problems I encountered.  There are several concepts that need to be understood such as how to set a Linux process to real-time,  and kernel preemption.&lt;&#x2F;p&gt;
&lt;p&gt;All of the work referenced in this article was done on a &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;Compulab cm-x270&lt;&#x2F;a&gt; system which is based on the PXA270 ARM processor.  Before utilizing any real-time optimizations, the packets sent out the serial port where anything but consistent.  There was a significant amount of jitter in the packet timing and occasionally we would see delays of up to several seconds.  Obviously this was not good enough.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;real-time-process-priority&quot;&gt;Real Time Process Priority&lt;&#x2F;h3&gt;
&lt;p&gt;The first step was to partition the application into several threads, and give the serial communication thread a priority of real time.  Linux supports several scheduling policies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SCHED_OTHER: default universal time-sharing scheduler policy used by most processes.&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_BATCH: intended for “batch” style execution&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_FIFO: First In-First Out scheduling. Can only be used with static priorities higher than 0.  A SCHED_FIFO process will always run before a SCHED_OTHER or SCHED_BATCH process.  A SCHED_FIFO process runs until it is blocked by an I&#x2F;O request, or is preempted by a higher priority process.&lt;&#x2F;li&gt;
&lt;li&gt;SCHED_RR: Round Robin scheduling.  SCHED_RR is similar to SCHED_FIFO, except the process will only run for a maximum time quantum if there is a process of equal priority waiting to be run.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Practically, in a simple system there is really not much difference between SCHED_FIFO and SCHED_RR as you will typically only have at most a couple real time processes and you will probably assign them different priorities.&lt;&#x2F;p&gt;
&lt;p&gt;The sched_setscheduler() system call can be used to set a process or thread priority – see the Linux man pages for more details.&lt;&#x2F;p&gt;
&lt;p&gt;After setting the communication thread to real time, there was a noticeable improvement in the packet scheduling, but there was still way too much jitter and the occasional several seconds of silence with no packets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preemptible-kernel&quot;&gt;Preemptible Kernel&lt;&#x2F;h3&gt;
&lt;p&gt;After some experimentation, and reading, it was suspected that the NAND flash driver in the system was locking the kernel for long periods of time.  With older Linux kernels, the kernel was not preemptible.  Any process running in the kernel had to finish before something else could run.  Recent 2.6 Linux kernel include an option to enable Kernel Preemption (CONFIG_PREEMPT).   This allows a real-time process to preempt the system even if it is running in kernel space.   After enabling the CONFIG_PREEMPT option in the kernel, the scheduling of packets was very consistent most of the time with almost no perceptible jitter.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;be-careful-what-you-put-in-your-real-time-thread&quot;&gt;Be careful what you put in your real-time thread&lt;&#x2F;h3&gt;
&lt;p&gt;Now the system was running fairly well, but we still noticed at system startup that there were still some long delays between packets.  It turns out the application was writing log messages to a file on NAND flash in the real-time thread using the standard glib logging functions.  At system startup, the NAND driver blocks for long periods of time (up to several seconds).  After the system has been running for a short time, this went away.  The solution in this case was to send any logging messages from the communication thread to a separate normal priority logging thread.  This fixed any remaining issues and the packet scheduling is now rock solid all the time.  The leads to an fundamental real-time concept which seems very obvious in hindsight:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Do not access any I&#x2F;O (such as storage or network interfaces) that may block for long periods of time****in a real time process.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Although we had designed all the primary I&#x2F;O to be handled this way, we had not given any consideration to log file writes, which are an important part of any program.&lt;&#x2F;p&gt;
&lt;p&gt;The glib library provides several very nice mechanisms for sending data between threads.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-real-time&quot;&gt;Linux Real-time&lt;&#x2F;h3&gt;
&lt;p&gt;With improvements in the 2.6 Linux kernel, Linux works very well for some real-time applications.  While I would still be very careful in using Linux for critical, hard-real time requirements due to its overall complexity, Linux works very well for multi-media, communication, and data acquisition systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND Flash is almost &quot;free&quot; and what it means for Embedded Systems</title>
        <published>2007-02-26T00:00:00+00:00</published>
        <updated>2007-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/149/nand-flash-is-almost-free/"/>
        <id>https://bec-systems.com/149/nand-flash-is-almost-free/</id>
        
        <content type="html" xml:base="https://bec-systems.com/149/nand-flash-is-almost-free/">&lt;p&gt;&lt;em&gt;original article p&lt;&#x2F;em&gt;ublished in March, 2007&lt;&#x2F;p&gt;
&lt;p&gt;EETimes recently ran an article titled “Plummeting prices make NAND appear almost free” (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.eetimes.com&#x2F;news&#x2F;latest&#x2F;showArticle.jhtml?articleID=197002923&quot;&gt;http:&#x2F;&#x2F;www.eetimes.com&#x2F;news&#x2F;latest&#x2F;showArticle.jhtml?articleID=197002923&lt;&#x2F;a&gt;).  1GBytes parts cost around $55 in Nov 2005. As of 2007-03-28, a 1GBytes part costs around $8.  This is almost an order of magnitude reduction in a little over a year.  This article examines the impact this price drop will have on embedded systems and the changes we will likely see including: storage is now at post-scarcity, will “embedded” distributions become obsolete, will uclibc become obsolete, and challenges with large NAND flash parts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-major-components-in-an-embedded-computer&quot;&gt;3 major components in an embedded computer&lt;&#x2F;h3&gt;
&lt;p&gt;The 3 major components in an embedded computer are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;processor&lt;&#x2F;li&gt;
&lt;li&gt;RAM&lt;&#x2F;li&gt;
&lt;li&gt;Flash Storage&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All of these components have been gradually decreasing in price over the years, and there has been a corresponding gradual increase in the use of complex embedded systems.  However, the drop in NAND flash in the last year represents more of a step change, and will likely result in some more drastic changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;we-are-to-the-point-of-post-scarcity-for-flash-storage&quot;&gt;We are to the point of post-scarcity for Flash storage&lt;&#x2F;h3&gt;
&lt;p&gt;Up to this point, most full featured embedded Linux systems contained 16-64MB of NOR flash.  A full featured graphical Linux terminal requires about 20-30MB of flash disk space just for applications and libraries.  So, in the past we were still concerned about application footprint.  The was a lot of incentive to not cross the 32MB to 64MB boundary, etc.  With 1GiB of flash now costing less than $10, we essentially have unlimited flash storage in the context of an embedded Linux distribution.  We will probably see the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;faster time to market as we need to spend less time optimizing&lt;&#x2F;li&gt;
&lt;li&gt;increased use of GTK+ as the standard GUI toolkit.  We no longer care how much space GTK+ takes.&lt;&#x2F;li&gt;
&lt;li&gt;more debugging features can be left in the production system.  Why not leave VIM, Minicom, and SSH in the build if we have plenty of space.  These non-critical features will lower the cost of maintaining a product.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;will-embedded-distributions-become-obsolete&quot;&gt;Will “embedded” distributions become obsolete?&lt;&#x2F;h3&gt;
&lt;p&gt;There has always been a great deal of interest in running Debian and other “standard” distributions in embedded systems.  With 1GiB of storage, this is going to be a lot more practical.  However, with a little experience, you soon realize that distribution size is only one of the many factors.  Another equally important factor is the ability to easily automate the build process for the entire project, including custom applications and image generation for programming.  With complex systems like Linux, it is easy to get into the hack-n-slash mode where it takes a lot of manual steps to build the system.  While this may seem OK when you building the system, it ends up causing a lot of pain and errors once you get in a hurry, of down the road when you are trying to maintain the system.  Ability to easily customize the distribution is another requirement.  OpenEmbedded (http:&#x2F;&#x2F;openembedded.org), and other build systems provide these features.  I think we will see a big increase in Debian and other standard Linux distributions in Embedded systems, but OpenEmbedded and other embedded build systems will continue to grow in use as well because there are many factors in the equation.  This is the nice thing about open source – use what works best for you.&lt;&#x2F;p&gt;
&lt;p&gt;Building and maintaining an embedded system is a lot different than setting up and maintaining a desktop or server system.  Other articles related to this topic include: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&lt;&#x2F;a&gt; and &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;will-uclibc-become-obsolete&quot;&gt;Will uclibc become obsolete?&lt;&#x2F;h3&gt;
&lt;p&gt;Because flash is now cheap, why do we need to use uclibc (small footprint libc) – can’t we just use glibc.  For full featured embedded Linux systems, this argument makes sense.  However, there is push toward higher integration at the low end.  Many companies are offering 32-bit “microcontrollers” with integrated flash and RAM.  The processors in these devices are more than capable of running Linux.  The limitation to date has been the RAM and Flash size.  The available memory in 32-bit microcontrollers will increase over time enabling them to run a low end uclibc based system.  The idea of running Linux on a system that is composed of a single chip is very interesting.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;challenges-with-large-nand-flash-parts&quot;&gt;Challenges with large NAND flash parts&lt;&#x2F;h3&gt;
&lt;p&gt;What challenges will using large NAND parts present?  In general, dealing with NAND is a lot more complex than with NOR flash.  For reading, NOR parts present a simple memory mapped interface.  A NAND interface is not memory mapped and looks more like a FIFO or a Hard Drive interface.  This makes booting from NAND flash much more difficult.  Some parts present a memory mapped interface for an initial loader.  Some processors build NAND flash bootloading into the processor.  Other systems boot from a small NOR flash and use NAND after the system has booted.&lt;&#x2F;p&gt;
&lt;p&gt;Filesystems are also a challenge with NAND flash.  The standard method is to use JFFS2 which was designed for smaller NOR parts.  JFFS2 works well, but is a log based filesystem.  This means it has to scan the entire file system on mount and store the entire inode chain in memory.  This takes lots of time and uses lots of RAM.  For small devices (64MB), this is tolerable, but for large devices the mount time can take 10’s of seconds.   YAFFS2 is another log based flash filesystem designed specifically for NAND flash which includes a feature called checkpointing that bypasses the normal mount scanning.  Another development is LogFS which looks promising, but will probably not be ready until mid&#x2F;late 2007.&lt;&#x2F;p&gt;
&lt;p&gt;Programming NAND flash can also be a challenge.  Because NAND flash can contain bad blocks, programming is a lot more complex.  Traditionally, flash programming in a NOR system was done by the bootloader.  For a system that boots from NOR flash, programming the NAND flash can be done from a small Linux system (see &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;66&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;66&#x2F;9&#x2F;&lt;&#x2F;a&gt;).  If you are booting from NAND flash, programming may be done with a JTAG programmer that supports NAND flash, or by downloading a small bit of bootstrap code into the processors internal memory using JTAG, and this bootstrap code then has enough functionality to program the NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The lower NAND prices will bring about change in the way embedded systems are built.  Please comment if you have addtional ideas or observations.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Do you need &quot;software update&quot; functionality in your Embedded Linux system?</title>
        <published>2007-02-21T00:00:00+00:00</published>
        <updated>2007-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/146/do-you-need-software-update/"/>
        <id>https://bec-systems.com/146/do-you-need-software-update/</id>
        
        <content type="html" xml:base="https://bec-systems.com/146/do-you-need-software-update/">&lt;p&gt;In this day and age, most embedded systems include a way for users to easily update software once the device has been deployed.  This article discusses the requirements for a field update mechanism along with pointers for how to implement.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;update-mechanism-requirements&quot;&gt;Update Mechanism Requirements&lt;&#x2F;h3&gt;
&lt;p&gt;Requirements for a field update mechanism might be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;easy for users to perform updates.&lt;&#x2F;li&gt;
&lt;li&gt;little chance of “bricking” a unit if reset occurs during update.&lt;&#x2F;li&gt;
&lt;li&gt;ability to update all of the software in the unit&lt;&#x2F;li&gt;
&lt;li&gt;in this case, update from files on a USB Storage device&lt;&#x2F;li&gt;
&lt;li&gt;ability to program NOR and NAND flash&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other systems may have requirements to update from a network, Compact Flash card, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-usb-wrinkle&quot;&gt;The USB wrinkle&lt;&#x2F;h3&gt;
&lt;p&gt;System update is typically done by the bootloader.  In this case, we are using a Compulab cm-x270 module (&lt;a href=&quot;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&quot;&gt;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&lt;&#x2F;a&gt;) that has a proprietary boot loader and does not support updates from a USB storage device.  Therefore, we need to run the updates from the context of the Linux operating system which has drivers for USB and the NAND flash.  We decided that the best way in this case is to have a small Linux OS image that contains enough functionality to update the main filesystem.  This also provides us with the capability to recover if the main filesystem ever gets corrupted.  The flash layout for the system is:&lt;&#x2F;p&gt;
&lt;table border=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt; Partition&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Flash Device&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Size&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;File System&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt; Description&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel&lt;&#x2F;td&gt;
&lt;td&gt;NOR&lt;&#x2F;td&gt;
&lt;td&gt;1536KiB&lt;&#x2F;td&gt;
&lt;td&gt;NA&lt;&#x2F;td&gt;
&lt;td&gt;Linux kernel&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Update rootfs&lt;&#x2F;td&gt;
&lt;td&gt;NOR&lt;&#x2F;td&gt;
&lt;td&gt;2304KiB&lt;&#x2F;td&gt;
&lt;td&gt;Initramfs (RO)&lt;&#x2F;td&gt;
&lt;td&gt;Small rootfs that contains just enough functionality to update the system&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Main rootfs&lt;&#x2F;td&gt;
&lt;td&gt;NAND&lt;&#x2F;td&gt;
&lt;td&gt;512MiB&lt;&#x2F;td&gt;
&lt;td&gt;JFFS2 (RW)&lt;&#x2F;td&gt;
&lt;td&gt;Main rootfs including application&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;There are other schemes that could work as well.  One way might be to have two identical application partitions and only update one at a time.  A reset while updating the kernel or the update rootfs does have the potential of “bricking” the system, but most of the updates will be for the Main rootfs, so we think this risk is low enough to be acceptable in this system.  The update rootfs is loaded into RAM before it is used, so there is little chance of it being corrupted during normal operation.  Running the update rootfs from ram is also convenient in that we can easily re-program the update rootfs in flash as we are not directly mounting the filesystem in flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;building-the-update-rootfs&quot;&gt;Building the Update rootfs&lt;&#x2F;h3&gt;
&lt;p&gt;The base update rootfs is built with OpenEmbedded as described in &lt;a href=&quot;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&quot;&gt;&#x2F;77&#x2F;compulab-cm-x270-pxa270-module-review&#x2F;&lt;&#x2F;a&gt;.  Once we had the system booting into the update rootfs, we had to add the following functionality:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Boot the main rootfs from NAND flash&lt;&#x2F;li&gt;
&lt;li&gt;look for update files on a USB Storage device and flash the kernel, update rootfs, and main rootfs as needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Booting the NAND flash image is accomplished using the busybox &lt;em&gt;switch_root&lt;&#x2F;em&gt; application.  This utility allows you to easily switch to another rootfs from an initramfs.  There are a few gotchas to be aware of when working with switch_root:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;switch_root must be “exec’d” from the init process with PID=“1”.&lt;&#x2F;li&gt;
&lt;li&gt;switch_root requires a “&#x2F;init” file to be present&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above functionality was accomplished by writing a shell script called &#x2F;init.  If an error occurs, the &#x2F;init shell script then launches the standard init process in &#x2F;sbin&#x2F;init which provides a terminal and allows for easy debugging.  The mtd-utils package provides a handy utility called &lt;em&gt;nandwrite&lt;&#x2F;em&gt; which can be used to write jffs2 images to NAND flash (handles bad blocks, etc).  At some point, we may remove all the extra functionality from the update rootfs like the standard sysvinit, terminal login, etc, but for now it is handy to have for debugging.  To give you an idea how easy it is to write to flash from a shell script, consider the following snippets:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# write Image into update rootfs parition
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;cat &#x2F;usb&#x2F;nor_rootfs.img &amp;gt; &#x2F;dev&#x2F;mtd2
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# write Image to NAND rootfs partition
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;flash_eraseall &#x2F;dev&#x2F;mtd3
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;nandwrite &#x2F;dev&#x2F;mtd3 &#x2F;usb&#x2F;nand_jffs2.img
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;# and to launch rootfs in nand flash
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;exec switch_root -c &#x2F;dev&#x2F;console &#x2F;jffs2 &#x2F;sbin&#x2F;init 5
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Having typically used bootloaders for system update in the past, I’m very pleased with how this mechanism worked out.  Thanks to the flexibility of Linux and OpenEmbedded, this only took several days to implement and debug.  Writing update programs with shell scripts at the application level gives you a lot of flexibility and allows you to use standard Linux drivers for USB and Flash access which are very robust.  At some point if there is interest, we may look at cleaning up our code and contributing functionality to OpenEmbedded to generate a more generic update initramfs.  Please contact us or leave a comment if you are interested in collaborating on something like this.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a tiny &quot;safe&quot; boot image using OpenEmbedded</title>
        <published>2007-02-16T00:00:00+00:00</published>
        <updated>2007-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/"/>
        <id>https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/143/building-a-tiny-safe-boot-image-using-openembedded/">&lt;p&gt;We are currently working a project that contains cm-x270 module (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;62&#x2F;9&#x2F;&lt;&#x2F;a&gt; ) which contains 4MB of NOR flash and 128MB of NAND flash.  The Linux kernel and a small root file system (rootfs) will be stored in NOR flash, and the main rootfs in the NAND flash.  The rootfs in the NOR flash will be used to update the system from a USB Flash drive in the field.  This article describes how to build a small boot rootfs using OpenEmbedded.  We also look at various ways to store the image in flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirments&quot;&gt;Requirments&lt;&#x2F;h3&gt;
&lt;p&gt;In many embedded systems, field upgrades is a requirement.  There are many ways to organize this, but one of the most reliable is to have two rootfs partitions.  The first partition is a “safe” rootfs that is only used to update the second partition.  The second partition contains the main application and can be updated in the field.  If a programming error, or power loss occurs while updating the 2nd partition,  you can always boot into the first rootfs partition and restart the process.&lt;&#x2F;p&gt;
&lt;p&gt;The kernel and the bootloader in this system take up about 1.5MB (out of 4MB total) of the NOR flash.  This leaves us with about 2.5MB for the update rootfs.  Because we are building the rest of the system using OpenEmbedded (OE), it may make sense for us to also build this update rootfs using OE to keep everything in one build environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uclibc-glibc-or-klibc&quot;&gt;uclibc, glibc, or klibc?&lt;&#x2F;h3&gt;
&lt;p&gt;There are several libc libraries that are commonly used to build Embedded Linux systems.  glibc is the standard that is used in desktop and sever systems and is what is being used in the main NAND rootfs partition.   uclibc is smaller than glibc is often used in space constrained systems.  klibc is a very minimal libc subset that supports operations typically used in an initramfs.  Because we are already using glibc, we decided to try this first as we could then use the same toolchain and build tree and just generate two images – one for NAND, and one for NOR.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openembedded-support-for-small-images&quot;&gt;OpenEmbedded support for small images&lt;&#x2F;h3&gt;
&lt;p&gt;OE includes a &lt;strong&gt;task-base-minimal&lt;&#x2F;strong&gt; meta target that can be used as a basis for a small images, or you can create your own based on task-base.  You will then need to create a custom image recipe that will use this meta task.  An example is shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;PR = &amp;quot;r0&amp;quot;

export IMAGE_BASENAME = &amp;quot;svs_nor&amp;quot;
export PACKAGE_INSTALL = &amp;quot;task-min&amp;quot;
# keep extra language files from being installed
export IMAGE_LINGUAS = &amp;quot;&amp;quot;

RDEPENDS = &amp;quot;task-min&amp;quot;

IMAGE_FSTYPES = &amp;quot;tar jffs2 ext2 cramfs squashfs squashfs-lzma cpio.gz&amp;quot;
IMAGE_ROOTFS_SIZE_ext2=&amp;quot;10240&amp;quot;

#EXTRA_IMAGECMD_jffs2=&amp;quot;--pad=0x1000000 --eraseblock=0x40000&amp;quot;
EXTRA_IMAGECMD_jffs2=&amp;quot;&amp;quot;

inherit image
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, I had defined a custom recipe for task-min based on task-base, which installs the following packages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;root@compulab-pxa270:~$ ipkg list_installed
base-files - 3.0.14-r58 -
base-passwd - 3.5.9-r2 -
busybox - 1.2.1-r11 -
initscripts - 1.0-r86 -
ipkg - 0.99.163-r1 -
ipkg-collateral - 1.0-r5 -
libc6 - 2.5-r4 -
libgcc1 - 4.1.1-r10 -
libipkg0 - 0.99.163-r1 -
makedevs - 1.0.0-r2 -
sysvinit - 2.86-r32 -
sysvinit-inittab - 2.86-r32 -
sysvinit-pidof - 2.86-r32 -
task-min - 1.0-r1 -
tinylogin - 1.4-r3 -
update-rc.d - 0.7-r0 -
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;storing-the-nor-filesystem-in-flash&quot;&gt;Storing the NOR filesystem in flash&lt;&#x2F;h3&gt;
&lt;p&gt;OE can generate images for many different flash filesystems and initrd mechanisms.  These are specified in the &lt;strong&gt;IMAGE_FSTYPES&lt;&#x2F;strong&gt; variable in the above recipe.  In this case, I chose to generate many different filesystems so I could see evaluate how much compression I would get with each filesystem type.  The results:&lt;&#x2F;p&gt;
&lt;table style=&quot;height: 173px;&quot; border=&quot;0&quot; width=&quot;232&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rootfs Type&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;strong&gt;Size (bytes)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;squashfs-lzma&lt;&#x2F;td&gt;
&lt;td&gt;1785856&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;tar.bz2&lt;&#x2F;td&gt;
&lt;td&gt;1918243&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;cpio.gz&lt;&#x2F;td&gt;
&lt;td&gt;2024558&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;squashfs&lt;&#x2F;td&gt;
&lt;td&gt;2109440&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;cramfs&lt;&#x2F;td&gt;
&lt;td&gt;2265088&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;jffs2&lt;&#x2F;td&gt;
&lt;td&gt;2455396&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;ext2 (uncompressed)&lt;&#x2F;td&gt;
&lt;td&gt;5481000&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;I ended up choosing the cpio.gz format as it can be loaded directly into an initramfs filesystem by the kernel.   There are several advantages to using an initramfs for this task:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You don’t have to mess around setting up tmpfs filesystems for directories that need to be writable.&lt;&#x2F;li&gt;
&lt;li&gt;You can update the NOR flash partition while you are running out of the initramfs filesystem.&lt;&#x2F;li&gt;
&lt;li&gt;It is fairly small with only squashfs-lzma being smaller.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;future-optimizations&quot;&gt;Future Optimizations&lt;&#x2F;h3&gt;
&lt;p&gt;For now, the glibc based solution is &lt;em&gt;good enough&lt;&#x2F;em&gt; because it fits in the flash space we have and it is easy to build with our existing build environment.  In the future, we may move to a uclibc or klibc based solution and try to reduce our flash size (OpenEmbedded supports both klibc and uclibc).  The above image sizes can also be reduced by removing ipkg and other components that are not needed.&lt;&#x2F;p&gt;
&lt;p&gt;This exercise illustrates many of the advantages of Linux and OpenEmbedded.  With very little work, I can produce exactly what I need.  The ability of the 2.6 Linux kernel to load a cpio archive into an initramfs is a very elegant solution for small boot images.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compulab cm-x270 PXA270 module review</title>
        <published>2007-01-30T00:00:00+00:00</published>
        <updated>2007-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/"/>
        <id>https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/77/compulab-cm-x270-pxa270-module-review/">&lt;p&gt;We are in the process of supporting a customer who is designing a product that uses the Compulab cm-x270 “Computer-on-module”.  The cm-x270 is a small computer module 66x44x7mm that contains an Intel PXA270 ARM processor similar to those found in many PDAs or smart phones.  This review provides an overview of the cm-x270, why it was selected, and how we are using it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;project-needs&quot;&gt;Project Needs&lt;&#x2F;h3&gt;
&lt;p&gt;For this project, we needed a low cost embedded computer that could drive a VGA (640x480) color display.  The graphical user interface for the device was fairly advanced, so we were also looking at a system that could run a modern OS with an advanced graphical toolkit.  After discussing the display requirements with the customer, we concluded that we needed a 32-bit processor with a LCD display controller.  As there was some custom circuitry needed, a configuration where the customer could design a custom baseboard and use an off-the-shelf computer module seemed optimal.  The schedule was also very aggressive and we did not have the time or budget to develop a full custom processor board.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cm-x270&quot;&gt;CM-X270&lt;&#x2F;h3&gt;
&lt;p&gt;After researching a number of computer modules, we chose the cm-x270 from Compulab.  The cm-x270 is a module that includes the following components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Intel PXA270 ARM processor (up to 520Mhz)&lt;&#x2F;li&gt;
&lt;li&gt;802.11b Interface&lt;&#x2F;li&gt;
&lt;li&gt;up to 128MB SDRAM&lt;&#x2F;li&gt;
&lt;li&gt;128-512MB NAND flash&lt;&#x2F;li&gt;
&lt;li&gt;up to 4MB NOR flash&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA&lt;&#x2F;li&gt;
&lt;li&gt;PCI&lt;&#x2F;li&gt;
&lt;li&gt;Serial Ports&lt;&#x2F;li&gt;
&lt;li&gt;Touch panel controller (UCB1400)&lt;&#x2F;li&gt;
&lt;li&gt;Host and Slave USB&lt;&#x2F;li&gt;
&lt;li&gt;and other features …&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For more details visit the compulab web site (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;http&#x2F;&#x2F;www.compulab.co.il&quot;&gt;http:&#x2F;&#x2F;http:&#x2F;&#x2F;www.compulab.co.il&lt;&#x2F;a&gt; ).  The cm-x270 provides a very impressive number of features in a very small space.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a picture of the cm-x270 mounted on the Compulab SBC-X270 baseboard with a VGA display.  The system is running the GPE Palmtop Environment built with OpenEmbedded.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;cm-x270-002-1.jpg&quot; alt=&quot;cm-x270-002&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;low-cost&quot;&gt;Low Cost&lt;&#x2F;h3&gt;
&lt;p&gt;Perhaps the most impressive feature of the cm-x270 is the cost.  When ordering in volume, Compulab will build the module with only the components you need.  For prototyping, you can order a standard offering with all components populated.  Starting a price of $50, it is the lowest cost module we found.  The configuration we will be using costs around $98 in 2K quantities (64MB DRAM, 4MB NOR Flash, 512MHz + 128MB NAND Flash + Audio&#x2F;Touchscreen + RTC).  Eventually, we may be able to reduce some of the features and get the price down around $70 per module.&lt;&#x2F;p&gt;
&lt;p&gt;At this price, the cm-x270 provides a very cost effective way to develop a low volume product (a few thousand per year) with advanced features provided by the PXA270 processor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;&#x2F;h3&gt;
&lt;p&gt;The bootloader and hardware design of the cm-x270 is proprietary.  Compulab does not supply schematics for the design or source code to the bootloader.  The documentation provided is adequate and provided all the information we needed to complete the design.  Compulab also provides schematics for their development baseboard, which is helpful.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bootloader&quot;&gt;Bootloader&lt;&#x2F;h3&gt;
&lt;p&gt;The cm-x270 bootloader provides typical features found in an embedded processor bootloader, including: a serial console, NAND and NOR flash programming, download images from a tftp server, downloading images over a USB connection to a PC, and a number of other configuration commands.  The tftp download works very well and is fast.  The USB download is much slower, but is convenient for systems that do not have a network connection.  The USB download requires a windows PC with a specific version of Microsoft ActiveSync installed, which is unfortunate.  A more general solution that uses something like libusb (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;libusb.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;libusb.sourceforge.net&#x2F;&lt;&#x2F;a&gt;) instead of ActiveSync would be preferred as it could then run on both Windows and Linux computers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-support&quot;&gt;Linux Support&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides a fairly complete port of the 2.6.16 Linux kernel for the cm-x270 in the form of a kernel patch.  Most of the peripherals we tested seem to work with the following exceptions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The SD card driver is not preempt safe.  In this application, we need kernel preemption turned on to meet certain real-time requirements.&lt;&#x2F;li&gt;
&lt;li&gt;The Touch driver contains a small bug that does not allow applications using it to exit properly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Overall, support is pretty good and enabled us to get started with development quickly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nand-flash-driver&quot;&gt;NAND Flash Driver&lt;&#x2F;h3&gt;
&lt;p&gt;As the Compulab module only provides 4MB of NOR flash, using the NAND flash is a requirement when implementing a full featured Linux system with an advanced graphical user interface.  Compulab provides a binary module that is linked into a kernel driver to support the NAND flash.  This driver provides a block interface on which standard filesystems like ext2 can be used.  The NAND driver has worked fairly well, although we have seen several cases where we get I&#x2F;O errors if we remove power to the device without shutting down the system properly.  The way to recover is to do a low level format the NAND flash.  This should not be an issue with this product as we will have a backup battery that will be used to power the system during shutdown if power is removed.  We may eventually move to an open source JFFS2 flash driver as time permits.&lt;&#x2F;p&gt;
&lt;p&gt;The proprietary NAND driver presents an additional wrinkle in that the driver cannot be linked into the kernel due to GPL licensing requirements.  One solution is to boot a small root file system from NOR flash that includes the NAND driver module, and then proceed to boot from NAND flash.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gnu-linux-root-file-system&quot;&gt;GNU&#x2F;Linux Root File System&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab provides an example root file system (I think based on Debian) and suggests using scratchbox to build applications.  We looked at it briefly, but then decided to build our own rootfs using OpenEmbedded for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We can easily add additional packages from the extensive OpenEmbedded catalog as needed.&lt;&#x2F;li&gt;
&lt;li&gt;Allows us to have an rootfs independent of the module – we can more easily move to other processor modules or architectures in the future.&lt;&#x2F;li&gt;
&lt;li&gt;OpenEmbedded provides us with mechanisms for package management and building complete images that include our applications and tweaks to the OS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For more information on OpenEmbedded, read our “&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;63&#x2F;9&#x2F;&quot;&gt;Introduction to OpenEmbedded&lt;&#x2F;a&gt; “.  With OpenEmbedded, we were able to quickly build a toolchain and a root file system that included the kdrive version of Xwindows and GTK+ libraries.  This rootfs fits in less than 32MB of flash disk space, which is much smaller than Compulab’s OS image.&lt;&#x2F;p&gt;
&lt;p&gt;We have also added machine configuration files to the OpenEmbedded project to support the cm-x270: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;repo&#x2F;org.openembedded.dev&#x2F;conf&#x2F;machine&#x2F;compulab-pxa270.conf&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;repo&#x2F;org.openembedded.dev&#x2F;conf&#x2F;machine&#x2F;compulab-pxa270.conf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;design-support&quot;&gt;Design Support&lt;&#x2F;h3&gt;
&lt;p&gt;Compulab seems mainly interested in customers who are interested in purchasing modules in volume.  They do not sell low cost development boards such as LogicPD’s $500 board.  Compulab requires you to purchase a fairly high cost development system ($1900) in order to get started.  Part of this cost is to pay for Compulab’s support costs.  For companies who do not have experience designing systems with PXA270 class processors, we highly recommend getting some up-front help from someone who has experience with these systems.  Even though the module takes care of a lot of the design complexity, it helps to have a detailed understanding of the PXA270 and associated components, as you still need to interact with them.  Consulting companies like BEC Systems can provide assistance in the form of hardware design reviews and Linux OS support to accelerate projects and help avoid costly mistakes and delays.  As Compulab designs only the module, there is only so much they can do when you run into problems – as shown in the next section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;issues-encountered&quot;&gt;Issues Encountered&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, the project using the cm-x270 has gone well.  The only real challenge we have faced is a latch-up issue with the ITE PCI controller on the cm-x270 module.  It appears that this part is very sensitive to the characteristics of the 3.3V supply to the module.  After a considerable amount of debugging and testing, we were able to solve this problem with some filtering and slowing down the rise time of the 3.3V supply.  This is a good example of where a project can get difficult very quickly when things don’t work as expected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;So far, the cm-x270 has worked very well in this project.  With its low cost, it is a very attractive option for companies wanting to implement advanced functionality in their products, but don’t have the time, sales volumes, or experience to justify a full processor board design.  Feel free to post comments about your experiences using embedded computer modules.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction to OpenEmbedded part 1</title>
        <published>2007-01-12T00:00:00+00:00</published>
        <updated>2007-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/141/introduction-to-openembedded-part-1/"/>
        <id>https://bec-systems.com/141/introduction-to-openembedded-part-1/</id>
        
        <content type="html" xml:base="https://bec-systems.com/141/introduction-to-openembedded-part-1/">&lt;p&gt;This is the first in a multi-part series on the OpenEmbedded development environment.  This and subsequent articles will provide an introduction to OpenEmbedded, why to use it,  how it works, and will provide examples of how BEC has used OE in various projects.&lt;&#x2F;p&gt;
&lt;p&gt;Part 1 – Why do we need OpenEmbedded?  This article discusses some of the problems developers face when building embedded Linux systems, such as collecting the pieces needed, setting up a repeatable build environment, cross-compiling, customizing a system, and licensing issues.  Future articles will cover how OE addresses some of these issues.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;embedded-linux-complex-system&quot;&gt;Embedded Linux = Complex System&lt;&#x2F;h3&gt;
&lt;p&gt;The fundamental problem with building Embedded Linux systems is the sheer complexity.  Lets face it, there is a lot going on in a typical Embedded Linux system.  Millions of lines of code are being compiled.  Typically there are tens to hundreds of applications and libraries that need to be built.  Linux supports many different processor architectures.  The size of Linux leads to the conclusion that a good deal of automation is required to manage all this.  In my paper “Tips for Planning your Embedded Linux Project” (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ), the analogy of the Iceberg is presented.  The application specific software in the project is the part of the Iceberg that is above water – the part you see.  Most of the system (Linux and system applications) is below water – you don’t see it.   The part under water is the big unknown and has the potential to add a lot of variance to a project.  Note: this problem is not specific to Linux – any system of this complexity that is targeted to so many different applications faces the same problem.  As a side, one might ask why use Linux if it is so complex?  The answer is simple – features.  Linux has the features and device support required for many Embedded products to be competitive.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collecting-and-building-all-the-pieces&quot;&gt;Collecting and building all the pieces&lt;&#x2F;h3&gt;
&lt;p&gt;There are a lot of pieces of software that need to come together to build an Embedded Linux system.  This may include a toolchain, kernel, system libraries, and many system applications and configuration scripts required to make a system work.  The is not something you want to do manually, or building an embedded Linux system quickly becomes impractical for most developers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;repeatable-builds&quot;&gt;Repeatable Builds&lt;&#x2F;h3&gt;
&lt;p&gt;With any software project, it is highly desirable to have a build system that is easily repeatable – which means it can be reproduced at any time on a wide variety of development workstations.  Some of the of the situations I have run into that are less than desirable are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Being dependent on a vendor to provide a pre-compiled root file system image for a system.  What happens when you need to add something two years down the road (such as foreign language support) and you don’t have a build system where you can easily reproduce the current build?&lt;&#x2F;li&gt;
&lt;li&gt;Being dependent on a golden build machine that takes a lot of work to set up and is very difficult to reproduce.  If you have a build environment where all the developers use one machine to build software, you may want to investigate if you are in this situation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What is really needed is a build system where you can check the build system out of a source control system onto about any Linux workstation at any point in time, type make, and a few hours later you have an image.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gpl-compliance&quot;&gt;GPL Compliance&lt;&#x2F;h3&gt;
&lt;p&gt;If you distribute binaries in your product compiled from GPL software, you must offer to provide the source code for these binaries.   Do you have easy access to the source for everything that is in your product?  Do you even know what all is in your product?  It is not good enough to simply point to someone else’s distribution or web site and say “I use that”.  As the founder of the MEPIS distribution &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;software.newsforge.com&#x2F;article.pl?sid=06&#x2F;06&#x2F;23&#x2F;1728205&amp;amp;tid=150&quot;&gt;discovered&lt;&#x2F;a&gt;, the GPL license explicitly states the distributor of the GPL code is obligated to provide source code for up to 3 years.  So if you build a distribution by copying binaries from a pre-build distribution, you may have a problem.  In one case I am familiar with, a company was in the last stages of a multi-year product development cycle.  They then discovered that they did not have the source code used to build the GPL binaries in the system.  The company that built the distribution for them was out of business and the open source project the binaries where originally obtained from no longer maintained the sources.  Although it may be possible to find all of the old sources, it is a huge amount of work and would probably be easier to just start over and build new distribution.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;customizing-the-system&quot;&gt;Customizing the system&lt;&#x2F;h3&gt;
&lt;p&gt;For most embedded systems, the distribution needs to be customized.  There are often requirements such as custom software update schemes.  Ideally, a good build system should easily allow you to integrate changes into the build system in a automated way, so that you don’t have any manual steps in the process of creating an image for the embedded system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cross-compiling&quot;&gt;Cross Compiling&lt;&#x2F;h3&gt;
&lt;p&gt;The above “repeatable build” requirement that you be able to build an image for your embedded target on about any Linux workstation leads to a requirement for cross-compiling.  Cross-compiling is the process of creating executable code for a platform different than the one on which the cross compiler is run (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross_compiler&quot;&gt;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross_compiler&lt;&#x2F;a&gt;).  Cross compiling many standard open source applications and libraries can be difficult on a good day, and near impossible on a bad day, as many of them were not written with cross compiling in mind.  Therefore, a good build environment should have tools that automate the process of cross-compiling as well as provide the ability to easily cross compile the many common programs and libraries that may be needed in an embedded Linux system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;As we examine some of the challenges, it should be obvious that putting together a production embedded Linux system is not something to be done in an ad-hoc fashion.  There are several ways to approach this problem.  Stay tuned for future articles where we explore how the OpenEmbedded build system solves these problems (subscribing to our blog or newsletter is a good way to do this).&lt;&#x2F;p&gt;
&lt;p&gt;Also, please post comments about your experiences – we like to hear and learn from you.  We are also interested in what problems you face when building Embedded systems.  This input will be used when writing future articles.  Thanks!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Remote access for embedded systems behind a firewall</title>
        <published>2006-12-19T00:00:00+00:00</published>
        <updated>2006-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/"/>
        <id>https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/</id>
        
        <content type="html" xml:base="https://bec-systems.com/137/remote-access-for-embedded-systems-behind-a-firewall/">&lt;p&gt;When deploying embedded systems, wouldn’t it be nice if you could easily set up remote access for troubleshooting and updates?  With Embedded Linux systems, this is quite easy to do.  This article will explore how to use SSH to set up remote access to an embedded system behind a firewall without using VPN or special network setup and presents a few tips for making this setup work well.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;With today’s complex embedded systems, testing and deployment can be a challenge.   During the initial testing and roll-out, a new system may need to be carefully monitored to assure it is operating correctly.  Embedded Systems programming is different than application programming in that often you are interfacing with external I&#x2F;O.  The behavior of things external to the embedded system are often very difficult to model during development; therefore time must be spent in the field testing the system in real-world situations.  Being able to remotely access the system during testing is very convenient.&lt;&#x2F;p&gt;
&lt;p&gt;As with most networked computer systems, networked embedded systems are typically deployed on a network behind a firewall. It is very easy to log in and administer any Linux system you have direct network access to – the challenge is getting to a system behind a firewall.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;options-for-remote-access&quot;&gt;Options for remote Access&lt;&#x2F;h3&gt;
&lt;p&gt;There are several general options for remote access to networks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;VPN&lt;&#x2F;li&gt;
&lt;li&gt;Port forwarding at the firewall&lt;&#x2F;li&gt;
&lt;li&gt;PC remote access technologies.  These are typically single session type connections that are initiated by the PC user.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The disadvantage of the above technologies is they require involvement from the IT department or users of the remote network.  BEC is currently involved in the deployment of a system that uses embedded computers in six different buildings.  Each building has its own firewalled network.  Getting remote access to all of these networks is a big task and everyone is busy.  An ideal solution would be a way to communicate directly with each embedded computer from a central location, which brings us to SSH …&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ssh&quot;&gt;SSH&lt;&#x2F;h3&gt;
&lt;p&gt;SSH (Secure Shell) is a set of standards and an associated network protocol that is used to establish a secure channel between a local and remote computer.  SSH encrypts all traffic (including passwords) and is generally considered to be very secure if used properly.  Some uses for SSH are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;remote terminal access.&lt;&#x2F;li&gt;
&lt;li&gt;transfer files between computers.&lt;&#x2F;li&gt;
&lt;li&gt;tunnelling and port forwarding between computers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The fact that SSH can be used to forward ports over an encrypted tunnel is what makes remote access possible using what is called a &lt;strong&gt;Reverse SSH&lt;&#x2F;strong&gt; tunnel.  Because the embedded system is behind a firewall with no direct access from the Internet, the connection must be initiated from the embedded system.   A reverse SSH tunnel is set up as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the embedded systems make a SSH connection to an external server that is internet accessible.&lt;&#x2F;li&gt;
&lt;li&gt;The SSH connection is set up so that a port on the external server (let’s pick 2900) is forwarded back over the SSH tunnel to port 22 (port used for SSH) on the embedded system.&lt;&#x2F;li&gt;
&lt;li&gt;The developer connects to 2900 on the external server using SSH.  Because port 2900 on the external server gets forwarded over the SSH tunnel to port 22 of the embedded system, the developer is actually logging into the embedded system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This connection is illustrated in the figure below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;reverse_ssh_diagram-1.png&quot; alt=&quot;reverse_ssh_diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the above figure, the external server is typically a system located in the developer’s office with only port 22 exposed to the Internet.  Port 2900 is only accessible to developers on the same private network as the server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security&quot;&gt;Security&lt;&#x2F;h3&gt;
&lt;p&gt;When talking about any type of remote access technology involving the internet, it is important to consider the security implications.  The reverse SSH mechanism is fairly secure, as everything is encrypted.  SSH is widely used for remote access to servers; therefore it receives a lot of testing and scrutiny.  With the reverse SSH remote access setup, the most likely attack is probably to compromise the external server and then try to access the remote network the embedded system is located on through the embedded system.    If the external server is properly secured, then this mechanism should be fairly safe.  One of the advantages of this scheme is that the embedded system is not directly exposed to the Internet, therefore  securing the embedded system itself is not all that important.&lt;&#x2F;p&gt;
&lt;p&gt;It is obviously very important that the people administering the remote network understand what you are doing – that is where this article can come in handy.  If there are concerns about external developers accessing a network, one mode of operation may be for the the SSH tunnel to be manually started and stopped so that administrators of the remote network know exactly when remote access is enabled.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tips&quot;&gt;TIPS&lt;&#x2F;h3&gt;
&lt;p&gt;A few ideas for making this work well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It may be useful to put the reverse SSH connection in a cron job on the embedded system so that the connection is automatically set up.  If you do this, I advise killing the connection and restarting every so often.  Reverse SSH connections are somewhat fragile and occasionally need restarted if there is a network glitch.&lt;&#x2F;li&gt;
&lt;li&gt;Use the SSH TCPKeepAlive option.  Some firewalls&#x2F;routers will drop a network connection if there is no activity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Using SSH for remote access is another example of the “Big Win” with Embedded Linux – how industrial grade technologies developed for use in server and desktop systems can be readily used in embedded systems (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ).  Remote access during the deployment and testing of embedded systems can drastically reduce the amount of time and effort required to roll out an embedded system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to build GNU&#x2F;Linux for an embedded x86 computer</title>
        <published>2006-11-29T00:00:00+00:00</published>
        <updated>2006-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/"/>
        <id>https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/</id>
        
        <content type="html" xml:base="https://bec-systems.com/134/how-to-build-gnulinux-for-an-embedded-x86-computer/">&lt;p&gt;Recently, I had a customer who needed an embedded Linux distribution running on an Advantech PCM-9371 single board computer (SBC).  The PCM-9371 contains a low voltage Celeron or Pentium III processor.  This article describes why the Openembedded build system was chosen and a few tips for running Openembedded on a x86 system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-hard-way&quot;&gt;The hard way!&lt;&#x2F;h2&gt;
&lt;p&gt;There are many ways to put Linux on a x86 embedded system.  There are hundreds of distributions out there and the temptation is always to do something “quick” and just try to trim down one of the standard distributions.  Other shortcuts are often taken, such as compiling your application on a workstation that is running a different distribution and different versions of the libraries used in the embedded systems.  This approach can work, but there are many possible pitfalls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Several years down the road, it will be difficult to compile applications for your target system as the libraries on the target system are very dated compared to tools and libraries used in standard desktop distributions.  What this means is you will need to keep a “golden” compile machine around for the life of your project – not fun!  I went through an experience like this on a previous version of this same project where it took us a week to set up a build machine to compile applications using a very old version of Debian.&lt;&#x2F;li&gt;
&lt;li&gt;It is difficult to gather GPL sources used to build the distribution you are using.  You are required to supply GPL source code upon request to customers who purchase your product.&lt;&#x2F;li&gt;
&lt;li&gt;To build applications correctly, you really need a build machine that is running the same distribution as the target, unless you set up a cross-compilation or scratchbox environment.&lt;&#x2F;li&gt;
&lt;li&gt;Most distributions are quite large and have difficulty fitting on CF card.&lt;&#x2F;li&gt;
&lt;li&gt;Most distributions are difficult to customize in a clean, systematic way.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;openembedded&quot;&gt;OpenEmbedded&lt;&#x2F;h2&gt;
&lt;p&gt;Considering the disadvantages of using an standard x86 distribution for this project, I chose to use OpenEmbedded (OE).  The OpenEmbedded project (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;openembedded.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;openembedded.org&lt;&#x2F;a&gt; ) is a full featured build system for building embedded Linux distributions.  The development is done on a Linux workstation of your choice and the entire distribution is cross-compiled to the architecture of your choice.  The entire build process is automated, including building the toolchain and an image that can be installed on the target embedded system.  Some of the features of OpenEmbedded are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Over 3000 packages that can be built.  About anything you would ever need for an embedded system.&lt;&#x2F;li&gt;
&lt;li&gt;Support for a wide variety of target architectures.  ARM and x86 processors are well supported.&lt;&#x2F;li&gt;
&lt;li&gt;Build system is very self contained.  This means you can do the builds on a variety of different host machines.  Many of the tools OE needs are built by OE, so there is very little dependence on host tools besides a few basics such as Python, make, and other standard tools.  This also means it is much easier to pull the build system out of the archives in several years, load it on a current machine, and do a build.&lt;&#x2F;li&gt;
&lt;li&gt;All source code used in the build is downloaded, so GPL compliance is easy.&lt;&#x2F;li&gt;
&lt;li&gt;and the list goes on …&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;build-and-installation&quot;&gt;Build and Installation&lt;&#x2F;h2&gt;
&lt;p&gt;Setting up an OE build is beyond the scope of this article, but it basically involves selecting a machine and distribution.  In this case, I chose the &lt;em&gt;x86&lt;&#x2F;em&gt; machine and the &lt;em&gt;generic&lt;&#x2F;em&gt; OE distribution.  Several hours later, I had an image in the form of a tar.gz file that I decompressed to a Compact Flash (CF) card.  After installing grub on the CF card, I had a booting Linux distribution that included all the basics (like ssh, ipkg package manager, shell, standard file utilities, etc) in less than 4MB of disk space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-gtk-and-xwindows&quot;&gt;Adding GTK+ and Xwindows&lt;&#x2F;h2&gt;
&lt;p&gt;This system required support for GTK+ and Xwindows.  To add this involved running the following commands: &lt;em&gt;bitbake xserver-kdrive&lt;&#x2F;em&gt; and &lt;em&gt;bitbake gtk+&lt;&#x2F;em&gt;.  The OE build system then automatically downloaded and compiled the need packages.  The image size is now around 20MB – still fits very easily on a CF card.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-x-running&quot;&gt;Getting X running&lt;&#x2F;h2&gt;
&lt;p&gt;There are several options for running X on a x86 system.  In this case, I chose the quickest way so that my customer could get started with application integration as quickly as possible.  Linux and Xwindows support the standard VESA Framebuffer mode.  Then can be enabled by selecting the CONFIG_FB_VESA kernel config option.  The kdrive version of X can then be started by running Xvesa.  In the future, we may move to an accelerated X driver if needed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;We now have Linux running off of a CF card with full X&#x2F;GTK+ support and the customer can proceed with integration, testing and application development.  Getting to this point took about 1 day of development as we did not encounter any major problems – much less time than it took to resurrect an old build environment used in previous versions of the project.  Future work will involve integrating applications into the OE build system, and customizing the distribution as needed.  Openembedded has proved to be a very valuable tool for getting embedded Linux systems running quickly and maintaining them in a controlled way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adding software to a Moxa UC7408 using OpenEmbedded</title>
        <published>2006-10-30T00:00:00+00:00</published>
        <updated>2006-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/"/>
        <id>https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/</id>
        
        <content type="html" xml:base="https://bec-systems.com/131/adding-software-to-a-moxa-uc7408-using-openembedded/">&lt;p&gt;One of the big advantages of using Linux in embedded systems is the thousands of applications and drivers available for it (&lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&lt;&#x2F;a&gt; ).  One of the challenges of Embedded Linux is building these applications.  Building applications for an embedded system often involves cross-compiling which is frustrating on a good day.  This article details how to use OpenEmbedded (OE) with the existing toolchain Moxa provides to build a number of applications for the Moxa UC7408.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;web-application-support&quot;&gt;Web Application Support&lt;&#x2F;h2&gt;
&lt;p&gt;My needs for this project were to build a web application that ran on the UC7408 (See &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;55&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;55&#x2F;9&#x2F;&lt;&#x2F;a&gt; for a review of the Moxa UC7408).  The Moxa firmware is fairly full featured and provides php for web application development.  This is probably fine for many applications, but I prefer to build web applications as detailed in this article: &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&quot;&gt;&#x2F;web&#x2F;content&#x2F;view&#x2F;46&#x2F;9&#x2F;&lt;&#x2F;a&gt; .  Because the rest of the application is written in Python, there are advantages to also implementing the web application in Python.  I also wanted to use the sqlite database.  A quick look at the php supplied with the Moxa firmware suggested it was built without sqlite support.  In summary, I needed the following components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Python&lt;&#x2F;li&gt;
&lt;li&gt;Clearsilver&lt;&#x2F;li&gt;
&lt;li&gt;sqlite&lt;&#x2F;li&gt;
&lt;li&gt;minicom&lt;&#x2F;li&gt;
&lt;li&gt;vim&lt;&#x2F;li&gt;
&lt;li&gt;strace&lt;&#x2F;li&gt;
&lt;li&gt;subversion&lt;&#x2F;li&gt;
&lt;li&gt;wget&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The above is a fairly small list, but what you don’t see are all the dependencies that also need to be built and installed.  This ends up being many more components.   Some of the items are for development only, but this is Linux – why not have nice tools running on the target system?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;oe-to-the-rescue&quot;&gt;OE to the rescue&lt;&#x2F;h2&gt;
&lt;p&gt;Ideally, the Moxa system would have a complete root file system built with OE running on it.  But I did not have the time or budget to implement this, so I did the next best thing – use the rootfs and toolchain supplied by Moxa along with OE to compile just the applications I needed.  Typically, OE builds the toolchain and Glibc, but fortunately OE provides a very slick way to use an external toolchain and glibc with OE.  How to do this is detailed in the OE manual: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.openembedded.org&#x2F;user-manual&amp;amp;dpage=commonuse_prebuilt_toolchain&quot;&gt;http:&#x2F;&#x2F;www.openembedded.org&#x2F;user-manual&amp;amp;dpage=commonuse_prebuilt_toolchain&lt;&#x2F;a&gt;.  Below is the setup I used:&lt;&#x2F;p&gt;
&lt;p&gt;Environment variables:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;TOOLCHAIN=&#x2F;usr&#x2F;local&#x2F;mxscaleb&#x2F;bin&#x2F;
export PRE_BUILT=&#x2F;usr&#x2F;local&#x2F;mxscaleb&#x2F;armv5b-linux

export CCACHE_DIR=&amp;quot;${TOPDIR}&#x2F;ccache&amp;quot;
export PYTHONPATH=&amp;quot;${TOPDIR}&#x2F;bitbake&#x2F;lib&amp;quot;
export BBPATH=&amp;quot;${TOPDIR}:${TOPDIR}&#x2F;openembedded:${TOPDIR}&#x2F;bitbake&amp;quot;
export PATH=&amp;quot;${TOPDIR}&#x2F;bitbake&#x2F;bin:${TOOLCHAIN}:${PATH}&amp;quot;
export LD_LIBRARY_PATH=
export LANG=C
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Local.conf file:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DL_DIR = &amp;quot;&#x2F;build&#x2F;sva_oe&#x2F;downloads&amp;quot;
BBFILES := &amp;quot;&#x2F;build&#x2F;sva_oe&#x2F;openembedded&#x2F;packages&#x2F;*&#x2F;*.bb&amp;quot;
BBMASK = &amp;quot;&amp;quot;
PREFERRED_PROVIDERS = &amp;quot;virtual&#x2F;qte:qte virtual&#x2F;libqpe:libqpe-opie&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;libsdl:libsdl-qpe&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc-initial:gcc-cross-initial&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc:gcc-cross&amp;quot;
PREFERRED_PROVIDERS += &amp;quot; virtual&#x2F;${TARGET_PREFIX}g++:gcc-cross&amp;quot;
PREFERRED_PROVIDER_virtual&#x2F;libx11 = &amp;quot;diet-x11&amp;quot;
ASSUME_PROVIDED += &amp;quot; virtual&#x2F;${TARGET_PREFIX}gcc &amp;quot;
ASSUME_PROVIDED += &amp;quot; virtual&#x2F;libc &amp;quot;
MACHINE = &amp;quot;moxa&amp;quot;
IPKG_ARCHS = &amp;quot;all arm armv4 armv5te xscale ${MACHINE}&amp;quot;
TARGET_CC_ARCH = &amp;quot;-mcpu=xscale&amp;quot;
TARGET_ARCH = &amp;quot;arm&amp;quot;
PACKAGE_ARCH=&amp;quot;xscale&amp;quot;
TARGET_OS = &amp;quot;linux&amp;quot;
TARGET_FPU = &amp;quot;soft&amp;quot;
DISTRO = &amp;quot;moxa-disro&amp;quot;
DISTRO_NAME = &amp;quot;moxa-distro&amp;quot;
DISTRO_VERSION = &amp;quot;0.0.1&amp;quot;
DISTRO_TYPE = &amp;quot;release&amp;quot;
INHERIT += &amp;quot; package_ipk package_tar debian&amp;quot;
IMAGE_FSTYPES = &amp;quot;jffs2 tar&amp;quot;
PARALLEL_MAKE = &amp;quot;-j 4&amp;quot;
BBINCLUDELOGS = &amp;quot;yes&amp;quot;
CVS_TARBALL_STASH = &amp;quot;http:&#x2F;&#x2F;www.oesources.org&#x2F;source&#x2F;current&#x2F;&amp;quot;
export CC  = &amp;quot;mxscaleb-gcc-3.3.2 ${HOST_CC_ARCH}&amp;quot;
export CXX = &amp;quot;mxscaleb-g++ ${HOST_CC_ARCH}&amp;quot;
export CPP = &amp;quot;mxscaleb-gcc-3.3.2 -E&amp;quot;
export LD = &amp;quot;mxscaleb-ld&amp;quot;
export AR  = &amp;quot;mxscaleb-ar&amp;quot;
export AS  = &amp;quot;mxscaleb-as&amp;quot;
export RANLIB  = &amp;quot;mxscaleb-ranlib&amp;quot;
export STRIP  = &amp;quot;mxscaleb-strip&amp;quot;
TARGET_CPPFLAGS_append = &amp;quot; -I${PRE_BUILT}&#x2F;include &amp;quot;
TARGET_LDFLAGS_prepend = &amp;quot; -L${PRE_BUILT}&#x2F;lib -Wl,-rpath-link, ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;${PRE_BUILT}&#x2F;lib -Wl,-rpath-link,${PRE_BUILT}&#x2F;qt2&#x2F;lib &amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the above setup, I was able to build the applications I needed with very little effort.  There were a few little problems I ran into, but I was able to quickly work around them.  The result is a number of packages that can be installed on the target system:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bigreqsproto-dev-X11R7.0-1.0.2-r0.tar.gz      python-crypt-2.4.3-ml0.tar.gz
busybox-1.2.1-r1.3.tar.gz                     python-curses-2.4.3-ml1.tar.gz
busybox-udhcpd-1.2.1-r1.3.tar.gz              python-datetime-2.4.3-ml0.tar.gz
clearsilver-0.10.3-r0.tar.gz                  python-db-2.4.3-ml0.tar.gz
clearsilver-dbg-0.10.3-r0.tar.gz              python-devel-2.4.3-ml0.tar.gz
clearsilver-dev-0.10.3-r0.tar.gz              python-distutils-2.4.3-ml0.tar.gz
clearsilver-doc-0.10.3-r0.tar.gz              python-email-2.4.3-ml0.tar.gz
inputproto-dev-X11R7.0-1.3.2-r0.tar.gz        python-fcntl-2.4.3-ml0.tar.gz
ipkg-0.99.163-r1.tar.gz                       python-gdbm-2.4.3-ml0.tar.gz
ipkg-dbg-0.99.163-r1.tar.gz                   python-hotshot-2.4.3-ml0.tar.gz
ipkg-dev-0.99.163-r1.tar.gz                   python-html-2.4.3-ml0.tar.gz
kbproto-dev-X11R7.1-1.0.3-r0.tar.gz           python-idle-2.4.3-ml0.tar.gz
libapr-0-0-0.9.12-r0.tar.gz                   python-image-2.4.3-ml0.tar.gz
libapr-0-bin-0.9.12-r0.tar.gz                 python-io-2.4.3-ml0.tar.gz
libapr-0-dev-0.9.12-r0.tar.gz                 python-lang-2.4.3-ml0.tar.gz
libaprutil-0-0-0.9.12-r0.tar.gz               python-lib-old-and-deprecated-2.4.3-ml0.tar.gz
libaprutil-0-bin-0.9.12-r0.tar.gz             python-logging-2.4.3-ml0.tar.gz
libaprutil-0-dev-0.9.12-r0.tar.gz             python-mailbox-2.4.3-ml0.tar.gz
libcrypto0.9.7-0.9.7g-r1.tar.gz               python-math-2.4.3-ml0.tar.gz
libexpat-bin-2.0.0-r1.tar.gz                  python-mime-2.4.3-ml0.tar.gz
libexpat-dev-2.0.0-r1.tar.gz                  python-mmap-2.4.3-ml0.tar.gz
libexpat-doc-2.0.0-r1.tar.gz                  python-netclient-2.4.3-ml1.tar.gz
libexpat1-2.0.0-r1.tar.gz                     python-netserver-2.4.3-ml0.tar.gz
libgcrypt-dbg-1.2.2-r0.tar.gz                 python-pickle-2.4.3-ml0.tar.gz
libgcrypt-dev-1.2.2-r0.tar.gz                 python-pprint-2.4.3-ml0.tar.gz
libgcrypt-doc-1.2.2-r0.tar.gz                 python-profile-2.4.3-ml0.tar.gz
libgcrypt11-1.2.2-r0.tar.gz                   python-pydoc-2.4.3-ml0.tar.gz
libgdbm-dbg-1.8.3-r2.tar.gz                   python-pyserial-2.2-r1.tar.gz
libgdbm-dev-1.8.3-r2.tar.gz                   python-pysqlite2-2.2.2-ml1.tar.gz
libgdbm-doc-1.8.3-r2.tar.gz                   python-pyxml-0.8.4-ml0.tar.gz
libgdbm3-1.8.3-r2.tar.gz                      python-re-2.4.3-ml0.tar.gz
libgnutls-bin-1.4.0-r1.tar.gz                 python-readline-2.4.3-ml0.tar.gz
libgnutls-dbg-1.4.0-r1.tar.gz                 python-resource-2.4.3-ml0.tar.gz
libgnutls-dev-1.4.0-r1.tar.gz                 python-shell-2.4.3-ml0.tar.gz
libgnutls-doc-1.4.0-r1.tar.gz                 python-stringold-2.4.3-ml0.tar.gz
libgnutls-extra13-1.4.0-r1.tar.gz             python-subprocess-2.4.3-ml0.tar.gz
libgnutls-locale-en+boldquot-1.4.0-r1.tar.gz  python-syslog-2.4.3-ml0.tar.gz
libgnutls-locale-en+quot-1.4.0-r1.tar.gz      python-terminal-2.4.3-ml0.tar.gz
libgnutls-locale-pl-1.4.0-r1.tar.gz           python-tests-2.4.3-ml0.tar.gz
libgnutls-openssl13-1.4.0-r1.tar.gz           python-textutils-2.4.3-ml0.tar.gz
libgnutls13-1.4.0-r1.tar.gz                   python-threading-2.4.3-ml0.tar.gz
libgpg-error-dbg-1.3-r1.tar.gz                python-tkinter-2.4.3-ml0.tar.gz
libgpg-error-dev-1.3-r1.tar.gz                python-unittest-2.4.3-ml0.tar.gz
libgpg-error-locale-de-1.3-r1.tar.gz          python-unixadmin-2.4.3-ml0.tar.gz
libgpg-error-locale-fr-1.3-r1.tar.gz          python-xml-2.4.3-ml0.tar.gz
libgpg-error-locale-pl-1.3-r1.tar.gz          python-xmlrpc-2.4.3-ml0.tar.gz
libgpg-error-locale-ro-1.3-r1.tar.gz          python-zlib-2.4.3-ml1.tar.gz
libgpg-error-locale-vi-1.3-r1.tar.gz          sqlite3-3.3.7-r2.tar.gz
libgpg-error0-1.3-r1.tar.gz                   sqlite3-dbg-3.3.7-r2.tar.gz
libice-dbg-X11R7.1-1.0.1-r0.tar.gz            strace-4.5.14-r3.tar.gz
libice-dev-X11R7.1-1.0.1-r0.tar.gz            strace-dbg-4.5.14-r3.tar.gz
libice6-X11R7.1-1.0.1-r0.tar.gz               strace-doc-4.5.14-r3.tar.gz
libipkg-dev-0.99.163-r1.tar.gz                subversion-1.3.1-r1.tar.gz
libipkg0-0.99.163-r1.tar.gz                   subversion-dbg-1.3.1-r1.tar.gz
liblzo-dbg-1.08-r14.tar.gz                    subversion-dev-1.3.1-r1.tar.gz
liblzo-dev-1.08-r14.tar.gz                    subversion-doc-1.3.1-r1.tar.gz
liblzo1-1.08-r14.tar.gz                       subversion-locale-de-1.3.1-r1.tar.gz
libneon-bin-0.25.5-r0.tar.gz                  subversion-locale-es-1.3.1-r1.tar.gz
libneon-dev-0.25.5-r0.tar.gz                  subversion-locale-fr-1.3.1-r1.tar.gz
libneon-doc-0.25.5-r0.tar.gz                  subversion-locale-it-1.3.1-r1.tar.gz
libneon25-0.25.5-r0.tar.gz                    subversion-locale-ja-1.3.1-r1.tar.gz
libpython2.4-1.0-2.4.3-ml5.tar.gz             subversion-locale-ko-1.3.1-r1.tar.gz
libreadline-dbg-4.3-r3.tar.gz                 subversion-locale-nb-1.3.1-r1.tar.gz
libreadline-dev-4.3-r3.tar.gz                 subversion-locale-pl-1.3.1-r1.tar.gz
libreadline-doc-4.3-r3.tar.gz                 subversion-locale-pt-br-1.3.1-r1.tar.gz
libreadline4-4.3-r3.tar.gz                    subversion-locale-sv-1.3.1-r1.tar.gz
libsm-dbg-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-cn-1.3.1-r1.tar.gz
libsm-dev-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-tw-1.3.1-r1.tar.gz
libsm6-X11R7.1-1.0.1-r0.tar.gz                tcl-8.4.11-r3.tar.gz
libsqlite-bin-2.8.17-r2.tar.gz                tcl-dbg-8.4.11-r3.tar.gz
libsqlite-dbg-2.8.17-r2.tar.gz                tcl-dev-8.4.11-r3.tar.gz
libsqlite-dev-2.8.17-r2.tar.gz                tcl-doc-8.4.11-r3.tar.gz
libsqlite0-2.8.17-r2.tar.gz                   time-1.7-r0.tar.gz
libsqlite3-0-3.3.7-r2.tar.gz                  time-dbg-1.7-r0.tar.gz
libsqlite3-dev-3.3.7-r2.tar.gz                time-doc-1.7-r0.tar.gz
libssl0.9.7-0.9.7g-r1.tar.gz                  tmp
libx11-6-X11R7.1-1.0.1-r1.tar.gz              update-rc.d-0.7-r0.tar.gz
libx11-dbg-X11R7.1-1.0.1-r1.tar.gz            util-macros-dev-X11R7.1-1.0.2-r0.tar.gz
libx11-dev-X11R7.1-1.0.1-r1.tar.gz            vim-7.0-r0.tar.gz
libx11-doc-X11R7.1-1.0.1-r1.tar.gz            vim-doc-7.0-r0.tar.gz
libx11-locale-X11R7.1-1.0.1-r1.tar.gz         vim-help-7.0-r0.tar.gz
libxau-dbg-X11R7.1-1.0.1-r0.tar.gz            vim-syntax-7.0-r0.tar.gz
libxau-dev-X11R7.1-1.0.1-r0.tar.gz            vim-tutor-7.0-r0.tar.gz
libxau-doc-X11R7.1-1.0.1-r0.tar.gz            wget-1.9.1-r6.tar.gz
libxau6-X11R7.1-1.0.1-r0.tar.gz               wget-dbg-1.9.1-r6.tar.gz
libxdmcp-dbg-X11R7.1-1.0.1-r0.tar.gz          wget-doc-1.9.1-r6.tar.gz
libxdmcp-dev-X11R7.1-1.0.1-r0.tar.gz          wget-locale-bg-1.9.1-r6.tar.gz
libxdmcp6-X11R7.1-1.0.1-r0.tar.gz             wget-locale-ca-1.9.1-r6.tar.gz
libxml2-2.6.22-r3.tar.gz                      wget-locale-cs-1.9.1-r6.tar.gz
libxml2-dbg-2.6.22-r3.tar.gz                  wget-locale-da-1.9.1-r6.tar.gz
libxml2-dev-2.6.22-r3.tar.gz                  wget-locale-de-1.9.1-r6.tar.gz
libxml2-doc-2.6.22-r3.tar.gz                  wget-locale-el-1.9.1-r6.tar.gz
libxml2-utils-2.6.22-r3.tar.gz                wget-locale-es-1.9.1-r6.tar.gz
libxt-dbg-X11R7.1-1.0.2-r0.tar.gz             wget-locale-et-1.9.1-r6.tar.gz
libxt-dev-X11R7.1-1.0.2-r0.tar.gz             wget-locale-fr-1.9.1-r6.tar.gz
libxt-doc-X11R7.1-1.0.2-r0.tar.gz             wget-locale-gl-1.9.1-r6.tar.gz
libxt6-X11R7.1-1.0.2-r0.tar.gz                wget-locale-he-1.9.1-r6.tar.gz
libz-dbg-1.2.3-r1.tar.gz                      wget-locale-hr-1.9.1-r6.tar.gz
libz-dev-1.2.3-r1.tar.gz                      wget-locale-hu-1.9.1-r6.tar.gz
libz1-1.2.3-r1.tar.gz                         wget-locale-it-1.9.1-r6.tar.gz
minicom-2.1-r0.tar.gz                         wget-locale-ja-1.9.1-r6.tar.gz
minicom-dbg-2.1-r0.tar.gz                     wget-locale-nl-1.9.1-r6.tar.gz
minicom-doc-2.1-r0.tar.gz                     wget-locale-no-1.9.1-r6.tar.gz
ncurses-5.4-r8.tar.gz                         wget-locale-pl-1.9.1-r6.tar.gz
ncurses-dbg-5.4-r8.tar.gz                     wget-locale-pt-br-1.9.1-r6.tar.gz
ncurses-dev-5.4-r8.tar.gz                     wget-locale-ro-1.9.1-r6.tar.gz
ncurses-doc-5.4-r8.tar.gz                     wget-locale-ru-1.9.1-r6.tar.gz
ncurses-terminfo-5.4-r8.tar.gz                wget-locale-sk-1.9.1-r6.tar.gz
ncurses-tools-5.4-r8.tar.gz                   wget-locale-sl-1.9.1-r6.tar.gz
openssl-0.9.7g-r1.tar.gz                      wget-locale-sv-1.9.1-r6.tar.gz
openssl-dbg-0.9.7g-r1.tar.gz                  wget-locale-tr-1.9.1-r6.tar.gz
openssl-dev-0.9.7g-r1.tar.gz                  wget-locale-uk-1.9.1-r6.tar.gz
openssl-doc-0.9.7g-r1.tar.gz                  wget-locale-zh-cn-1.9.1-r6.tar.gz
python-audio-2.4.3-ml0.tar.gz                 wget-locale-zh-tw-1.9.1-r6.tar.gz
python-bsddb-2.4.3-ml0.tar.gz                 xcmiscproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-codecs-2.4.3-ml0.tar.gz                xextproto-dev-X11R7.0-7.0.2-r0.tar.gz
python-compile-2.4.3-ml0.tar.gz               xf86bigfontproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-compiler-2.4.3-ml0.tar.gz              xproto-dev-X11R7.1-7.0.5-r0.tar.gz
python-compression-2.4.3-ml0.tar.gz           xtrans-dev-X11R7.0-1.0.0-r1.tar.gz
python-core-2.4.3-ml1.tar.gz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Installing the needed packages is just a matter of uncompressing a subset of the above files on the target system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This exercise demonstrates how a developer can quickly (took me less than 4 hours) add a large number of applications (and dependencies) to about any Embedded Linux system.  Leveraging embedded Linux is being able to use the components &lt;em&gt;&lt;strong&gt;you&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; need.  Please contact us if you would like additional details or assistance.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Moxa UC7408 Review</title>
        <published>2006-09-29T00:00:00+00:00</published>
        <updated>2006-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/124/moxa-uc7408-review/"/>
        <id>https://bec-systems.com/124/moxa-uc7408-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/124/moxa-uc7408-review/">&lt;p&gt;I am currently evaluating a Moxa UC7408 for one of my customers.  The UC7408 is a small fanless industrial computer that runs Linux or Windows CE.  This article provides a basic overview of this unit and a review of some of the UC7408 features and the Linux distribution Moxa provides.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_1-1.jpg&quot; alt=&quot;moxa_1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The basic specifications for the UC7408 are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;relatively small size and fanless&lt;&#x2F;li&gt;
&lt;li&gt;Intel Xscale IXP-422 266MHz Processor&lt;&#x2F;li&gt;
&lt;li&gt;8 RS232&#x2F;422&#x2F;485 serial ports&lt;&#x2F;li&gt;
&lt;li&gt;8 digital Input and 8 digital output ports&lt;&#x2F;li&gt;
&lt;li&gt;dual 10&#x2F;100 Ethernet&lt;&#x2F;li&gt;
&lt;li&gt;PCMCIA, CompactFlash, Wireless LAN Expansion (supports 802.11b&#x2F;802.11g)&lt;&#x2F;li&gt;
&lt;li&gt;Runs Linux or WinCE&lt;&#x2F;li&gt;
&lt;li&gt;Console serial port&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;&#x2F;h3&gt;
&lt;p&gt;The documentation Moxa provides is adequate and fairly detailed.  The moxa documents include a quick install guide, hardware user’s manual, and a 114 page user’s manual.  As good as this documentation is, a general knowledge of Linux is always helpful when working with embedded Linux systems.  Basics like using SSH, FTP, Telnet, and basic Linux system administration are essential when working with embedded Linux.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linux-distribution&quot;&gt;Linux Distribution&lt;&#x2F;h3&gt;
&lt;p&gt;The Linux Distribution provided by Moxa is fairly full featured.  A few highlights with the v1.8 Linux firmware:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provides a 26MB user JFFS2 flash partition.  This partition is read&#x2F;write and is about 45% full leaving about 14.5MB for user files.  It is probably also possible to delete some of the files that are not required, freeing up more space.&lt;&#x2F;li&gt;
&lt;li&gt;Apache &amp;amp; PHP support&lt;&#x2F;li&gt;
&lt;li&gt;SSH&lt;&#x2F;li&gt;
&lt;li&gt;a number of other utilities are provided such as telnet, ftp, iptables, etc.&lt;&#x2F;li&gt;
&lt;li&gt;VI editor&lt;&#x2F;li&gt;
&lt;li&gt;Many command line utilities found in most Linux systems.&lt;&#x2F;li&gt;
&lt;li&gt;2.4.18 Kernel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Linux distribution seems to be based on MontaVista Linux and seems fairly solid.  I ran through some of the basics like mounting a CF card and everything seems to work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;firmware-updates-and-recovery-mode&quot;&gt;Firmware Updates and Recovery Mode&lt;&#x2F;h3&gt;
&lt;p&gt;Moxa provides a mechanism to update the firmware in the system.  This update is a global flash update that programs the entire flash and will erase all user changes.  The update works by enabling a RAM file system and copying the new flash image to the ram file system.  Running an update command that copies the firmware update file into flash.&lt;&#x2F;p&gt;
&lt;p&gt;The 7408 contains a stripped down version of Linux in a separate flash partition that can be booted in a recovery mode if the User flash partition becomes corrupted or unusable.  This mode can be enabled by pressing the “Reset to Default” button on the unit and powering it on.  In this mode, there is no ssh support and you must ftp an image from an ftp server to the device and then reflash it.  This requires you to set up an ftp server that the Moxa system can access.  While this is an entirely workable solution, it may be a challenge for inexperienced Linux users.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tools&quot;&gt;Tools&lt;&#x2F;h3&gt;
&lt;p&gt;Moxa provides a Linux and Windows toolchain to use with the device.  I have built a number of packages with the Linux toolchain and it seems to work well.  It is based on GCC 3.3.2.  Cross compiling applications for embedded Linux is always a challenge and in a future article I will present a way to use OpenEmbedded to compile a number of packages using the Moxa toolchain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;possible-improvements&quot;&gt;Possible Improvements&lt;&#x2F;h3&gt;
&lt;p&gt;There would be some benefits if the system was a little more open in the following areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;access to the bootloader console and documentation.  This would allow developers to more easily flash their own software.&lt;&#x2F;li&gt;
&lt;li&gt;readily provide source for GPL components.  Moxa provides a form that you can fill out to receive GPL source code on a CE.  The cost is $100.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One of the big advantages of using Linux in an embedded system is the ability to use the many open source components available.  The easier an embedded solution provider makes this for developers, the more value their system provides.  See the white paper &lt;a href=&quot;..&#x2F;..&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;&quot;&gt;Tips for Planning Your Embedded Linux Project&lt;&#x2F;a&gt; (&#x2F;web&#x2F;content&#x2F;view&#x2F;35&#x2F;37&#x2F;) for more ideas on this subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;Overall, the Moxa system seems very usable and the hardware is quite nice.  Stay tuned for future articles about how to get the most out of this system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_2-1.jpg&quot; alt=&quot;moxa_2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_3-1.jpg&quot; alt=&quot;moxa_3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;moxa_4-1.jpg&quot; alt=&quot;moxa_4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to evaluate VoIP providers with Asterisk</title>
        <published>2006-09-20T00:00:00+00:00</published>
        <updated>2006-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/"/>
        <id>https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/</id>
        
        <content type="html" xml:base="https://bec-systems.com/269/how-to-evaluate-voip-providers-with-asterisk/">&lt;p&gt;There are many options when selecting a VoIP provider to terminate your Asterisk PBX.  One of the most important factors in this selection is the quality of the internet connection between your PBX and the VoIP provider.  The route between you and your VoIP provider is one of the most important considerations when selecting a provider.  This article details a simple method for evaluating this connection using Asterisk.&lt;&#x2F;p&gt;
&lt;p&gt;Asterisk includes a feature that can be used to monitor the latency between your system and a &lt;em&gt;peer&lt;&#x2F;em&gt; or &lt;em&gt;friend&lt;&#x2F;em&gt;.  This feature is enabled by setting the &lt;em&gt;qualify&lt;&#x2F;em&gt; setting in the &lt;em&gt;iax.conf&lt;&#x2F;em&gt; configuration file.  Valid options are &lt;em&gt;yes&lt;&#x2F;em&gt;, &lt;em&gt;no&lt;&#x2F;em&gt;, or a time in milliseconds.  If qualify is enabled, NOTIFY messages are sent periodically to the peer and the latency between replies is measured.  The peer is determined unreachable if the number of milliseconds is greater than the qualify value or 2,000 if qualify  is set to &lt;em&gt;yes&lt;&#x2F;em&gt;.  If a peer is unreachable, events are logged in &#x2F;var&#x2F;log&#x2F;asterisk&#x2F;messages as shown below:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;Sep 19 21:48:19 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now UNREACHABLE! Time: 49
Sep 19 21:50:09 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now REACHABLE! Time: 49
Sep 20 07:16:38 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now TOO LAGGED (769 ms)!
Sep 20 07:16:48 NOTICE[752] chan_iax2.c: Peer &amp;#39;NuFone2&amp;#39; is now REACHABLE! Time: 50
Sep 20 12:09:31 NOTICE[752] chan_iax2.c: Peer &amp;#39;teliax&amp;#39; is now TOO LAGGED (2923 ms)!
Sep 20 12:17:27 NOTICE[752] chan_iax2.c: Peer &amp;#39;teliax&amp;#39; is now REACHABLE! Time: 83
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am currently using two different VoIP providers and I get qualify notice messages about once every day or two with the qualify set to 400ms.  This is a very useful information as it allows me to determine which provider has the most reliable route from my office.  If you get very few qualify NOTICE messages, you can probably assume your VoIP connection will be fairly reliable.&lt;&#x2F;p&gt;
&lt;p&gt;Have connections with two different providers also tells me when the congestion is with my Internet connection or if it is something beyond my connection.  If both providers go out at the same time, it is most likely the internet connection at my office or problems with my ISP.  I rarely if ever see this scenario, so I can conclude that my internet connection is fairly reliable and the congestion problems are most likely between me and the VoIP provider or problems at the VoIP provider.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, things are now working fairly well.  As we continue to resolve problems, VoIP is now starting to become a very usable option for us.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Implenting QoS for VOIP in a Linksys router</title>
        <published>2006-08-28T00:00:00+00:00</published>
        <updated>2006-08-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/"/>
        <id>https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/</id>
        
        <content type="html" xml:base="https://bec-systems.com/264/implenting-qos-for-voip-in-a-linksys-router/">&lt;p&gt;In our quest to implement an Asterisk PBX in our office, we are evaluating several VOIP (Voice Over IP) providers.  VOIP provides several benefits over traditional phone lines including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;low cost (typically around $0.02 per minute)&lt;&#x2F;li&gt;
&lt;li&gt;available in pre-paid plans&lt;&#x2F;li&gt;
&lt;li&gt;can support concurrent concurrent calls on the same number&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;However, implementing VOIP successfully is not trivial.  You &lt;strong&gt;must&lt;&#x2F;strong&gt; have a reliable internet connection and we have found you must implement some type of Quality of Service (QoS) in the router. The first problem I ran into was calls sounded great to me, but people I called mentioned the calls sometimes sounded garbled to them.  This article discusses the diagnosis of this problem and how to implement QoS in a Linksys router to fix this issue.&lt;&#x2F;p&gt;
&lt;p&gt;Our connection is a standard DSL connection – 5Mb&#x2F;sec down and 640Kb&#x2F;sec up.  There is plenty of bandwidth for incoming voice, but bandwidth for outgoing voice is much more limited.  A few tests confirmed this – when a ftp upload or some other bulk transfer was occurring, the outgoing voice sounded really bad.&lt;&#x2F;p&gt;
&lt;p&gt;The solution to this problem is to implement some type of Quality of Service (QoS) mechanism that prioritizes the VOIP traffic over all other types of traffic.  Vonage and other “boxed” solutions no doubt do this as they recommend placing their box between the modem and the router. It turns out that QoS can be implemented in a standard Linksys router&#x2F;firewall.  I spent some time trying to get QoS working using a Linksys WRT54G v5 router with no success, I ended up loading the dd-wrt firmware (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.dd-wrt.com&lt;&#x2F;a&gt;) on an older Linksys router I had laying around.  The dd-wrt firmware is quite nice and is worthy of consideration if you have a v4 or earlier Linksys router or the WRT54GL version.   QoS may have worked on the WRT54G v5 with Linksys firmware with some more effort, but after trying dd-wrt, I’m not going back.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-qos&quot;&gt;Setting up QOS&lt;&#x2F;h2&gt;
&lt;p&gt;The QoS settings can be found under Applications &amp;amp; Gaming -&amp;gt; QoS.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to assign priority to your VOIP system.  I just used the IP address as shown below.  192.168.1.10 is the LAN private IP of the Asterisk system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;qos1-1.png&quot; alt=&quot;qos1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the priority of the Asterisk box set to high, we should be all set.  It turns out that unless you cap the bandwidth, you will still have QoS problems.  Enter around 85% of your up and down bandwidth in the Uplink and Downlink boxes.  Capping the bandwidth is required to keep the latency low.  Otherwise, your bandwidth is filled up with large packets and the priority settings are not effective for VOIP traffic.  See &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;wiki&#x2F;index.php&#x2F;Quality_of_Service&quot;&gt;http:&#x2F;&#x2F;www.dd-wrt.com&#x2F;wiki&#x2F;index.php&#x2F;Quality_of_Service&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;qos2-1.png&quot; alt=&quot;qos2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the above settings, VOIP calls are now clear even with other concurrent activities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Several people have reported being able to install dd-wrt on v6 WRT54 routers and the QoS configuration is the same.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded is a Service Industry</title>
        <published>2006-06-02T00:00:00+00:00</published>
        <updated>2006-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/60/embedded-is-a-service-industry/"/>
        <id>https://bec-systems.com/60/embedded-is-a-service-industry/</id>
        
        <content type="html" xml:base="https://bec-systems.com/60/embedded-is-a-service-industry/">&lt;p&gt;Linuxdevices.com has recently published an article titled: &lt;em&gt;Let’s call Embedded what it is – a Service Industry&lt;&#x2F;em&gt;(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;linuxdevices.com&#x2F;articles&#x2F;AT6989225710.html&quot;&gt;http:&#x2F;&#x2F;linuxdevices.com&#x2F;articles&#x2F;AT6989225710.html&lt;&#x2F;a&gt;).  In this article, Curt Schacker discusses how little growth there has been in the Embedded Systems industry. He claims that most embedded companies are trying to establish themselves as product companies, when the market is really a services market.  Having worked for two Embedded companies in the past that went out of business, I think he is right.  I have often heard the argument that service companies are too much work, they don’t scale, etc.  But, to me services has always been a more natural fit for myself and an embedded systems company – one of the reasons BEC Systems exists.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TRAC and Distributed Development</title>
        <published>2006-05-29T00:00:00+00:00</published>
        <updated>2006-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/231/trac-and-distributed-development/"/>
        <id>https://bec-systems.com/231/trac-and-distributed-development/</id>
        
        <content type="html" xml:base="https://bec-systems.com/231/trac-and-distributed-development/">&lt;p&gt;I have long been a big fan of source control tools and issue tracking systems.  The “concurrent” model made popular by CVS is a tremendous benefit any time there are multiple people working on the same project.  For most of the projects BEC participates in, we end up setting up a source control system (usually Subversion these days) and an issue tracking system (typically Bugzilla).  On one of my recent projects, I decided to try the trac integrated SCM &amp;amp; Project Management tool.  Trac brings together several functions into a clean, easy to use web based tool for managing projects.  This article relates some of my experiences and the benefits of using trac.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-trac&quot;&gt;What is trac?&lt;&#x2F;h2&gt;
&lt;p&gt;Trac provides the following functions (from the trac website - &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.edgewall.com&#x2F;trac&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.edgewall.com&#x2F;trac&#x2F;&lt;&#x2F;a&gt; ):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An integrated system for managing software projects&lt;&#x2F;li&gt;
&lt;li&gt;An enhanced wiki&lt;&#x2F;li&gt;
&lt;li&gt;A flexible web-based issue tracker&lt;&#x2F;li&gt;
&lt;li&gt;An interface to the Subversion revision control system&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;why-is-trac-so-interesting&quot;&gt;Why is trac so interesting?&lt;&#x2F;h2&gt;
&lt;p&gt;Although all of these functions are available as separate tools, having them in one tool has several benefits:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The tool is more likely to be used if everything is in one place&lt;&#x2F;li&gt;
&lt;li&gt;The ease of cross referencing wiki pages, issues, and Subversion changesets compounds the usefulness of each tool.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have been using and implementing collaboration tools for years and one thing you eventually learn is that getting people to use collaboration tools is a big challenge (see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.linux-watch.com&#x2F;news&#x2F;NS9450464356.html&quot;&gt;http:&#x2F;&#x2F;www.linux-watch.com&#x2F;news&#x2F;NS9450464356.html&lt;&#x2F;a&gt; for some more thoughts on this subject).  Having mutiple tools in one place greatly increases the likelihood they will be used.  A typical session might go something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A developer might want to see what has changed recently in the code base, so he logs into trac to view the timeline – after all, most developers are mainly concerned with code.&lt;&#x2F;li&gt;
&lt;li&gt;As the trac timeline lists all changes (wiki and issues as well as source code changes), he notices that a wiki page with notes about driver X has changed – that looks interesting, so he view the page.  While viewing the page, the developer notes there is some missing information, so he adds the information by simply editing the page.&lt;&#x2F;li&gt;
&lt;li&gt;Once this habit is established, it can greatly improve the productivity of the team as the project becomes more transparent to all team members.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Any collaboration tool must be easy to use and provide an obvious benefit to those using the tool.&lt;&#x2F;p&gt;
&lt;p&gt;The wiki markup used in trac is used for both wiki pages as well as issue&#x2F;bug reports.  Referencing an issue in a wiki page or another bug report is simple as typing #&lt;issue number&gt;.  It is also very easy to reference code changsets in the wiki markup by simply typing r&lt;change set number&gt; (see image below).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;trac3-1.png&quot; alt=&quot;trac3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Clicking on a issue or changeset  number will take you directly to the information.  The trac interface is very clean and very easy to use.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distributed-teams&quot;&gt;Distributed teams&lt;&#x2F;h2&gt;
&lt;p&gt;Tools like trac allow for very effective distributed teams.  The success of Open Source software has proven that development can occur efficiently in a distributed manner.  BEC has integrated this model and we regularly work with people all over the country and in Europe.  When there is a process for all people involved in the project to keep up with its status and progress, distributed development becomes very possible.  Often, the customer is part of the development team.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;project-transparency&quot;&gt;Project Transparency&lt;&#x2F;h2&gt;
&lt;p&gt;Another benefit of trac for BEC, is that we can easily provide project transparency to our customers.   It is BEC’s practice to provide customers with access to the project as it develops, so we give our customers trac logins and they can follow the progress by watching the timeline and milestone pages.  This gives the customer an assurance that progress is being made on the project and some insight into some of the issues encountered.  Having a comprehensive view into the project also allows customers to provide early feedback and reduces BEC’s project management and reporting overhead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Tools like trac improve our customer relationships, increase efficiency and reduce our costs.  If you are interested in implementing tools like trac, BEC can assist you in selecting and implementing the right tools to make your projects run smoothly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Opencores SPI Controller Review</title>
        <published>2006-05-08T00:00:00+00:00</published>
        <updated>2006-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/66/opencores-spi-controller-review/"/>
        <id>https://bec-systems.com/66/opencores-spi-controller-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/66/opencores-spi-controller-review/">&lt;p&gt;Recently, I had the opportunity to use a SPI controller from Opencores in a customer design based on an Intel PXA255 processor and a Xilinx CPLD.  The customer did not want to change the processor or the CPLD family, but needed an extra SPI interface in the device.  I had my doubts, but mentioned I would look into a SPI controller from Opencores.  To my surprise, the core fit in a Xilinx CPLD and worked out very well.  We have since upgraded to a Altera MAXII CPLD.  This review details this effort.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;spi-controller-overview&quot;&gt;SPI Controller Overview&lt;&#x2F;h3&gt;
&lt;p&gt;The SPI controller is based on the interface for a standard Motorolla SPI controller and is available at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.opencores.org&#x2F;projects.cgi&#x2F;web&#x2F;spi&#x2F;overview&quot;&gt;http:&#x2F;&#x2F;www.opencores.org&#x2F;projects.cgi&#x2F;web&#x2F;spi&#x2F;overview&lt;&#x2F;a&gt; .  The core includes the following features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Full duplex synchronous serial data transfer&lt;&#x2F;li&gt;
&lt;li&gt;Variable length of transfer word up to 128 bits&lt;&#x2F;li&gt;
&lt;li&gt;MSB or LSB first data transfer&lt;&#x2F;li&gt;
&lt;li&gt;Rx and Tx on both rising or falling edge of serial clock independently&lt;&#x2F;li&gt;
&lt;li&gt;8 slave select lines&lt;&#x2F;li&gt;
&lt;li&gt;Fully static synchronous design with one clock domain&lt;&#x2F;li&gt;
&lt;li&gt;Technology independent Verilog&lt;&#x2F;li&gt;
&lt;li&gt;Fully synthesizable&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A datasheet type document is provided with the core that provides the necessary information for developers writing software for this core.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-wishbone-bus&quot;&gt;The Wishbone bus&lt;&#x2F;h3&gt;
&lt;p&gt;Most of the cores from Opencores uses the Wishbone bus standard.  The Wishbone bus is a synchronous bus designed to be used inside an IC.  The CPLD was connected to the PXA255 processors asynchrous bus, so most of the effort required was to create an PXA255 &amp;lt;-&amp;gt; Wishbone interface module.  At some point, I hope to release this module on Opencores.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;simulation&quot;&gt;Simulation&lt;&#x2F;h3&gt;
&lt;p&gt;The simulation was done using the Icarus Verilog simulator under Linux.  Below is a screen shot of the simulation displayed in GTKWave:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;spi_sim_small-1.png&quot; alt=&quot;spi_sim_small&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h3&gt;
&lt;p&gt;The Opencores SPI core worked out very well in our design and I was very impressed with quality of this core.  The documentation is more than adequate.  Standards like Verilog make it very easy to move designs between different vendors devices and allows designers to use tools of their choice such as the Icarus Verilog simulator.  As FPGAs and CPLDs become more larger and more standand, Opencores is valuable resource for adding standard interfaces to these devices.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Really Nice Hex Calculator</title>
        <published>2006-05-02T00:00:00+00:00</published>
        <updated>2006-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/226/a-really-nice-hex-calculator/"/>
        <id>https://bec-systems.com/226/a-really-nice-hex-calculator/</id>
        
        <content type="html" xml:base="https://bec-systems.com/226/a-really-nice-hex-calculator/">&lt;p&gt;When working with embedded software, I often have a need for a hex calculator.  Over the years I’ve used a number of different tools.  Through college and for several years after, I used my HP48 calculator.  It is a great tool.  Around 1998, I discovered the Python programming language.  As Python supports an interactive session, it works well as a desktop calculator – I don’t think I have used my HP48 since I discovered Python.  Recently, I’ve been using Ruby more in place of Python and am finding it is even nicer.  This article presents several tips and snippets of code for using Ruby as a very effective hex calculator.&lt;&#x2F;p&gt;
&lt;p&gt;For those of you not familiar with Ruby, Ruby is an interpreted scripting language for quick and easy object-oriented programming – similar in concept to Python or Perl.&lt;&#x2F;p&gt;
&lt;p&gt;Ruby provides an interactive Ruby shell called “irb”.  After you install Ruby, you can run irb from a command prompt.  You can immediately do useful calculations like the following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):001:0&amp;gt; a = 10
=&amp;gt; 10
irb(main):002:0&amp;gt; b = 23
=&amp;gt; 23
irb(main):003:0&amp;gt; a+b
=&amp;gt; 33
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hexadecimal numbers are prefixed with “0x” as in many other languages:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):005:0&amp;gt; c = 0x1000
=&amp;gt; 4096
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is easy to convert from hex to decimal – just type the hex number, hit return and Ruby will give you the decimal equivalent as shown above.   To convert from decimal to hex, I often just use the &lt;em&gt;printf&lt;&#x2F;em&gt; statement.  The syntax is similar to C, so it is very natural for embedded programmers.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):006:0&amp;gt; printf &amp;quot;0x%x&amp;quot;, (3*1024*1024)
0x300000=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ruby provides standard shift operators similar to those found in C.  For example, if you want to know the hex value when bits 15 and 23 are set high:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):019:0&amp;gt; printf &amp;quot;0x%x&amp;quot;, (1&amp;lt;&amp;lt;15)|(1&amp;lt;&amp;lt;23)
0x808000=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is often useful to know what bits are set in a particular number when determining if a bit in a status register is high, what address bits are used, etc. Ruby provides a bit reference method in the form.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;fix[n]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;n is the nth bit in a binary number &lt;em&gt;fix&lt;&#x2F;em&gt; where fix[0] is the least significant bit.  Some examples:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):010:0&amp;gt; 2[0]
=&amp;gt; 0
irb(main):011:0&amp;gt; 2[1]
=&amp;gt; 1
 irb(main):017:0&amp;gt; a = 3*1024*1024
=&amp;gt; 3145728
irb(main):018:0&amp;gt; 31.downto(0) {|n| print a[n]}
00000000001100000000000000000000=&amp;gt; 31
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For convenience, I wrote a simple module called &lt;em&gt;bits.rb&lt;&#x2F;em&gt; that extends the basic Integer number class and provides a nice display of the bits in a number.  To use this, create a file called bits.rb with the following contents and drop it in your Ruby &lt;em&gt;site_ruby&lt;&#x2F;em&gt; directory.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; M = 1024*1024
K = 1024

class Integer
        def bits
                print &amp;quot;3322222222221111111111n&amp;quot;
                print &amp;quot;10987654321098765432109876543210n&amp;quot;
                print &amp;quot;---|---|---|---|---|---|---|---|n&amp;quot;
                31.downto(0) { |x| print self[x] }
        end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And to use this extension to see what address bits are used to decode 8MB of address space:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; irb(main):020:0&amp;gt; require &amp;#39;bits&amp;#39;
=&amp;gt; true
irb(main):021:0&amp;gt; (8*M).bits
3322222222221111111111
10987654321098765432109876543210
---|---|---|---|---|---|---|---|
00000000100000000000000000000000=&amp;gt; 31
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From this example, we can see that address bits 0 through 23 are required to decode 8MB of address space.&lt;&#x2F;p&gt;
&lt;p&gt;===========================================&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2009-07-30&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The following was posted as a comment to my old web site:&lt;&#x2F;p&gt;
&lt;p&gt;An even easier way of converting between bases in Ruby:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; puts 300.to_s(16)
12c
=&amp;gt; nil
irb(main):002:0&amp;gt; puts &amp;quot;12c&amp;quot;.to_i(16)
300
=&amp;gt; nil
irb(main):003:0&amp;gt; puts 255.to_s(2)
11111111
=&amp;gt; nil
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very nice!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Specialization or not</title>
        <published>2005-11-15T00:00:00+00:00</published>
        <updated>2005-11-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/55/specialization-or-not/"/>
        <id>https://bec-systems.com/55/specialization-or-not/</id>
        
        <content type="html" xml:base="https://bec-systems.com/55/specialization-or-not/">&lt;p&gt;I have often wondered about specialization.  We can often find ourselves in ruts if we specialize too much.  But on the other hand, specialization can lead efficiencies in some cases.  In my work as a consultant, I often find myself in new situations where I have to learn fast.  As one of my associates states – problem solving is the key skill.  Kevin Barnes article &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.journalhome.com&#x2F;codecraft&#x2F;15583&#x2F;&quot;&gt;Three theories on how to use developers efficiently&lt;&#x2F;a&gt; is a good read about the subject.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Total Phase USB Protocol Analyzer review</title>
        <published>2005-11-03T00:00:00+00:00</published>
        <updated>2005-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/"/>
        <id>https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/</id>
        
        <content type="html" xml:base="https://bec-systems.com/222/total-phase-usb-protocol-analyzer-review/">&lt;p&gt;I recently purchased a USB protocol analyzer from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.totalphase.com&#x2F;products&#x2F;beagle&#x2F;usb&#x2F;&quot;&gt;Total Phase&lt;&#x2F;a&gt;.  The device will analyze full speed USB traffic and works well with Linux.  On Linux, the software makes use of libusb, so there is very little setup required to get the device working – very nice.  At a price of $400, there is really no reason not to have one if you are doing any type of USB development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;uploads&#x2F;2009&#x2F;01&#x2F;beagle-1.jpg&quot; alt=&quot;beagle&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Economics and Finding Outsourcing Talent</title>
        <published>2005-11-03T00:00:00+00:00</published>
        <updated>2005-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bec-systems.com/51/economics-and-finding-outsourcing-talent/"/>
        <id>https://bec-systems.com/51/economics-and-finding-outsourcing-talent/</id>
        
        <content type="html" xml:base="https://bec-systems.com/51/economics-and-finding-outsourcing-talent/">&lt;p&gt;Economics In One Lesson by Henry Hazlitt presents an interesting and logical view of economics.  The book presents many ideas that seem right (like saving) and provides very logical arguments to back them up.  Even though the book was originally published in 1946, the topics covered seem very applicable to today (The Blessings of Destruction, Public Works Mean Taxes, Taxes Discourage Production, Credit Diverts Production, The Curse of Machinery, Spread-the-Work Schemes, Disbanding Troops and Bureaucrats, The Fetish of Full Employment, Who’s “Protected” by Tariffs?, The Drive for Exports, “Parity” Prices, Saving the X Industry, How the Price System Works, “Stabilizing” Commodities, Government Price-Fixing, What Rent Control Does, Minimum Wage Laws, Do Unions Really Raise Wages?, “Enough to Buy Back the Product”, The Function of Profits, The Mirage of Inflation, The Assault on Saving)&lt;&#x2F;p&gt;
&lt;p&gt;The book can be found:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;online: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;jim.com&#x2F;econ&#x2F;contents.html&quot;&gt;http:&#x2F;&#x2F;jim.com&#x2F;econ&#x2F;contents.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;download: &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.fee.org&#x2F;pdf&#x2F;books&#x2F;Economics_in_one_lesson.pdf&quot;&gt;http:&#x2F;&#x2F;www.fee.org&#x2F;pdf&#x2F;books&#x2F;Economics_in_one_lesson.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;amazon.com&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following article presents some of the realities of finding talent in places like India.  It is encouraging that the basic economic laws of supply and demand still work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;finding-coders-on-the-subcontinent&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.journalhome.com&#x2F;codecraft&#x2F;13920&#x2F;&quot;&gt;Finding coders on the subcontinent&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
</content>
        
    </entry>
</feed>
