Monday, May 30, 2016

Bare Metal C with the Raspberry Pi 3 and Sony 8mp NoIR camera

780nm IR Laser Diode pulsed at ~20.2Hz
Sony NoIR 8mp Camera Module for Raspberry Pi 3
Pulsing a laser diode at a frequency over 38 to 40 megahertz from bare metal necessitates an FPGA, microcontroller board with an RTOS running on it, or a dedicated circuit.  Some of the laser diodes that were tested required a simple voltage divider circuit. Others stayed well under 5v and 20ma.

Several different methods of pulsing the GPIO pins were tested; memory mapped IO where the physical ARM peripheral base addresses were mapped into Linux user space via virtual addressing, C and python user space programs that link against user space dynamically linked libraries which in turn read and write the ARM peripheral address space to toggle the GPIO pins, a device driver that disables interrupts and writes to the underlying ARM peripheral address space after being called from a syscall in user space, and bare metal C code that directly writes to the ARM peripheral address space.
780nm IR Laser Diode pulsed at ~20.2Hz
 Sony NoIR 8mp Camera Module

These images were shot using the Sony NoIR 8mp Camera module for the Raspberry Pi 3.

850nm IR Laser Continuous Wave
Sony NoIR 8mp Camera Module





Friday, May 27, 2016

Pulse any GPIO Pin from Bare Metal on a Raspberry Pi 3

Any of the usable GPIO pins on the Raspberry Pi model B can be pulsed from bare metal with a few changes to the code from the prior post. The following commands were used to compile this code on the Raspberry Pi 3 Model B.

$ arm-none-eabi-gcc -O2 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv8-a -mtune=cortex-a53 \ -nostartfiles pulse.c -o kernel.elf






-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

/* 
 * Bare Metal program for toggling any GPIO pin on the Raspberry Pi 3 Model B
 * Copyright (C) 05-27-2016  Bryan R. Hinton
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#define GPIO_BASE  0x3f200000 /* GPIO base address for rpi3 */
#define GPSET0_OFFSET  0x07    /* GPIO Pin Output Set 0 Offset */
#define GPCLR0_OFFSET  0x0a    /* GPIO Pin Output Clear 0 Offset */
#define MAXPINCNT 26

int main(void)
{
   /* static const array of usable gpio pins on raspberry pi 3 */
   static const unsigned int gpiopin[MAXPINCNT] =  {2,3,4,17,27,22,10,9,11,5,6,\
                                   13,19,26,14,15,18,23,24,25,8,7,12,16,20,21};

   /* select pin index */
   int pinidx = 1;

   /* setup gpio base address */
   volatile unsigned int *gpio_base = (unsigned int *)GPIO_BASE;

  /* set gpio(n) for input by clearing bits (GPIO_PIN%10)*3 GPFSEL(N)
   * where (GPIO_PIN%10)*3 is FSEL(N) or the three configuration bits for GPIO(N)
   * 1. Find the gpio function select(gpfsel) register for the GPIO pin.
   *  Pins 0-9 use gpfsel 0
   *  Pins 10-19 use gpfsel 1
   *  Pins 20-29 use gpfsel 2
   *  Pins 30-39 use gpfsel 3
   *  Pins 40-49 use gpfsel 4
   *  Pins 50-53 use gpfsel 5
   * 2. Set or Clear the function select bits in that register for the designated gpio pin
   *  gpio pin 5 is set for input in gpfsel 0 by clearing bits 15-17  
   *  gpio pin 5 is set for output in gpfsel 0 by setting bits 15-17 to 001  
   *  gpio pin 22 is set for input in gpfsel 2 by clearing bits 6-8  
   *  gpio pin 22 is set for output in gpfsel 2 by setting bits 6-8 to 001 */

  /*  set gpiopin[pinidx] for input by clearing bits k,k+1,K+2 in gpfsel n.
   *  gpfsel(2) gpiopin 22 bit string mask for gp input 11111111111111111111111000111111 (rval)
   *  gpfsel(0) gpiopin 3 bit string mask for gp input 11111111111111111111000111111111 (rval) */
   *(gpio_base + (*(gpiopin+pinidx)%10)) &= ~(7  < ((*(gpiopin+pinidx)%10)*3));

  /*  set gpiopin[pinidx] for output by setting bits k,k+1,k+2 to 001 in gpfsel n.
   *  gpfsel(2) gpiopin 22 bit string mask for gp output 00000000000000000000000001000000 (rval)
   *  gpfsel(2) gpiopin 3 bit string mask for gp output 00000000000000000000001000000000 (rval) */
   *(gpio_base + (*(gpiopin+pinidx)%10)) |= (1 << ((*(gpiopin+pinidx)%10)*3));

   /* iterate through each usable gpio pin and pulse it */
   while(1) {

      /* set gpio pin */
      *(gpio_base + GPSET0_OFFSET) |= (1 << (*(gpiopin+pinidx)));

      /* clear gpio pin */
      *(gpio_base + GPCLR0_OFFSET) &= (1 << (*(gpiopin+pinidx)));
   }
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJXSN4dAAoJEKJTsaf+3Ky+11EP/3uf38uUC7SbyAE5Jp0SwfMC
YhIgC92Erb4A5OKK9dOx7FzCgwCdU7ifoCjPcjZonxkFqMt/lEpFa7MaqHqpsUWt
vxHmXHx5V/9WCVAy8acunAlVcWhimls9dqJni5gfIpSH80C1Nvph14UTgYB3ejs+
onCsipkIqK4/YOih58ZNqHYOleVvX8DpQvnY+mGgqYzuhITtOddgYmgmwK3FOy6s
1EjP3xLo3ovs1FGX11j/ZRdlpoh1MnivJtUNIuTXMv+4BYKv8asQbDdukkYYRM+L
VEulKrjYveJZtiWElZ0csL1sMoeBZV4pWsKhtriWcS08XsscqJXc2D8RrlgbrR08
MhoKYoXUZcAxH6pXJC6KkI/pIITKkhqzO+XgoOL+VLiUqldMu00sWUuk9muHx4EH
jtSxpI9aQZOiNwDe+iomOsIfwFA5Zon6TAga0EesMUDGRt9/qlYM2y7nwooOZAkD
/Jinz/QmYp9+bRkxDMUiBm8zwa4o6EkfycJ33Sye4fviwmjwUgftBUPKWgCDldac
Qk7VbMSzjlyJ/wPOOIGEppDcQXwwH87d1TOwy+sr2OLjO2eZpAs7P6ZgV9YNcVvA
CZKGPD6fZm5jkVYjNjbxyHk517uuCIUWYptCFFPUnNbCPvLl3klsBasStG+7HJCP
/IPgYPuswmijA06lAC4I
=y2H9
-----END PGP SIGNATURE-----


Github Repo

Thursday, May 26, 2016

Pulse an IR Laser from Bare Metal on the Raspberry Pi 3



Pulsing an LED or Laser from code running on bare metal is faster than pulsing the LED or Laser from userspace on a preemptive, time sliced operating system such as Linux.  The GPIO pins on the Raspberry Pi 3 model B can be toggled via bare metal code.  The following code was cross-compiled on Linux using the latest generic ARM toolchain for the Quad Core Cortex-A53 processor on the Raspberry Pi 3 model B.


The Cortex-A53 supports the ARMv8-A Architecture.  The following commands were used to compile this code on the Raspberry Pi 3. Please note, you will need to pull bootcode.bin and start.elf from the Raspberry Pi github master branch.





$ arm-none-eabi-gcc -O2 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv8-a -mtune=cortex-a53 \ -nostartfiles pulse.c -o kernel.elf
$ arm-none-eabi-objcopy kernel.elf -O binary kernel7.img
$ cp kernel7.img kernel.img



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


/* 
 * Bare Metal program for toggling a GPIO pin on the Raspberry Pi 3 Model B
 * Copyright (C) 05-26-2016  Bryan R. Hinton
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#define GPIO_BASE  0x3f200000 /* GPIO base address for rpi3 */
#define GPSET0_OFFSET  0x07    /* GPIO Pin Output Set 0 Offset */
#define GPCLR0_OFFSET  0x0a    /* GPIO Pin Output Clear 0 Offset */
#define GPFSEL2_OFFSET  0x02    /* GPFSEL2 Offset */
#define GPFSEL_OFFSET GPFSEL2_OFFSET
#define GPIO_PIN 22

int main(void)
{
   /* setup gpio base address */
   volatile unsigned int *gpio_base = (unsigned int *)GPIO_BASE;
  
  /* clear gpio(n) for input by setting bits (GPIO_PIN%10)*3 to 000 in GPFSEL(N)
   * where (GPIO_PIN%10)*3 is FSEL(N) or the three configuration bits for GPIO(N)
   */
  *(gpio_base + GPFSEL2_OFFSET) &= ~(7 << (GPFSEL2_OFFSET*3));
  /* set gpio(n) for output by setting bits (GPIO_PIN%10)*3 to 001 in GPFSEL(N)
   * for FSEL(N) 
   */
  *(gpio_base + GPFSEL2_OFFSET) |= (1 << ((GPFSEL2_OFFSET)*3));

   while(1) {
      /* set gpio pin */
      *(gpio_base + GPSET0_OFFSET) |= (1 << GPIO_PIN);
      /* clear gpio pin */
      *(gpio_base + GPCLR0_OFFSET) &= (1 << GPIO_PIN);
  }
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJXR79kAAoJEKJTsaf+3Ky+ZGcP/RwA6WePGwbcSrbFIERqIdHG
hrIA48VpwUQ/SIVvKyH93fvTzlqfrSrHzFbI9IUmqtZgWOah1X/dCfnFSrNRTn4x
6ZaZgCADlKCuarC/7tuMLkqtP6cOuvH0rWsKAtEIkmSyFPp22GttkkiHrW6ZvKZd
Z9AybVJ5XemzYVwolnkdFFb8C6oFwijaKqbkUrlHFEvvyILnsrnNhKo18iQ3dEaH
fvZCwDRMYOrHM8XqMb0ZVP27UBAuXlkaFElNeHs0iG1qmS82C7fFRwlAQe9PWo87
0xzYyeP93+pQFCo5lRtdRsm3w9R6gkhliKztyRVROiL0onzi/MGc850JX9TkWwP+
z1+uSJNf93THe9vNc9SMiuMPmx2SjCTT2WoVKFJ31K8PYvGA7nfOD/s0msV02WKr
hnPVDdQDzGSYio4uIs5J4QDvNgfFjxMZSvZvWgT/vuI3KZVxwVDU1VQxAtlx3BuA
CCBSbVa0X2Wum6XQqafZuXd11I3IIMoFXFHIH1VwLdxRYVWBtC8Bj41hR9iiOKXo
3omOCve73GozpgDMaW53BoyFqNYbyqzRN6JUtvbO8ST6a/szWARZcVOI4bwHZPIB
cSSQ75YszsNz7rSTGMdyNOy4V4e7YrfSyBn/Arc1FWmtPddU55DEjXy5mqiUIep6
lsPoPUfgviuYvzqtEVxR
=RCpP
-----END PGP SIGNATURE-----

Sunday, May 22, 2016

Pulse an IR Laser at Multiple Frequencies with the Raspberry Pi 3


The following C program pulses an Infrared laser at multiple frequencies using the GPIO pin on the Raspberry Pi 3.  The program can be compiled on the Raspberry Pi 3 and is dynamically linked against the Wiring Pi library.

Please note, preemptive time slicing in the stock Raspbian kernel restricts the frequency at which the laser can be pulsed.







/* 
Copyright (c) 2016, Bryan R. Hinton
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

/* set mode of gpio pin on rpi3 */
void gpio_setup(const unsigned int *gpiopin, int mode)
{
pinMode(*gpiopin, mode);
}

/* toggle laser on gpio pin at two different frequencies */
void gpio_toggle_pin(const unsigned int *gpiopin, const unsigned int *delay_a_usec, const unsigned int *delay_b_usec)
{

for(;;) {
/* toggle pin high */
digitalWrite(*gpiopin, HIGH);
/* wait for delay_a_usec microseconds */
delayMicroseconds(*delay_a_usec);
/* toggle pin low */
digitalWrite(*gpiopin, LOW);
/* wait for delay_a_usec microseconds */
delayMicroseconds(*delay_a_usec);

/* toggle pin high */
digitalWrite(*gpiopin, HIGH);
delayMicroseconds(*delay_b_usec);
/* wait for delay_b_usec microseconds */

/* toggle pin low */
digitalWrite(*gpiopin, LOW);
delayMicroseconds(*delay_b_usec);
/* wait for delay_b_usec microseconds */
}

}

int main(int argc, char **argv)
{
/* gpio pin 17 on rpi3 is pin 0 in wiringpi */
const unsigned int gpiopin17 = 0x00;
/* 500000 microseconds */
const unsigned int delay_a_usec = 500000;
/* 225000  microseconds */
const unsigned int delay_b_usec = 225000;

/* no parameters allowed */
if(argc > 1) {
printf("error: argc > 1\n");
return EXIT_FAILURE;
}
/* setup wiring pi library. requires root */
if(wiringPiSetup() < 0) { 

printf("wiringPiSetup() error\n");
return EXIT_FAILURE;
}

/* set gpio pin to mode */
gpio_setup(&gpiopin17, OUTPUT);

/* toggle laser at two different frequencies */
gpio_toggle_pin(&gpiopin17, &delay_a_usec, &delay_b_usec);

return EXIT_SUCCESS;
}

Tuesday, March 29, 2016

Identification & Authentication

Cherry Blossoms








Identification


Identification is the process whereby a human or computer presents its identity to another human or computer. When you claim that you are a certain person, you are presenting your identity. This process is known as identification.  

For example, when you introduce yourself to someone, you present your identity to her.  When you travel on a plane, you have to wait in a line to have your bags checked.  Before placing your bags on the conveyor belt to be scanned, you present your driver's license or government ID card to a law enforcement, security officer.   The process of presenting your ID card to the officer is called identification.   

Authentication


After you present your ID card to the officer, she reads your ID card and compares your physical face to the printed photo of your face.  The process of comparing your physical face to the printed face on the ID card is called authentication.  If your physical face matches the face on the printed ID card, then you are successfully authenticated. The officer may also compare your name on the ID card against the name that is printed on the airline ticket. 

The process of validating your identity is called authentication.  Formally, authentication is the process whereby a human or computer validates that you are who you say you are.

Human-Generated Facial Signatures


When the officer views your photo on the ID card, she looks for distinguishable physical characteristics on your face.  She identifies features on your face. It is this combination of unique characteristics that forms a visual signature of you. She then looks at your physical face and creates a second physical signature, after which she compares the signature of your printed face with the signature of your physical face.  If they match, then you are successfully authenticated and can proceed to the conveyor belt. She may also perform additional checks as already mentioned.  

The process that her brain performs when creating human facial signatures and storing them in her brain's memory is called an algorithm. Formally, an algorithm is a finite sequence of steps or rules that produce a solution to a problem.  

Computer-Generated Facial Signatures


Computers can execute algorithms more efficiently than humans. While the human brain can form a visual signature of someone by identifying unique combinations of visual, facial characteristics, a computer can also create a visual signature of a person's identity.  In contrast to a human, a computer can identify millions of tiny pixels in a photograph and compare them against the pixels in another photograph. Computer algorithms perform shading and blending to identify facial features with extreme precision.  A unique signature is generated that is both computationally complex and reproducible. If you are standing at a 90 degree angle to a camera instead of an 85 degree angle, then the same unique signature of your face can be generated.  If you are standing at an 80 degree angle to the camera and you are wearing make up, then the same signature can be created. If there are 300 million other people also getting their photos taken at these angles, both with and without makeup, the computer can still generate unique signatures for every single human. The computer representation of this information is typically a long string of numbers. Your name and birth date are typically appended to this long string of numbers.  The entire string or a partial length of the string are then stored in computer memory so that the computation of the signature can be easily recalled when needed.  Replacing your name with someone else's name in this string or modifying your unique physical characteristics could mean the creation of an identity that is not you.  

It is for this reason that your signature must be stored in a secure computer system.  Microprocessor-based storage chips often provide an encrypted, non-volatile medium for the storage of identification information.  This cryptographic storage medium is usually accompanied by a small, embedded, and highly optimized microprocessor for performing computationally expensive cryptographic operations or algorithms such as encryption, decryption, and signature generation.

As we grow older and our physical features change, computer algorithms should compensate for these changes and generate the same or similar unique signatures. DNA can also be used to uniquely identify humans.  Computer algorithms should properly compensate for changes in human DNA so that individuals can be uniquely identified.


Resources


Sunday, November 8, 2015

Configuring the 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 Captain America logo was popular this Halloween. 

So I picked up a couple of Altera FPGA SoC boards a few weeks ago and immediately pulled up all of the documentation that I could find on the Cyclone V SoC.  This 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 you build the source code.  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 you can do 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.



Wednesday, October 28, 2015

Altera Cyclone V FPGA SoC - the Possibilities are endless

Altera FPGA SoC and Camera
Altera FPGA ARM Powered® SoC and Camera - the Possibilities are endless

Altera's new Cyclone V FPGA SoC - An Integrated ARM® Cortex®-A9 MPCoreTM Processor System and Cyclone V FPGA.

The DE0-Nano-SoC development board was released by Terasic in the summer of 2015 and includes the lateset Cyclone V FPGA SoC.  The board comes with a wealth of features including an analog to digital converter (LTC2308) and has an Arduino expansion header. 


There are an adequate number of programmable logic elements on the FPGA - 40K along with 5 fractional PLLs and 2460 Kbits of embedded memory.  The ARM® Cortex®-A9 MPCore Dual Core processor (HPS) runs at 925Mhz and the board has 1GB of DDR3 SDRAM.   The board also includes an on board ethernet PHY, USB OTG and Micro-AB connectors, a micro SD card slot, accelerometer, and built-in USB Blaster II.

Altera Quartus II 15.0 Web Edition and Altera SoC Embedded Design Suite with ARM DS-5 AE run seamlessly on X86 64 Fedora 21.  The board supports OpenCL so you can easily program the FPGA from Linux user space running on the HPS. Finally, writing a newly compiled bitstream to the FPGA from Quartus II running on an attached Linux host was also seamless.