IT System Design 101: Decoupling of address and entity data in a self-addressing bus

There exists a special use-case for data handling in a situation where multiple self-addressing devices are using the same bus for communication. In the common case self-addressing devices work as follows:

  1. Each device has hardcoded unique piece of information to be used as a seed value for addressing (lets call this “serial number” for simplicity)
  2. Upon powering up, the devices negotiate with each other, either on the common bus (think application CanBUS) or nondocumented/out-of-band means
  3. During the negotiations, the devices agree about bus addresses of each device, based on presence of each device and everyone’s serial

Self-addressing bus is presented briefly in the image below.

Okay, so far so good. But what happens if the number of devices on the bus changes? There are multiple ways to deal with the situation. In case of new devices, one possibility is to assign the new devices with next, unused bus addresses. But how about when we lose devices? Should we just drop those bus addresses and be happy with it? There is no one size fits all -solution for the total problem, but a reasonable solution for situations where the number of devices is comparably small is to always re-negotiate the bus addresses. Another possibility is to regard missing devices as missing but in-place and re-negotiate only if the new device takes a bus address already in use.

Identifying a bus address change can be made with a couple of techniques. One possibility is to have a register status bit announce a change condition. Another possibility is to send announcement messages for a sufficient amount of time. External shared DIO can also be used in some contexts. And of course, there is the pathological case of reading all serial numbers during all communication rounds, but this is usually something we should try to avoid, and especially if we are designing the actual bus operation.

Let’s define next what is bus data and device address in a self-addressing bus. Bus data is verbatim, contemporary data read from a device on the bus. The bus data can tell it came from a certain bus address, but it cannot directly tell that it came from a certain physical device (though this information is attainable). Device address is something allocated by the system controlling the devices. It is semi-permanent, conceptual address we use in consistently in user interfaces to differentiate between devices. To recap:

  1. Device address is used for user interfaces, does not change in practice
  2. Bus address is somewhat volatile indication of where the current bus data came from
  3. Bus data is various readouts from the device (like voltage, power, etc)

Let’s make short example to clarify how bus address change happens. Let’s say we first have device A with bus address 1. Now, device B comes present on the bus and devices re-negotiate their bus addresses. Device B now gets bus address 1. Device A will switch from bus address 1 to bus address 2. Any cached bus address 1 data needs to be properly invalidated or repurposed.

We have now somewhat adequately described what is bus data and how does it react to address changes. But to make it very clear, we should regard bus data as volatile information, something we might not be able to re-read in the future, rendering the old data outdated. So, what is the non-volatile version of bus data? We can call it device data, or if we want to put it more finely, entity data. In normal operation, device data is linked to bus data. This glue mechanism is called inventory. The linking of bus data to device data is maintained by keeping a record of device serial number in device data. We also have a placeholder for the serial number in bus data (we read serial number bus data only when there is an address change situation).

Small sketch of inventory system managing bus and device data is presented below.

Now, in the event of addressing changes in the system the following happens:

  1. All links between all bus data and device data are cut
  2. Bus data is zeroed so it does not cause trouble or confusion
  3. Complete bus data is read from all available device address
  4. Serial numbers between device data and bus data are compared; if there is a match, bus data and device data are linked
  5. Special cases are handled

Let’s finally list some of the special cases and the accompanied actions

  • New device appears on bus => If there is space, allocate new device address
  • Device leaves bus => Keep device data and device address, but mark device non-communicating
  • New device replaces old device => Ask user to acknowledge configuring to new device as the old device was
  • System startup => Request a mapping of device addresses, serial numbers, and configuration data, then scan bus devices and if the same serial numbers are found, configure the devices accordingly

With all the previous stated we have covered majority of decoupling address and entity/device data in a self-addressing bus environment. We learned that bus data can become obsolete fast and that the real device data should be kept on a separate data structure, with 2-way links between device data and bus data. We also learned about addressing change circumstances and the special cases involved with them.

Orange Pi Zero 2W at first glance

Orangi Pi has recently introduced the Orangi Pi Zero 2W single-board computers. There are a couple of variants, with changing amount of RAM, maxing at 4 GB. The CPU is a 4 core Allwinner H618 Cortex-A53. The main board houses CPU, some system chips, antenna connector, micro-SD socket and 16 MB flash. There is also mini-HDMI socket as well as 2 USB-C sockets, one for power in and one for general peripherals. There is also handy 2 x 20 pin hole grid in the main board, and thank heavens they have not soldered the provided pin header in because it would actually more than double the height of the construction. They played this very smart. This does not happen often in electronics industry.

One side of the main board has a flat cable connection possibility to external daughter card housing IR receiver, RJ45 Ethernet, some buttons, 2 regular USB ports and audio jack. The board is incredibly thin. Everything in this design hints it will be a killer app for so-called “smart” TVs.

We took a short exploration tour of the product tour with the vendor-provided Debian Linux  (Note: Daughter card was NOT connected nor tested.) Read more below.

Continue reading “Orange Pi Zero 2W at first glance”

Forcing VMware virtual machines to appear 32-bit on 64-bit hosts

There are sometimes needs to run 32-bit VMware guest images on a 64-bit host. This is possible, for example in VMware Workstation 15 Player. The out-of-the-box behavior, however, is that the Player passes trough the CPU information more or less as such. The result is that the guest sees a x86_64 processor, not a x86 processor. Frequently this detection is made by reading the CPUID 29th feature bit for so-called “long mode” (see: https://en.wikipedia.org/wiki/CPUID#EAX=80000001h:_Extended_Processor_Info_and_Feature_Bits ). As this is seen by the guest, it might think it needs to run 64-bit image (Player does not force this, it is a decision of the image itself). The long mode bit seen from Linux /proc/cpuinfo :

Continue reading “Forcing VMware virtual machines to appear 32-bit on 64-bit hosts”

Portable Position-Independent Code (PIC) bootloader and firmware for ARM Cortex-M0 and Cortex-M4

Disclaimer 2024-05-07

Although PIC was a very interesting trek in the deep embedded territory, I’m not that confident about the benefits as of today, 2024-05-07. See the comment below from “manne”.  He discovered that even though some aspects of my solution works, it is basically unusable in the comprehensive scale. Therefore, for the time being, I am discouraging people from using PIC in real-world applications, and only exploring the subject for academic interest. I will write later more in-depth analysis of shortcomings and will also propose some compiler changes to tackle the main issue and also some some generic PIC optimizations.

Rest of the text is kept for posterity.

How to implement Position-Independent Code for microcontroller (MCUs) is a question which has been asked countless and countless of times all over the Internet. The answers and “solutions” are usually whippersnappering comments dropping a couple of key terms they probably just googled up without any kind of intrinsic knowledge about how the system should be working.

Sometimes the answer is “OK I got it working” followed by eternal silence from people asking clarifications. In other words, it looks like the task is very difficult and once people get it to work, it is so valuable they want to hide the details. In a way I cannot blame them much; it took me 6 months of half-time work every now and then to understand everything.

So, some 6 months ago I set myself a goal: “Create a portable solution where an intelligent bootloader can boot firmware images from any address in flash on Cortex-M0 or Cortex-M4 platform.” Finally, as of today 2022-01-16, I consider I have solved the problem in an intelligent and understandable way.

Funnily, I think I am the only person on planet Earth who has made available readily working example code and documented the code in a way I am doing now in this post.

Those impatient can explore the fully working STM32CubeIde codes at GitHub, for Cortex-M0: https://github.com/usvi/F070RB-BL-FW  and for Cortex-M4: https://github.com/usvi/L432KC-BL-FW  . (One might ask why one would use this kind of bloated stock configuration for developing on MCUs. Believe me, I’m doing it here only for pedagogical reasons. This way it is easier for noobs having the needed evaluation boards to verify that the code is working.)

The set of code I have created is a proof-of-concept, working for the C language. There might, and I underline, might be unforeseen problems when amount of global variable gets absurdly high. In any case, comments and criticism is more than welcome.

If you are ready to dive into the deep end of Cortex-M boot process, PIC constructs, esoteric debugging and linker script optimizations, continue reading…

Continue reading “Portable Position-Independent Code (PIC) bootloader and firmware for ARM Cortex-M0 and Cortex-M4”

Primer and use case of Position-Independent Code in ARM Cortex-M MCU environment

Recently I described my friend that I was working with Position-Independent Code on a Cortex-M0 and Cortex-M4 environment. To my surprise, he was more interested about “why” and not “how”. I think before revealing the nitty-gritty details of this domain, I can give readers an overview about things.

Continue reading “Primer and use case of Position-Independent Code in ARM Cortex-M MCU environment”

PC Engines APU2E0 – a tiny fanless server with Intel NICs

My earlier gateway box, the Lanner NCA-1010B decided to stop working, leaving everything as a messy chaos. I gobbled up my retired Zotac Zbox and hastily built a makeshift router.

A long term solution was however needed. I had heard good things from this no-bullshit-geeky Swiss company called PC Engines GmbH. They make a board called APU2E0, among other things. It is a AMD GX-412TC-based SOC product with 2 Intel i211AT NICs. And it does not have regular monitor connections. Instead, there is a DB9 serial port for installation purposes.

The board’s sister version is pictured below for reference.

Continue reading “PC Engines APU2E0 – a tiny fanless server with Intel NICs”

Building Raspberry Pi Alpine Linux drivers (splix) for Samsung SCX-3205

(Executive summary: Some prebuilt packages also available at my site http://alpine.asuka.fi/v3.12/community/ )

Remember my old war horse, the Samsung SCX-3205 black & white printer/scanner? I recently moved in to a house. My girlfriend did not want printer near TV (with my ESXi shoebox) anymore, so I had to invent something else.

I had old Raspberry Pi 2 Model B v. 1.1 around, so I thought I should hook it up with the printer. Unfortunately I ended up compiling the necessary drivers myself because Alpine Linux did not have anything relevant. (I don’t blame them, this is quite outdated and rare.)

BTW Some Prebuilt packages are available at

http://alpine.asuka.fi/

Continue reading “Building Raspberry Pi Alpine Linux drivers (splix) for Samsung SCX-3205”

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

The journey continues. In this blog post we learn how to get WhatsApp installed on our freshly installed Android x86 7.1 . This article exists for 2 reasons:

  1. To offer completeness in our efforts to get virtualized WhatsApp instances to authorize regular WhatsApp web clients
  2. To show the minor differences there are involved in the process compared to normal WhatsApp install

This is the second article in our 3 article series:

Installing Android x86 7.1 on VMware ESXi 6.7

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

Complicatedly authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1

Again, as always, lets get started.

Continue reading “Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1”