Friday, March 20, 2026

Spectral Witness: EPR Pairs and the Physics of Light

\(\theta_{\min} = \min_{\mathbf{r}} \arccos\!\left( \frac{\mathbf{s} \cdot \mathbf{r}}{\lVert \mathbf{s} \rVert \, \lVert \mathbf{r} \rVert} \right)\)

© 2026 Bryan R. Hinton

The interrogation of physical reality through the medium of light remains one of the most profound endeavors of scientific inquiry. This pursuit traces its modern theoretical roots to the early twentieth century, a pivotal era for physics.

I'm feeling it tonight, the full, aching weight of it. The irreversibility of things.

I came to this history not through equations on a chalkboard, but through a train. Einstein's train. Let me set the scene the way I still see it: a long, straight ribbon of track, a rail car gliding over it, and two sets of eyes, one fixed on the ground, one carried along for the ride. Lightning strikes twice, ahead and behind.

To the one standing still, planted midway between the flashes, the light arrives together. Simultaneous. A clean, tidy fact.

But the rider? The rider is swept toward one strike and away from the other. The forward flash reaches her first. For her, the world is out of sync.

And here is the part that still gets me, right in the sternum: they are both right. There is no cosmic referee. Simultaneity isn't a property of the world out there; it's a receipt for how you are moving when you look up. Your motion decides what counts as now.

A train, though, can only go so fast. To watch motion bend time itself, you need a spaceship, and inside it, a clock made of light: just a photon bouncing between two mirrors. On board, it ticks straight up and down, pristine and simple. But watch it from the ground? That light traces a longer, slanted path. And because light will not be hurried, because it has its own sacred, unbreakable speed, each tick drags out longer. The moving clock runs slow.

That isn't a metaphor. That is time travel. Real, measured, merciless. The traveler drifts into the ground observer's future, one slow, stretched‑out tick at a time, leaving the rest of us behind in her wake.

But then comes the fine print. Relativity opens a road forward in time and offers no road back.

And that is the knot. We spend our lives begging for the road back. We want to send a message, a single word, a warning, a desperate whisper, into yesterday. Forward, sending information is easy and agonizingly ordinary. It is just a signal coasting at light speed or slower, drifting into tomorrow like a stone dropped in a river, inevitably carried downstream. But backward? Backward is the forbidden fruit. We dream of tachyons that outrun causality, of wormholes propped open with negative energy, of spinning black holes that fold space like paper, all just to get a single bit of data to arrive before it was ever sent. But the universe slaps our hands away. Every blueprint for backward information ends in a paradox that eats its own tail. You cannot warn your past self. You cannot undo a single word you said.

And a person? A person is so much heavier than a signal. Forward, it is brutally simple: strapping a human to that spaceship, sending them hurtling through space, and watching them wake up, ten years older, to find Earth has aged a full century. That is sending a person to another time, a one‑way ticket to the distant years ahead, bought and paid for by acceleration and sheer, lonely speed. Relativity will grant you that journey without hesitation; it is just physics.

And here is what the universe will actually sell you: distance in time, as much as you can pay for in speed. The spaceship already showed the price list. Ten years aboard buys a century outside. Push harder and the exchange rate goes vertical. Burn at one gravity, the same gentle push you feel in your chair right now, flip the ship at the midpoint, and a couple of decades of your one human life carries you clean across the galaxy while a hundred thousand years pour past outside. The year 3000 is reachable. The year 100,000 is reachable. You could stand in the deep future, in your own body, under constellations no one alive has named, and nothing in the laws forbids it. The fare is obscene, granted: even a perfect engine, annihilating matter with antimatter, burns a fortune in mass for every kilogram of passenger it delivers. But look at what kind of obstacle that is. A bill, not a law. The universe posts a price, not a prohibition. This is not loophole and not fantasy. It is the same time travel the light clock proved, scaled up until it takes your breath. The future is the one country with an open border, and relativity is the visa, already stamped.

What clung to me, what I still carry in my bones, is the cruel elegance of the instrument itself. Those trains, those spaceships: they aren't just physics. They are lenses. Tools for seeing exactly what light permits and what it ruthlessly forbids.

And thirty years after that miracle year of 1905, Einstein aimed that same sharp, unforgiving lens away from the stars and straight into the quantum mess. He was looking for a new foothold, a new way of seeing the chaos underneath.

In 1935, Albert Einstein and his colleagues Boris Podolsky and Nathan Rosen published a seminal paper that challenged the completeness of quantum mechanics.1 They described what later became known as EPR pairs: particles inextricably linked, their states correlated regardless of spatial separation, the phenomenon now called quantum entanglement.

It is the quintessential example of quantum entanglement. An EPR pair is created when two particles are born from a single, indivisible quantum event, like the decay of a parent particle.

This process "bakes in" a shared quantum reality where only the joint state of the pair is defined, governed by conservation laws such as spin summing to zero. As a result, the individual state of each particle is indeterminate, yet their fates are perfectly correlated.

Measuring one particle (e.g., finding its spin "up") instantaneously determines the state of its partner (spin "down"), regardless of the distance separating them. This "spooky action at a distance," as Einstein called it, revealed that particles could share hidden correlations across space that are invisible to any local measurement of one particle alone. While Einstein used this idea to argue quantum theory was incomplete, later work by John Bell2 and experiments by Alain Aspect3 confirmed this entanglement as a fundamental, non-classical feature of nature.


The EPR–Spectral Analogy: Hidden Correlations
Quantum Physics (1935)
EPR Pairs: Particles share non-local entanglement. Their quantum states are correlated across space. Measuring one particle gives random results; correlation only appears when comparing both.

Spectral Imaging (Today)
Spectral Pairs: Materials share spectral signatures. Their reflective properties are correlated across wavelength. The correlation is invisible to trichromatic (RGB) vision.


Mathematical Reconstruction

Estimates Hidden Correlations

Key Insight: Both quantum entanglement and material spectroscopy require looking beyond direct observation through mathematical analysis to infer a deeper, hidden layer of correlation.

While the EPR debate centered on the foundations of quantum mechanics, its core philosophy, that direct observation can miss profound hidden relationships, resonates deeply with modern imaging. Just as the naked eye perceives only a fraction of the electromagnetic spectrum, standard RGB sensors discard the high-dimensional "fingerprint" that defines the chemical and physical properties of a subject. Today, we address this limitation through multispectral imaging. By modeling how materials interact with light across the full spectrum, we can mathematically estimate the spectral information that lies between the visible bands, the correlations across wavelength that trichromatic vision discards, just as the analysis of EPR pairs revealed hidden correlations across space.


Silicon Photonic Architecture
The realization of this physics in modern hardware is constrained by the physical dimensions of the semiconductor used to capture it. The interaction of incident photons with the silicon lattice, generating electron–hole pairs, is the primary data acquisition step for any spectral analysis.

Sensor Architecture
The core of this pipeline is a modern back‑illuminated CMOS sensor, optimized for high‑resolution radiometry.

Active Sensing Area: The sensor's physical dimensions are paramount, as the sensing area is directly proportional to the total photon flux the device can integrate, setting the fundamental Signal‑to‑Noise Ratio (SNR) limit, a constraint no downstream algorithm can recover.
Pixel Pitch: Native photodiode pitches in current high‑resolution sensors sit on the order of \(1\text{–}2.5 \, \mu\text{m}\). Binning‑capable color filter arrays sum the charge from groups of adjacent photodiodes, trading spatial sampling density for a larger effective pixel pitch.

Mode Selection
The choice between binned and unbinned modes depends on the analysis requirements:

Binned mode (larger effective pitch): Superior for low‑light conditions and spectral estimation accuracy. By summing the charge from four photodiodes, the signal increases by a factor of 4, while read noise increases only by a factor of 2, significantly boosting the SNR required for accurate spectral estimation.
Full‑resolution mode (native pitch): Optimal for high‑detail texture correlation where spatial resolution drives the analysis, such as resolving fine fiber patterns in historical documents or detecting micro‑scale material boundaries.

The Optical Path
The light reaching the sensor passes through a multi‑element lens assembly with a fast maximum aperture. It is critical to note that "Spectral Fingerprinting" measures the product of the material's reflectance \(R(\lambda)\) and the lens's transmittance \(T(\lambda)\). Modern high‑refractive‑index glass absorbs specific wavelengths in the near‑UV (less than 400 nm), which must be accounted for during calibration.

The Digital Container: DNG and Linearity
The accuracy of computational physics depends entirely on the integrity of the input data. The Adobe DNG specification, in its recent revisions, provides the necessary framework for scientific photography by strictly preserving signal linearity.

Scene‑Referred Linearity
The specification permits raw data to be stored either as an unprocessed sensor mosaic or as demosaiced pixel values, captured after color filter array interpolation but before any non‑linear tone mapping. In both pathways the data remains scene‑referred linear, meaning the digital number stored is linearly proportional to the number of photons collected (\(DN \propto N_{photons}\)). This linearity is a prerequisite for the mathematical rigor of spectral reconstruction, classical or learned.

Gain Maps and Aesthetic Metadata
A key innovation of recent spec revisions is support for spatially varying gain maps: metadata describing the local tone mapping a device intends for display, stored alongside the linear pixel data rather than baked into it.

Scientific Stewardship: By decoupling the "aesthetic" gain map from the "scientific" linear data, the pipeline can discard the gain map entirely. This ensures that the spectral reconstruction algorithms operate on pure, linear photon counts, free from the spatially variant distortions introduced by computational photography.

Algorithmic Inversion: From 3 Channels to a Dense Spectral Grid
Recovering a high‑dimensional spectral curve \(S(\lambda)\) (upwards of a hundred narrow bands sampled at nanometre‑scale intervals, spanning the visible spectrum and into the near‑infrared) from a low‑dimensional RGB input is an ill‑posed inverse problem. Because infinitely many distinct spectra can project onto the same RGB triplet, the phenomenon of metamerism, the recovered spectrum is an estimate constrained by learned priors, not a direct measurement. Classical linear methods like Wiener estimation long defined the baseline for this problem; modern high‑end hardware enables the use of advanced Deep Learning architectures that supersede it.

Wiener Estimation (The Classical Baseline)
The classical approach minimizes the mean square error between the estimated and actual spectra through a single closed‑form matrix:

\(W = K_r M^T (M K_r M^T + K_n)^{-1}\)

For decades this was the standard route from a 3‑channel input to an n‑band estimate, and it remains the fast, interpretable reference against which learned methods are judged. But as a global linear operator it cannot exploit spatial context or resolve metameric ambiguity: precisely the gap the architectures below exist to close.

State‑of‑the‑Art: Transformers and Mamba
For high‑end hardware environments, predictive neural architectures leverage spectral‑spatial correlations to resolve ambiguities.

MST++ (Spectral Attention Architecture)6: The MST++ (Multi‑stage Spectral‑wise Transformer) architecture represents a significant leap in accuracy. Unlike global matrix methods, MST++ utilizes Spectral‑wise Multi‑head Self‑Attention (S‑MSA). It calculates attention maps across the spectral channel dimension, allowing the model to learn complex non‑linear correlations between texture and spectrum. Because each spectral feature map is treated as a token, the attention cost grows quadratically with the number of spectral channels but only linearly with spatial resolution, a deliberate design choice that keeps high‑resolution inference tractable. The multi‑stage design is nonetheless memory‑hungry: at full sensor resolutions, activations demand substantial GPU memory (VRAM) and dedicated hardware.

State Space Models (Linear Complexity)7: A newer family of architectures replaces attention entirely. Selective State Space Models (Mamba)7 discretize a continuous state space equation into a recurrent form that can be computed with linear complexity \(O(N)\), where conventional spatial self‑attention scales quadratically with pixel count. Recent work has adapted these models to the spectral domain: multi‑scale Mamba variants for efficient spectral reconstruction4 and Mamba‑inspired unfolding networks for snapshot spectral compressive imaging5. These designs reach transformer‑class accuracy while keeping memory and compute linear in image size, well suited to the super‑resolution composites described below, where quadratic spatial attention would be prohibitive.

Multi‑Frame Super‑Resolution: Approaching the Gigapixel Frontier
The resolution limits of a single sensor frame can be overcome through multi‑frame super‑resolution compositing, where multiple sub‑pixel‑offset exposures are interleaved into a single high‑resolution mosaic. This technique, implemented in the pipeline through a motion‑compensated registration and upsampling layer, effectively increases the spatial sampling density beyond the native pixel pitch. Combining a burst of offset frames produces composite images approaching the gigapixel regime, at effective resolutions an order of magnitude beyond the native sensor output. These composites preserve the linear radiometric integrity of the source raw files, ensuring that spectral reconstruction algorithms operate on the same photon‑count linearity as single‑frame captures. The data footprint scales accordingly: a full super‑resolution composite at floating‑point precision can exceed several gigabytes per spectral layer, requiring distributed memory architectures and optimized I/O pipelines. This increase in spatial detail enables micro‑scale textural analysis that would otherwise be lost, revealing deposition patterns, brushstroke gradients, and surface anomalies at resolutions that approach the diffraction limit of the optical system. The compositing step is fully integrated into the ingestion workflow, feeding the resulting high‑resolution arrays directly into the same MST++ and Mamba‑based reconstruction chains, with the deep learning models now operating on an order of magnitude more spatial detail.

Computational Architecture: The Linux Python Stack
Achieving multispectral precision requires a robust, modular architecture capable of handling massive arrays across a high-dimensional latent space. The implementation relies on a heavy Linux‑based Python stack designed to run on high‑end hardware.

Ingestion and Processing: We can utilize rawpy (a LibRaw wrapper) for the low‑level ingestion of raw files, bypassing OS‑level gamma correction to access the linear sensor data at its native bit depth. NumPy engines handle the high‑performance matrix algebra required to expand 3‑channel RGB data into n‑band spectral cubes.
Scientific Analysis: Scikit‑image and SciPy are employed for geometric transforms, image restoration, and advanced spatial filtering. Matplotlib provides the visualization layer for generating spectral signature graphs and false‑color composites.
Data Footprint: The scale of this operation is significant. A single high‑resolution frame converted to floating‑point precision results in massive file sizes. Intermediate processing files often exceed 600 MB for a single 3‑band layer. When expanded to a full n‑band multispectral cube, the storage and I/O requirements scale proportionally. With the super‑resolution composites, these numbers multiply further, producing intermediate arrays that routinely exceed 12 GB per 3‑band layer and necessitating the stability and memory management capabilities of a Linux environment, along with NVMe storage arrays and multi‑channel memory bandwidth to sustain the processing pipeline.

The Spectral Solution
When analyzed through the n‑band multispectral pipeline:

Spectral Feature Ultramarine (Lapis Lazuli) Azurite (Copper Carbonate)
Primary Reflectance Peak Approximately 450–480 nm (blue‑violet region) Approximately 470–500 nm with secondary green peak at 550–580 nm
UV Response (below 420 nm) Minimal reflectance, strong absorption Moderate reflectance, characteristic of copper minerals
Red Absorption (600–700 nm) Moderate to strong absorption Strong absorption, typical of blue pigments
Characteristic Features Sharp reflectance increase at 400–420 nm (violet edge) Broader reflectance curve with copper signature absorption bands

Note: Spectral values are approximate and can vary based on particle size, binding medium, and aging.

Completing the Picture
The successful analysis of complex material properties relies on a convergence of rigorous physics and advanced computation.

Photonic Foundation: A modern back‑illuminated CMOS sensor provides the necessary high‑SNR photonic capture, with readout mode (binned vs. full‑resolution) driven by the specific analytical requirements of each examination.
Sensor Diversity: The pipeline accepts raw frame data from a range of full‑frame, mirrorless, and mobile camera systems, in both proprietary and standard raw formats, processing each through a unified ingestion layer that normalises black level, white balance, and colour filter array geometry before spectral reconstruction. This format‑agnostic design ensures that the analytical stack operates on consistent linear sensor data regardless of capture device.
Data Integrity: The DNG specification is the critical enabler, preserving the linear relationship between photon flux and digital value while sequestering non‑linear aesthetic adjustments in metadata.
Algorithmic Precision: While Wiener estimation remains the classical reference point, the highest fidelity is achieved through spectral‑wise transformers (MST++) and Mamba‑based state space architectures. These models disentangle the complex non‑linear relationships between visible light and material properties, effectively generating n distinct spectral bands from 3 initial channels. The integration of multi‑frame super‑resolution composites further elevates the spatial precision of these reconstructions, delivering a joint spectral‑spatial resolution that is unattainable with single‑frame captures.
Physical Pattern Analysis: Spectral reconstruction alone cannot resolve every ambiguity. Materials that are spectrally similar can often be separated by their spatial characteristics: texture, edge morphology, and distribution across a surface. By supplementing per‑pixel spectral classification with geometric analysis of the spatial domain, the system gains a second, independent axis of evidence. This fusion of spectroscopic precision with pattern‑level reasoning closes a gap that purely spectral methods leave open.
Historical Continuity: The EPR paradox of 1935 revealed that quantum particles share hidden correlations across space, correlations invisible to local measurement but real nonetheless. Modern spectral imaging points to an analogous truth: materials possess hidden correlations across wavelength, invisible to trichromatic vision but accessible through mathematical reconstruction. In both cases, completeness requires looking beyond what direct observation provides.

This synthesis of hardware specification, file format stewardship, and deep learning reconstruction defines the modern standard for non‑destructive material analysis: a spectral witness to what light alone cannot tell us.


And what about the paint? Here is a physical sample: pigment, substrate, history compressed into matter. Light passes through it, scatters from it, carries fragments of its story: yet the full truth remains hidden until we choose to look deeper. Every layer, every faded stroke, every chemical trace is a silent archive. We are not just observers; we are custodians of that archive. When we build tools to see beyond the visible, we are not merely extending sight: we are accepting a quiet responsibility: to bear witness honestly, to preserve what time would erase, to honor what has been made and endured.

Light can expose structure.
It cannot carry history.

That part is on us.

We can choose to let the machines we build serve memory rather than erasure, dignity rather than classification, truth rather than convenience. The past does not ask for perfection: it asks only that we refuse to let it be forgotten. In every reconstruction, in every layer we uncover, we have the chance to listen again to what was silenced. That is not just engineering. That is the work of being human.

But tonight, sitting here in the dark, I realize I am still riding that same damn train. Hurtling toward one flash, watching the other recede into a past I can never touch, never text, never warn. Information can race forward, people can race forward, but nothing, nothing gets to go back. We are all just riders, carried away from every moment we have already survived, looking for answers in the one direction the universe actually lets us move. Forward. Always forward. And that is the most beautiful, devastating thing I know.


References
1 Einstein, A., Podolsky, B., & Rosen, N. (1935). Can Quantum‑Mechanical Description of Physical Reality Be Considered Complete? Physical Review, 47(10), 777–780.
2 Bell, J. S. (1964). On the Einstein Podolsky Rosen paradox. Physics Physique Физика, 1(3), 195–200.
3 Aspect, A., Dalibard, J., & Roger, G. (1982). Experimental Test of Bell's Inequalities Using Time‑Varying Analyzers. Physical Review Letters, 49(25), 1804–1807.
4 Zhang, Y., Li, L., Lin, Q., Ming, Z., Yu, F., & Leung, V. C. M. M3SR: Multi‑Scale Multi‑Perceptual Mamba for Efficient Spectral Reconstruction.
5 Qin, M., Feng, Y., Wu, Z., Zhang, Y., & Yuan, X. Detail Matters: Mamba‑Inspired Joint Unfolding Network for Snapshot Spectral Compressive Imaging.
6 Cai, Y., Lin, J., Lin, Z., Wang, H., Zhang, Y., Pfister, H., Timofte, R., & Van Gool, L. (2022). MST++: Multi‑stage Spectral‑wise Transformer for Efficient Spectral Reconstruction. Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition Workshops (CVPRW).
7 Gu, A., & Dao, T. (2023). Mamba: Linear‑Time Sequence Modeling with Selective State Spaces. arXiv:2312.00752.

Provenance · Integrity Record
Hashes are of the byte-identical JPEGs converted from raw sensor data. Verify with sha512sum -c SHA512SUMS.
Fingerprint: CA42 47E8 9A5E FEAB 36DC 6A42 C547 9171 B69A 3CFB 887D B92C 3FB1 480A 2993 57A3
The .ots file proves that SHA512SUMS existed at or before the Bitcoin block timestamp below.
Anchor: Bitcoin block 961298
Timestamp: 2026-08-06 13:42 UTC
SHA512SUMS.ots

Wednesday, February 24, 2021

A hardware design for variable output frequency using an n-bit counter

The DE1-SoC from Terasic is an excellent board for hardware design and prototyping. The following VHDL process is from a hardware design created for the Terasic DE1-SoC FPGA. The ten switches and four buttons on the FPGA are used as an n-bit counter with an adjustable multiplier to increase the output frequency of one or more output pins at a 50% duty cycle.

As the switches are moved or the buttons are pressed, the seven-segment display is updated to reflect the numeric output frequency, and the output pin(s) are driven at the desired frequency. The onboard clock runs at 50MHz, and the signal on the output pins is set on the rising edge of the clock input signal (positive edge-triggered). At 50MHz, the output pins can be toggled at a maximum rate of 50 million cycles per second or 25 million rising edges of the clock per second. An LED attached to one of the output pins would blink 25 million times per second, not recognizable to the human eye. The persistence of vision, which is the time the human eye retains an image after it disappears from view, is approximately 1/16th of a second. Therefore, an LED blinking at 25 million times per second would appear as a continuous light to the human eye.

scaler <= compute_prescaler((to_integer(unsigned( SW )))*scaler_mlt);
gpiopulse_process : process(CLOCK_50, KEY(0))
begin
if (KEY(0) = '0') then -- async reset
count <= 0;
elsif rising_edge(CLOCK_50) then
if (count = scaler - 1) then
state <= not state;
count <= 0;
elsif (count = clk50divider) then -- auto reset
count <= 0;
else
count <= count + 1;
end if;
end if;
end process gpiopulse_process;
The scaler signal is calculated using the compute_prescaler function, which takes the value of a switch (SW) as an input, multiplies it with a multiplier (scaler_mlt), and then converts it to an integer using to_integer. This scaler signal is used to control the frequency of the pulse signal generated on the output pin.

The gpiopulse_process process is triggered by a rising edge of the CLOCK_50 signal and a push-button (KEY(0)) press. It includes an asynchronous reset when KEY(0) is pressed.

The count signal is incremented on each rising edge of the CLOCK_50 signal until it reaches the value of scaler - 1. When this happens, the state signal is inverted and count is reset to 0. If count reaches the value of clk50divider, it is also reset to 0.

Overall, this code generates a pulse signal with a frequency controlled by the value of a switch and a multiplier, which is generated on a specific output pin of the FPGA board. The pulse signal is toggled between two states at a frequency determined by the scaler signal.

It is important to note that concurrent statements within an architecture are executed concurrently, meaning that they are evaluated concurrently and in no particular order. However, the sequential statements within a process are executed sequentially, meaning that they are evaluated in order, one at a time. Processes themselves are executed concurrently with other processes, and each process has its own execution context.

Tuesday, August 25, 2020

Creating stronger keys for OpenSSH and GPG

Create Ed25519 SSH keypair (supported in OpenSSH 6.5+). Parameters are as follows:

-o save in new format
-a 128 for 128 kdf (key derivation function) rounds
-t ed25519 for type of key
ssh-keygen -o -a 128 -t ed25519 -f .ssh/ed25519-$(date '+%m-%d-%Y') -C ed25519-$(date '+%m-%d-%Y')
Create Ed448-Goldilocks GPG master key and sub keys.
# gpg --quick-generate-key ed448-master-key-$(date '+%m-%d-%Y') ed448 sign 0
# gpg --list-keys --with-colons "ed448-master-key-08-03-2021" | grep fpr
# gpg --quick-add-key "$fpr" cv448 encr 2y
# gpg --quick-add-key "$fpr" ed448 auth 2y
# gpg --quick-add-key "$fpr" ed448 sign 2y

Sunday, September 2, 2018

96Boards - JTAG and serial UART configuration for ARM powered, single-board computers

The 96boards CE specification calls for an optional JTAG connection. The specification also indicates that the optional JTAG connection shall use a 10 pin through hole, .05" (1.27mm) pitch JTAG connector. The part is readily available on most electronics sites. Breaking out the pins with long wires and shrink wrapping them is ideal for making sure that each connection is labeled and separate when connecting to a JTAG debugger. While a JTAG connection is not required for flashing or loading the bootloaders onto the board, the JTAG connection is useful for advanced chip-level debugging. The serial UART connection is sufficient for loading release or debug versions of bl0, bl1, bl2, bl31, bl32, the kernel, and userspace.  Last but not least, ARM-powered boards, with 12V power input, often require external fans to keep the board cool. As seen in the below photos, two 5V fans were powered from an external power supply. Any work on microcontroller boards should be performed on a grounded surface.  Proper grounding procedures should always be followed as most microcontroller boards contain ESD sensitive components.

In the below photos, a 96Boards SBC is mounted on an IP65, ABS plastic junction box for durability. The pins are extended and mounted with screws underneath the junction box. The electrical conduit holes on the side of the junction box are ideal for holding small, project fans. The remaining electrical conduit holes provide a clean place to place the remaining wires from the board - micro USB, USB-C, and 12V power.


Thursday, June 7, 2018

HiKey 960 Linux Bridged Firewall

The Kirin 960 SoC and on-board USB 3.0 make the HiKey 960 SBC an ideal platform for running a Linux Bridged firewall. The number of single-board computers with an SoC as powerful as the HiSilicon Kirin 960 are limited.

When compared with the Raspberry Pi series of single board computers (SBC), the HiKey 960 SBC is significantly more powerful. The Kirin 960 also stands above the ARM powered SoCs which reside in most commercial routers.

USB 3.0 makes the HiKey 960 board an attractive option for bridging or routing, filtering network traffic, or connecting to an external gateway via IPSec. Both network traffic filtering and IPSec tunneling can be computationally expensive operations. However; the multicore Kirin 960 is well suited for these types of tasks.

In order to be able to run an IPSec client tunnel and a Linux Bridged firewall connected over 1G ethernet links, certain kernel configuration modifications are needed. Furthermore, the Android Linux kernel for the HiKey 960 board does not boot on a standard Linux root filesystem because it is designed to boot an Android customized rootfs.

The latest googlesource Linux kernel (hikey-linaro-4.9) for Android (designed to boot Android on the HiKey 960 board) has been customized to remove the Android specific components so that the kernel boots on a standard Linux root filesystem, with the proper drivers enabled for network connectivity via attached 1000Mb/s USB 3.0 to ethernet adapters. The standard UART interface on the board should be used for serial connectivity and shell access. WiFi and Bluetooth have been removed from the kernel configuration. The kernel should be booted off of a microSDHC UHS-I card. The 96boards instructions should be followed for configuring the HiKey 960 board, setting the jumpers on the board, building and flashing the l-loader, firmware package, partition tables, UEFI loader, ARM Trusted Firmware, and optional Op-TEE. Links for the normal Linux kernel configuration, multi-interface bridge configuration, and single interface IPSec configuration are below. Additional kernel config modifications may be needed for certain types of applications.

kernel build instructions


mkdir /usr/local/toolchains
cd /usr/local/toolchains/
wget https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
tar -xJf gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz
export ARCH=arm64
export CROSS_COMPILE=/usr/local/toolchains/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export PATH=/usr/local/toolchains/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/gcc-aarch64-linux-gnu/bin:$PATH
cd /usr/local/src
git clone https://android.googlesource.com/kernel/hikey-linaro
cd hikey-linaro
git checkout -b android-hikey-linaro-4.9 
make hikey960_defconfig
make -j8

multi-interface bridge configuration 

Bridged configuration, no ip addresses on dual nic interfaces. (crossover cable is useful for testing). Bridge interface obtains dhcp address(/11) from wlan router. aliased interface added to br0 and assigned private subnet ip on different subnet (/8). Spanning tree set on bridge interface. Basic ebtables and iptables ruleset below.

brctl addbr <br>
brctl addif <br> <eth1> <eth2>
ifconfig <br> up
ifconfig <eth1> up
ifconfig <eth2> up
brctl stp <br> yes
dhclient <br>
ifconfig <br>:0 <a.b.c.d/sn> up

iptables --table nat --append POSTROUTING --out-interface <br> -j MASQUERADE
iptables -P INPUT DROP
iptables --append FORWARD --in-interface <br>:0 -j ACCEPT
ebtables -P FORWARD DROP
ebtables -P INPUT DROP
ebtables -P OUTPUT DROP
ebtables -t filter -A FORWARD -p IPv4 -j ACCEPT
ebtables -t filter -A INPUT -p IPv4 -j ACCEPT
ebtables -t filter -A OUTPUT -p IPv4 -j ACCEPT
ebtables -t filter -A INPUT -p ARP -j ACCEPT
ebtables -t filter -A OUTPUT -p ARP -j ACCEPT
ebtables -t filter -A FORWARD -p ARP -j REJECT
ebtables -t filter -A FORWARD -p IPv6 -j DROP
ebtables -t filter -A FORWARD -d Multicast -j DROP
ebtables -t filter -A FORWARD -p X25 -j DROP
ebtables -t filter -A FORWARD -p FR_ARP -j DROP
ebtables -t filter -A FORWARD -p BPQ -j DROP
ebtables -t filter -A FORWARD -p DEC -j DROP
ebtables -t filter -A FORWARD -p DNA_DL -j DROP
ebtables -t filter -A FORWARD -p DNA_RC -j DROP
ebtables -t filter -A FORWARD -p LAT -j DROP
ebtables -t filter -A FORWARD -p DIAG -j DROP
ebtables -t filter -A FORWARD -p CUST -j DROP
ebtables -t filter -A FORWARD -p SCA -j DROP
ebtables -t filter -A FORWARD -p TEB -j DROP
ebtables -t filter -A FORWARD -p RAW_FR -j DROP
ebtables -t filter -A FORWARD -p AARP -j DROP
ebtables -t filter -A FORWARD -p ATALK -j DROP
ebtables -t filter -A FORWARD -p 802_1Q -j DROP
ebtables -t filter -A FORWARD -p IPX -j DROP
ebtables -t filter -A FORWARD -p NetBEUI -j DROP
ebtables -t filter -A FORWARD -p PPP -j DROP
ebtables -t filter -A FORWARD -p ATMMPOA -j DROP
ebtables -t filter -A FORWARD -p PPP_DISC -j DROP
ebtables -t filter -A FORWARD -p PPP_SES -j DROP
ebtables -t filter -A FORWARD -p ATMFATE -j DROP
ebtables -t filter -A FORWARD -p LOOP -j DROP
ebtables -t filter -A FORWARD --log-level info --log-ip --log-prefix FFWLOG
ebtables -t filter -A OUTPUT --log-level info --log-ip --log-arp --log-prefix OFWLOG -j DROP
ebtables -t filter -A INPUT --log-level info --log-ip --log-prefix IFWLOG

single-interface ipsec gateway configuration


iptables -t nat -A POSTROUTING -s <clientip>/32 -o <eth> -j SNAT --to-source <virtualip>
iptables -t nat -A POSTROUTING -s <clientip>/32 -o <eth> -m policy --dir out --pol ipsec -j ACCEPT

Thursday, February 1, 2018

a Hardware Design for XOR gates using sequential logic in VHDL



ModelSim Full Window view with wave form output of xor simulation. ModelSim-Intel FPGA Starter Edition © Intel


XOR logic gates are a fundamental component in cryptography, and many of the typical stream and block ciphers use XOR gates. A few of these ciphers are ChaCha (stream cipher), AES (block cipher), and RSA (block cipher).

While many compiled and interpreted languages support bitwise operations such as XOR, the software implementation of both block and stream ciphers is computationally inefficient compared to FPGA and ASIC implementations.

Hybrid FPGA boards integrate FPGAs with multicore ARM and Intel application processors over high-speed buses. The ARM and Intel processors are general-purpose processors. On a hybrid board, the ARM or Intel processor is termed the hard processor system or HPS. Writing to the FPGA from the HPS is typically performed via C from an embedded Linux build (yocto or buildroot) running on the ARM or Intel core. A simple bitstream can also be loaded into the FPGA fabric without using any ARM design blocks or functionality in the ARM core for a hybrid ARM configuration.

The following is a simple hardware design written in VHDL and simulated in ModelSim. The image contains the waveform output of a simulation in ModelSim. The HPS is not used. On boot, the bitstream is loaded into the FPGA fabric. VHDL components are utilized, and a testbench is defined for testing the design. The entity and architecture VHDL design units are below.
- --three input xnor gate entity declaration - external interface to design entity
entity xnorgate is
port (
a,b,c : in std_logic;
q : out std_logic);
end xnorgate;

architecture xng of xnorgate is
begin
q <= a xnor b xnor c;
end xng;

- --chain of xor / xnor gates using components and sequential logic
entity xorchain is
port (
A,B,C,D,E,F : in std_logic;
Av,Bv : in std_logic_vector(31 downto 0);
CLOCK_50 : in std_logic;
Q : out std_logic;
Qv : out std_logic_vector(31 downto 0));
end xorchain;

architecture rtl of xorchain is
component xorgate is
port (
a,b : in std_logic;
q : out std_logic);
end component;

component xnorgate is
port (
a,b,c : in std_logic;
q : out std_logic);
end component;

component xorsgate is
port (
av : in std_logic_vector(31 downto 0);
bv : in std_logic_vector(31 downto 0);
qv : out std_logic_vector(31 downto 0));
end component;

signal a_in, b_in, c_in, d_in, e_in, f_in : std_logic;
signal av_in, bv_in : std_logic_vector(31 downto 0);

signal conn1, conn2, conn3 : std_logic;

begin
xorgt1 : xorgate port map(a => a_in, b => b_in, q => conn1);
xorgt2 : xorgate port map(a => c_in, b => d_in, q => conn2);
xorgt3 : xorgate port map(a => e_in, b => f_in, q => conn3);
xnorgt1 : xnorgate port map(conn1, conn2, conn3, Q);
xorsgt1 : xorsgate port map(av => av_in, bv => bv_in, qv => Qv);

process(CLOCK_50)
begin
if rising_edge(CLOCK_50) then --assign inputs on rising clock edge
a_in <= A;
b_in <= B;
c_in <= C;
d_in <= D;
e_in <= E;
f_in <= F;
av_in(31 downto 0) <= Av(31 downto 0);
bv_in(31 downto 0) <= Bv(31 downto 0);
end if;
    end process;
end rtl;

entity xorchain_tb is
end xorchain_tb;

architecture xorchain_tb_arch of xorchain_tb is
signal A_in,B_in,C_in,D_in,E_in,F_in : std_logic := '0';
signal Av_in : std_logic_vector(31 downto 0);
signal Bv_in : std_logic_vector(31 downto 0);
signal CLOCK_50_in : std_logic;
signal BRK : boolean := FALSE;
signal Q_out : std_logic;
signal Qv_out : std_logic_vector(31 downto 0);

component xorchain
port (
A,B,C,D,E,F : in std_logic;
Av : in std_logic_vector(31 downto 0);
Bv : in std_logic_vector(31 downto 0);
CLOCK_50 : in std_logic;
Q : out std_logic;
Qv : out std_logic_vector(31 downto 0));
end component;

begin
xorchain_instance: xorchain port map (A => A_in,B => B_in, C => C_in,
D => D_in, E => E_in, F => F_in, Av => Av_in,
Bv => Bv_in, CLOCK_50 => CLOCK_50_in, Q => Q_out,
Qv => Qv_out);
clockprocess: process
begin
while not BRK loop
CLOCK_50_in <= '0';
wait for 20 ns;
CLOCK_50_in <= '1';
wait for 20 ns;
end loop;
wait;
end process clockprocess;

testprocess : process
begin
A_in <= '1';
B_in <= '0';
C_in <= '1';
D_in <= '0';
E_in <= '1';
F_in <= '1';
wait for 40 ns;
A_in <= '1';
B_in <= '0';
C_in <= '1';
D_in <= '0';
E_in <= '1';
F_in <= '0';
wait for 20 ns;
A_in <= '0';
B_in <= '0';
C_in <= '1';
D_in <= '0';
E_in <= '1';
F_in <= '0';
wait for 40 ns;
BRK <= TRUE;
wait;
end process testprocess;
end xorchain_tb_arch;

entity xorgate is
port (
a,b : in std_logic;
q : out std_logic);
end xorgate;

architecture xg of xorgate is
begin
q <= a xor b;
end xg;

entity xorsgate is
port (
av : in std_logic_vector(31 downto 0);
bv : in std_logic_vector(31 downto 0);
qv : out std_logic_vector(31 downto 0));
end xorsgate;

architecture xsg of xorsgate is
begin
qv <= av xor bv;
end xsg;

Saturday, September 17, 2016

Implementing Software-defined radio and Infrared Time-lapse Imaging with Tensorflow on a custom Linux distribution for the Raspberry Pi 3

GNURadio Companion Qt Gui Frequency Sync - multiple FIR filter taps
sample running on Raspberry Pi 3 custom Linux distribution

The Raspberry Pi 3 is powered by the ARM Cortex-A53 processor. This 1.2GHz 64-bit quad-core processor fully supports the ARMv8-A architecture. For this project, a custom Linux distribution was created for the Raspberry Pi 3.  

The custom Linux distribution includes support for GNURadio, several FPGA and ARM Powered SDR devices, D-STAR (hotspot, repeater, and dongle support), hsuart, libusb, hardware real-time clock support, Sony 14 megapixel NoIR image sensor, HDMI and 3.5mm audio, USB Microphone input, X-windows with Xfce, Lighttpd and PHP, Bluetooth, WiFi, SSH, TCPDump, Docker, Docker registry, MySQL, Perl, Python, QT, GTK, IPTables, x11vnc, SELinux, and full native-toolchain development support.

The Sony 14 megapixel image sensor with the infrared filter removed can be connected to the Raspberry Pi 3's MIPI camera serial interface. Image capture and recognition can then be performed over contiguous periods of time, and time-lapsed video can be created from the images. With support for Tensorflow and OpenCV, object recognition within images can be performed.

D-STAR hotspot with time-lapsed infrared imaging.


For the initial run, an infrared Time-lapse Video was created from an initial image capture run of one 3280x2460 infrared jpeg image captured every 15 seconds for three hours. 40, 5mm, 940nm LEDs, powered by 500ma over 12v DC, provided infrared illumination in the 940nm wavelength.

Tensorflow ran in the background (on v4l2 kmod) and provided continuous object recognition and scoring within each image via a sample model. Finally, OpenCV was also installed in the root file system.

The time-lapse infrared video was captured of the living room using the above setup. Below this image are images of Tensorflow running in a terminal in the background on the Raspberry Pi 3 and recognizing/scoring objects in the living room.

Tensorflow running on the Raspberry Pi 3 and continuously capturing frames from the image sensor and scoring objects



 

GNURadio Companion running on xfce on the Raspberry Pi 3

Tuesday, August 16, 2016

Profiling Multiprocess C programs with ARM DS-5 Streamline

The ARM DS-5 Streamline Performance Analyzer is a powerful tool for debugging, profiling, and analyzing multithreaded and multiprocess C programs.  Instructions can easily be traced between load and store operations.  Per process and per thread function call paths can be broken down by system utilization percentage.  Branch mispredictions and multi-level CPU caches can be analyzed. Furthermore, disk I/O usage, stack and heap usage, and a number of other useful metrics can quickly be referenced within the debugger. These are just a few of its capabilities.

In order to capture meaningful information from the DS-5 Streamline Performance Analyzer tool, a Linux, multiprocess, C program was modified to insert 1000 packets into a packet processing simulation buffer.  A code excerpt from the program is below.  The child processes were modified to sleep and then wake 1000 times in order to simulate process activity.  The program was analyzed using the DS-5 Streamline Performance Analyzer tool.  There are two screenshots below the code excerpt where the program is loaded into the DS-5 Streamline Performance Analyzer.

void *insertpackets(void *arg) {

struct pktbuf *pkbuf;
struct packet *pkt;
int idx;

if(arg != NULL) {

pkbuf = (struct pktbuf *)arg;

/* seed random number generator */
...

/* insert 1000 packets into the packet buffer */
for(idx = 0; idx < 1000; ++idx) {

pkt = (struct packet *)malloc(sizeof(struct packet));

if(pkt != NULL) {

/* set the packet processing simulation multiplier to 3 */
pkt->mlt=...()%3;

/* insert packet in the packet buffer */
if(pkt_queue(pkbuf,pkt) != 0) {

...
...
...
...
...
...

int fcnb(time_t secs, long nsecs) {

struct timespec rqtp;
struct timespec rmtp;
int ret;
int idx;

rqtp.tv_sec = secs;
rqtp.tv_nsec = nsecs;

for(idx = 0; idx < 1000; idx++) {

ret = nanosleep(&rqtp, &rmtp);

...
...
... 
 
ARM DS-5 Streamline - Profiling the process creation application

ARM DS-5 Streamline - Code View with C code in the top window
and ARM assembly instructions in the bottom window

https://github.com/brhinton/de0-nano-soc/blob/main/run.c

Thursday, June 30, 2016

VHDL Processes for Pulsing Multiple GPIO Pins at Different Frequencies on Altera FPGA

 
DE1-SoC GPIO Pins connected to 780nm Infrared Laser Diodes, 660nm Red Laser Diodes, and Oscilloscope

The following VHDL processes pulse the GPIO pins at different frequencies on the Altera DE1-SoC using multiple Phase-Locked Loops. Several diodes were connected to the GPIO banks and pulsed at a 50% duty cycle with 16mA across 3.3V. Each GPIO bank on the DE1-SoC has 36 pins. Pin 1 is pulsed at 20Hz from GPIO bank 0, and pins 0 and 1 are pulsed at 30Hz from GPIO bank 1. A direct mode PLL with locked output was configured using the Altera Quartus Prime MegaWizard. The PLL reference clock frequency is set to 50MHz, the output clock frequency is set to 50MHz, and the duty cycle is set to 50%. The pin mappings for GPIO banks 0 and 1 are documented on the DE1-SoC datasheet.

Pulsed Laser Diodes via GPIO pins on DE1-SoC FPGA

- -- ---------------------
- -- CLOCK A AND B PROCESSES --
- -- INPUT: direct mode pll with locked output
- -- and reference clock frequency set to 50MHz,
- -- output clock frequency set to 50MHz with 50% duty
- -- cycle and output frequency scaled by freq divider constant
- -- ----------------------------------------------------------- 
clk_a_process : process (lkd_pll_clk_a)
begin
if rising_edge(lkd_pll_clk_a) then
if (cycle_ctr_a < FREQ_A_DIVIDER) then
cycle_ctr_a <= cycle_ctr_a + 1;
else
cycle_ctr_a <= 0;
end if;
end if;
end process clk_a_process;

clk_b_process : process (lkd_pll_clk_b)
begin
if rising_edge(lkd_pll_clk_b) then
if (cycle_ctr_b < FREQ_B_DIVIDER) then
cycle_ctr_b <= cycle_ctr_b + 1;
else
cycle_ctr_b <= 0;
end if;
end if;
end process clk_b_process; 
- -- ---------------------
- -- GPIO A AND B PROCESSES --
- -- INPUT: direct mode pll with locked output
- -- ------------------------------------------------------- 
gpio_a_process : process (lkd_pll_clk_a)
begin
if rising_edge(lkd_pll_clk_a) then
if (cycle_ctr_a = 0) then
gpio_sig_0 <= NOT gpio_sig_0;
end if;
end if;
end process gpio_a_process;

gpio_b_process : process (lkd_pll_clk_b)
begin
if rising_edge(lkd_pll_clk_b) then
if (cycle_ctr_b = 0) then
gpio_sig_1 <= NOT gpio_sig_1;
end if;
end if;
end process gpio_b_process;
GPIO_0 <= gpio_sig_0;
GPIO_1 <= gpio_sig_1;

Friday, June 3, 2016

FPGA Audio Processing with the Cyclone V Dual-Core ARM Cortex-A9

The DE1-SoC FPGA Development board from Terasic is powered by an integrated Altera Cyclone V FPGA and ARM MPCore Cortex-A9 processor. The FPGA and ARM core are connected by a high-speed interconnect fabric. Linux can be booted on the ARM core and the FPGA and ARM core can communicate.

The DE1-SoC board below has been programmed via Quartus Prime running on Fedora 23, 64-bit Linux. The FPGA bitstream was compiled from the Terasic Audio codec design reference. After the bitstream was loaded on to the FPGA over the USB blaster II interface, the NIOS II command shell was used to load the NIOS II software image onto the chip. A menu-driven, debug interface is running from a terminal on the host via the NIOS II shell with the target connected over the USB Blaster II interface.

A low-level hardware abstraction layer was programmed in C to configure the on-board audio codec chip. The NIOS II chip is stored in on-chip memory and a PLL driven, clock signal is fed into the audio chip. The Verilog code for the hardware design was generated from Qsys. The design supports configurable sample rates, mic in, and line in/out.

Additional components are connected to the DE1-SoC board in this photo. The Linear DC934A (LTC2607) DAC is connected to the DE1-SoC and an oscilloscope is connected to the ground and vref pins on the DAC.

The DC934A features an LTC2607 16-Bit Dual DAC with i2c interface and an LTC2422 2-Channel 20-Bit uPower No Latency Delta Sigma ADC.

3.5mm audio cables are connected to the mic in and line out ports, respectively. The DE1-SoC is connected to an external display over VGA so that a local console can be managed via a connected keyboard and mouse when Linux is booted from uSD.

With GPIO pins accessible via the GPIO 0 and 1 breakouts, external LEDs can be pulsed directly from the Hard Processor System (HPS), FPGA, or the FPGA via the HPS.

Monday, November 9, 2015

Configuring the Altera Cyclone V FPGA SoC Boot loader on a DE0-Nano-SoC board

Understanding the boot loader on a computer system is probably the most important aspect of security. Most computer systems have multiple boot loaders that run in sequence immediately after a power reset is applied to the processor on the computer system.  This applies to embedded, desktop, and server systems.

The Altera Cyclone V SoC has an FPGA and a Hard Processor System (HPS) woven into a single processor package.  The HPS is a dual core ARM Cortex A9.  Building everything from scratch is the best way to figure out how the system works.

The boot sequence on a Cyclone V HPS works like this:

The On-chip ROM (for which source code is not provided) loads the preloader (1st stage bootloader). The preloader then loads U-boot. U-boot then loads the kernel and root file system.

There are two well thought out options for the preloader according to the Cyclone V boot guide.  The two options are licensed differently depending on how the source code is built. One is licensed under a BSD license and the other under GPL v2 with U-Boot.

Building a pre-loader image for the DE0-Nano-SoC board was straightforward.  Altera provides the bsp-editor utility for customizing the preloader configuration and generating the BSP HPS preloader source code, after which, make is used to build the sources using the Mentor ARM cross toolchain.
The preloader settings directory can be found on the DE0-Nano-SoC CD in the DE0_NANO_SOC_GHRD subdirectory.



The preloader load address can be set via the bsp-editor so that the on chip ROM either loads the preloader from an absolute zero address on the sdcard or from a fat partition with id equal to a2 on the sdcard.  These are the options for booting from the sdcard.


After the sources are generated and the preloader image is built using the Makefile, U-boot must be compiled. An Altera port of U-Boot is available on github for the Cyclone V FPGA SoC. U-Boot is built using the Linaro ARM cross toolchain.

There's quite a bit that can be done with the Cyclone V FPGA SoC boot configuration.  FPGA images can be loaded from U-boot.  The jumpers on the board can be configured to boot from the on-board serial flash (QSPI), bare metal applications can be loaded from the preloader, the FPGA can be configured from serial flash, and the list goes on.  The HPS SoC Boot Guide for the Cyclone V SoC  is a valuable reference and contains all of the boot configuration information.

Thursday, October 29, 2015

The "Three Fives" Discrete 555 Timer Kit

The NE555 timer IC is a classic and widely used component in electronic circuits, so building a transistor-scale replica of it is a great way to understand how it works at a fundamental level. It's also a good way to develop your soldering skills and learn how to use an oscilloscope to measure signals in a circuit.

I picked up a "Three Fives" Discrete Timer Kit this weekend. As it turns out the kit was well worth the money. The "Three Fives" Discrete Timer Kit is a transistor-scale replica of the NE555 timer IC. The printed circuit board (PCB) is high-quality and soldering the transistors and resistors was alot of fun. Thanks to Eric Schlaepfer and Evil Mad Scientist Labs for this high quality circuit kit.

The size of the board makes it easy to measure what's going on inside the circuit. Just connect the probes from an oscilloscope to any of the solder or test points on the board.

A photo of the board that I built is below. I also wired a sample test circuit for blinking a pink LED and then connected a scope to the board so that I could look at the square wave.

 






Friday, July 17, 2015

Creating a custom Linux BSP for an ARM Cortex-A9 SBC with Yocto 1.8 - Part III

In part III of this guide, the installation of the final image to the SD card will be covered.  The SD card will then be booted on the target.  Finally, audio recording and playback will be tested.

Part III of this guide consists of the following sections.

  1. Write the GNU/Linux BSP image to an SD card.
  2. Set the physical switches on the RioTboard (Internet of Things) to boot from the uSD or SD card.
  3. Connect the target to the necessary peripherals for boot.
  4. Test audio recording, audio playback, and Internet connectivity.

1.  Write the GNU/Linux BSP image to an SD card

At this point, the build should be complete, without errors.  The output should be as follows.


 real 254m28.335s
user 737m9.307s
sys 133m39.529s

Insert an SD card into an SD card reader, connect it to the host, and execute the following commands on the host.


 host]$ cd $HOME/src/fsl-community-bsp/build /tmp/deploy/images/imx6dl-riotboard
host]$ sudo umount /dev/sd<X>
host]$ sudo dd if=bsec-image-imx6dl-riotboard.sdcard of=/dev/sd<X> bs=1M
host]$ sudo sync


2. Set the physical switches on the RioTboard to boot from the uSD or SD card.


For booting from the SD card on the bottom of the target, set the physical switches as follows.
SD (J6, bottom) 1 0 1 0 0 1 0 1

For booting from the uSD card on the top of the target, set the physical switches as follows.
uSD (J7, top) 1 0 1 0 0 1 1 0

3. Connect the target to the necessary peripherals for boot.

There are two options

Option 1

Connect one end of an ethernet cable to the target. Connect the other end of the ethernet cable to a hub or DHCP server.  

Connect the board to the host computer via the J18 serial UART pins on the target.  This will require a serial to USB breakout cable.  Connect TX, RX, and GND to RX, TX, and GND on the cable. The cable must have an FTDI or similar level shifter chip. Connect the USB end of the cable to the host computer.

Connect the speakers to the light green 3.5 mm audio out jack and the microphone to the pink 3.5 mm MIC In jack.

Connect a 5V / 4 AMP DC power source to the target.

Run minicom on the host computer. Configure minicom at 115200 8N1 with no hardware flow control and no software flow control. If a USB to serial cable with an FTDI chip in it is used, then the cable should show up in /dev as ttyUSB0 in which case, set the serial device in minicom to /dev/ttyUSB0.

If this option was chosen, drop into U-boot after power on by pressing Enter on the host keyboard with minicom open and connected.

If enter is not pressed after power-on, the target will boot and a login prompt will appear.

A login prompt will not appear.

Option 2

Connect one end of an ethernet cable to the target. Connect the other end of the ethernet cable to a hub or DHCP server.  

Connect a USB keyboard, USB mouse, and monitor (via an HDMI cable) to the target.

Connect the speakers to the light green 3.5 mm audio out jack and the microphone to the pink 3.5 mm MIC In jack.

Connect a 5V / 4 AMP DC power source to the target.

A login prompt will now appear.

4. Test audio recording, audio playback, and Internet connectivity


Type root to log in to the target. The root password is not set.

Execute the following commands on the target

 root@imx6dl-riotboard: alsamixer 

Press F6.
Press arrow down so that 0 imx6-riotboard-sgtl5000 is highlighted.
Press Enter.
Increase Headphone level to 79<>79.
Increase PCM level to 75<>75.
Press Tab.
Increase Mic level to 59.
Increase Capture to 80<>80.
Press Esc.

 root@imx6dl-riotboard: cd /usr/share/alsa/sounds
root@imx6dl-riotboard: aplay *.wav

A sound should be played through the speakers.

 root@imx6dl-riotboard: cd /tmp
root@imx6dl-riotboard: arecord -d 10 micintest.wav

Talk into the microphone for ten seconds.

 root@imx6dl-riotboard: aplay micintest.wav

A recording should play through the speakers.

 root@imx6dl-riotboard: ping riotboard.org

An ICMP reply should be received.

Wednesday, July 15, 2015

Creating a custom Linux BSP for an ARM Cortex-A9 SBC with Yocto 1.8 - Part II

In the second part of this guide, the source code will be pulled, the build configuration will be customized, and the build will be executed.  Part II of this guide consists of the following sections.

  1. Pull the Freescale community BSP platform source code from github. 
  2. Setup the build environment using the predefined imx6dl-riotboard RioTboard (Internet of Things) machine.
  3. Create a new layer for the custom Linux distribution.
  4. Customize the image in the meta-bsec layer. 
  5. Create layer.conf file in the meta-bsec layer. 
  6. Create the distribution configuration file in the meta-bsec layer. 
  7. Add the new layer to bblayers.conf.
  8. Customize the local configuration.
  9. Execute
    the build.

1. Pull the Freescale community BSP platform source code from github.


Execute the following commands on the host.
 host]$ mkdir $HOME/bin  
host]$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
host]$ chmod a+x $HOME/bin/repo
host]$ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
host]$ source .bashrc
host]$ mkdir -p $HOME/src/fsl-community-bsp
host]$ cd $HOME/src/fsl-community-bsp
host]$ repo init -u https://github.com/Freescale/fsl-community-bsp-platform -b fido
host]$ repo sync

2. Setup the build environment using the predefined imx6dl-riotboard machine.


Execute the following commands on the host.

 host]$ MACHINE=imx6dl-riotboard . ./setup-environment build  

3. Create a new layer for the custom Linux distribution


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/sources  
host]$ mkdir -p meta-bsec/conf/distro
host]$ mkdir -p meta-bsec/recipes-bsec/images
host]$ cd poky/meta/recipes-extended/images
host]$ cp core-image-full-cmdline.bb \
../../../../meta-bsec/recipes-bsec/images/bsec-image.bb

4. Customize the image in the meta-bsec layer.


Execute the following commands on the host.

  host]$ cd $HOME/src/fsl-community-bsp/sources/meta-bsec/recipes-bsec/images

Customize bsec-image.bb as follows.  Lines with bold text indicate lines to add to the file.

 DESCRIPTION = "A console-only image with more full-featured Linux system \
functionality installed."

# customize IMAGE_FEATURES as follows
IMAGE_FEATURES += "dev-pkgs tools-sdk tools-debug tools-profile tools-testapps \
debug-tweaks splash ssh-server-openssh package-management"

# packagegroup-core-tools-profile will build and install tracing and profiling tools to the target image.
# packagegroup-core-buildessential will build and install autotools, gcc, etc. to the target image.
# kernel-modules for install of the kernel modules.
# kernel-devsrc for building out of tree modules.
# IMAGE_ROOTFS_EXTRA_SPACE_append for adding extra space to the target rootfs image.

# customize IMAGE_INSTALL as follows
IMAGE_INSTALL = "\
packagegroup-core-boot \
packagegroup-core-full-cmdline \
packagegroup-core-tools-profile \
packagegroup-core-buildessential \
kernel-modules \
${CORE_IMAGE_EXTRA_INSTALL} \
kernel-devsrc \
"
inherit core-image

# Add extra space to the rootfs image
IMAGE_ROOTFS_EXTRA_SPACE_append += "+ 3000000"

5. Create layer.conf file in the meta-bsec layer.


Create sources/meta-bsec/conf/layer.conf with the below contents.

BBPATH .= ":${LAYERDIR}"  
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "bsec"
BBFILE_PATTERN_bsec = "^${LAYERDIR}/"
BBFILE_PRIORITY_bsec = "6"


6. Create the distribution configuration file in the meta-bsec layer.


Create sources/meta-bsec/conf/disro/bsecdist.conf with the below contents.

 require conf/distro/poky.conf    
# distro name
DISTRO = "bsecdist"
DISTRO_NAME = "bsecdist distribution"
DISTRO_VERSION = "1.0"
DISTRO_CODENAME = "bsc"
DISTRO_FEATURES_append = " alsa usbhost usbgadget keyboard bluetooth"
SDK_VENDOR = "-bsecdistsdk"
SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"
MAINTAINER = "bsecdist "
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "1"

7. Add the new layer to bblayers.conf


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/build/conf

Customize bblayers.conf by adding the meta-bsec layer to BBLAYERS as follows.

 LCONF_VERSION = "6"

BBPATH = "${TOPDIR}"
BSPDIR := "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../..')}"

BBFILES ?= ""
BBLAYERS = " \
${BSPDIR}/sources/poky/meta \
${BSPDIR}/sources/poky/meta-yocto \
\
${BSPDIR}/sources/meta-openembedded/meta-oe \
${BSPDIR}/sources/meta-openembedded/meta-multimedia \
\
${BSPDIR}/sources/meta-fsl-arm \
${BSPDIR}/sources/meta-fsl-arm-extra \
${BSPDIR}/sources/meta-fsl-demos \
${BSPDIR}/sources/meta-bsec \
"

8. Customize the local configuration


Customize local.conf as follows.

 MACHINE ??= 'imx6dl-riotboard'
# set distro name
DISTRO ?= 'bsecdist'
PACKAGE_CLASSES ?= "package_rpm package_deb"
EXTRA_IMAGE_FEATURES = " "
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS = "\
STOPTASKS,${TMPDIR},1G,100K \
STOPTASKS,${DL_DIR},1G,100K \
STOPTASKS,${SSTATE_DIR},1G,100K \
ABORT,${TMPDIR},100M,1K \
ABORT,${DL_DIR},100M,1K \
ABORT,${SSTATE_DIR},100M,1K"
PACKAGECONFIG_append_pn-qemu-native = " sdl"
PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
ASSUME_PROVIDED += "libsdl-native"
CONF_VERSION = "1"
BB_NUMBER_THREADS = '4'
PARALLEL_MAKE = '-j 4'
DL_DIR ?= "${BSPDIR}/downloads/"
ACCEPT_FSL_EULA = "1"
# archive source code for all of the packages that will be built into the image
INHERIT += "archiver"
ARCHIVER_MODE[src] = "original"
# ensure that license files accompany each binary in final image
COPY_LIC_MANIFEST = "1"
COPY_LIC_DIRS = "1"
# setup source mirror
# make sure that bitbake checks for all of the source tarballs in a local directory
# before going to the Internet to fetch them.
SOURCE_MIRROR_URL ?= "file://${BSPDIR}/source-mirror/"
INHERIT += "own-mirrors"
# create a shareable cache of source code management backends
BB_GENERATE_MIRROR_TARBALLS = "1"

9. Execute the build


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/build 
host]$ time bitbake bsec-image

While the image is building, please take note of the following.

The input specifications for the GNU/Linux kernel and U-boot segments of the BSP are in the below files. These specifications include such things as GNU/Linux kernel patch files for i.MX 6 processor features, kernel boot args, kernel load address, cortex specific tuning parameters, etc.

 sources/meta-fsl-arm-extra/conf/machine/imx6dl-riotboard.conf  
sources/poky/meta-yocto/conf/distro/poky.conf
sources/meta-fsl-arm/recipes-kernel/linux/linux-imx.inc
sources/meta-fsl-arm/recipes-kernel/linux/linux-fslc_4_0.bb
sources/poky/meta/conf/machine/include/tune-cortexa9.inc

In part III of this guide, the image will be booted on the target and then audio will be tested, including recording and playback. Continue to part III of this guide.

Continue to Part III