Raspberry Pi based Stratum 1 NTP Server Notes

The Raspberry Pi is a low cost ARM7 based singleboard linux computer. The most useful feature of the Raspberry Pi is the built in GPIO that functions very similar to a PIC micro controller.

Parts

Total: $?

Wiring Guide

  • P1-01 (+3.3V power) to VIN (supply voltage)
  • P1-06 (Ground) to GND
  • P1-08 (UART0_TXD) to RX (serial data in)
  • P1-10 (UART0_RXD) to TX (serial data out)
  • P1-12 (GPIO18) to PPS (pulse-per-second output)

Hardware Setup

  1. Using a dremel, cut off the standoff in the enclosure closest to the hinge
  2. Drill a hole on the top side large enough to show the 'in' port on the POE splitter (don't leave enough room to show the POE voltage switch, if someone switches it to anything other than 5v, it will destroy the raspberry pi)
  3. Drill a hole beside the POE splitter for the antenna to connect
  4. Adhere the POE splitter next to it's hole with double sided tape
  5. Attach the antenna SMA to uFL adaptor to the enclosure
  6. Crimp an ethernet cable that is about 6" long, the connector must be as small as possible
  7. Cut the included POE power cable in half and strip the wires
  8. Cut the Standard A end off of the right-angle micro usb cable, strip the wires (cut off the white and green wires, those are for data and we don't need them)
  9. Splice the POE power cable onto the USB cable by soldering the wires together, use heat shrink to seal the wire
    • On the POE power cable, the wire with the long block stripe is positive
  10. Assemble the raspberry pi into the enclosure (on the side closest to the hinge) adhering it with double sided tape

Software Setup

This is for very early versions, for newer (2018) setups see: http://www.unixwiz.net/techtips/raspberry-pi3-gps-time.html however remember to reboot after modifying /boot/config.txt and check for newer versions of gpsd if compiling from src.

Old notes where:

  1. Perform Initial Setup
    1. Image the SD card with the latest version of raspbian - See the wiki for more information
      • Raspbian can be found at raspberrypi.org, the latest version as of this page being written is 2013-09-25-wheezy
      • If using a unit that already has our custom image on it, the cscf-adm account will still need to be added as of March 2014 (it was forgotten)
    2. Connect the SD card, power, network and a keyboard to the raspberry pi
    3. Configure the raspberry pi on the configuration screen
      1. Select Advanced Options -> Update to update the tool
      2. Select Expand Filesystem to increase the partition size from 2Gb to the size of your SD card
      3. Select Change User Password and enter a temporary password (this account will be deleted later)
      4. Select Finish
    4. Reboot
         sudo reboot
    • The MAC address isn't labelled on the machine itself, to retrieve it run ifconfig and look for HWaddr associated with eth0
  2. Setup network
    • Assign an IP address to the machine in E&I using the previously obtained MAC address, DHCP should automatically assign the correct address on startup
    1. Change the hostname
         sudo nano /etc/hostname
    2. Update the hosts file with the previously chosen hostname to point to localhost
         sudo nano /etc/hosts
  3. Setup user accounts
    • By default, the only user on the raspbian image is the user "pi" with the password "raspberry"
    1. Add both the cscf-adm and cscf-op accounts
         sudo adduser cscf-adm
      • Use the current appropriate passwords. If unsure, get the current password from the safe or ask Phil.
    2. Edit /etc/group and add both the cscf-adm and cscf-op accounts to the same groups as the "pi" user (excluding the pi group)
         sudo nano /etc/group
      • Ensure that both are added to the adm and sudo groups
    3. Logout of "pi" and login as either cscf-op and cscf-adm
    4. Remove the user "pi"
         sudo userdel pi
    5. Delete the "pi" home directory
         sudo rm -rf /home/pi
  4. Setup Advanced Packaging Tool and update
    1. Become root
         sudo -s
    2. Edit /etc/apt/sources.list and add deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi to the last line of the file so that later on we can recompile the NTP sources
    3. Update the raspberry pi
         apt-get update
         apt-get upgrade
         apt-get dist-upgrade
         apt-get autoclean
    4. Configure hostname under /etc/hostname and /etc/hosts
  5. Disable the serial console
    • We are going to use the default serial port on the GPIO (aka ttyAMA0) to transmit GPS data. By default this interface is used as a console so we need to disable it.
    • Edit the command line file at /boot/cmdline.txt and remove console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
      • The cmdline.txt for bigben is
        dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
    • Edit /etc/inittab and comment out (add a # to the beginning of the line) the line regarding the serial line
      #Spawn a getty on Raspberry Pi serial line
      #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 
    • Reboot
         reboot
  6. Recompile the kernel
    • In order to tell the Raspberry Pi where to receive the PPS signal, we need to recompile the kernel with some changes. Since compiling it on the Pi takes about 8 hours, we will be using a Thinkpad T420s running Ubuntu 12.04 LTS and cross compiling it for the Pi.
    • Under the rpi folder in the CORE Asimov share, there is a kernel that was compiled November 2013, this can be used but it is highly recommended that the kernel be recompiled from scratch using the latest version
    1. Create a directory called 'pi-compile' under your home directory of the machine you are using to compile. The name and location don't really matter, this is just to keep everything in one place
    2. Install the appropriate packages for compiling the kernel
          sudo apt-get install gcc-arm-linux-gnueabi make ncurses-dev
    3. Get the kernel sources (ensure that your current directory is your working directory we just made)
           wget 'https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz'
           tar xvzf rpi-3.6.y.tar.gz
           mv linux-rpi-3.6.y linux
    4. Ensure that the kernel source is clean (no configuration)
           make mrproper
    5. On the raspberry pi, copy the kernel configuration and send it to the 'compile machine'
           gunzip -c /proc/config.gz >config
           scp config cscf-op@192.168.1.209:/home/cscf-op/pi-compile
      • Replace the destination path, user and address to the appropriate information for your compile machine
    6. On the compile machine, copy the config file to .config at the top directory of the 'linux' folder (note the leading dot)
  7. Configure Cross-Development Toolchain and Apply Configuration
    1. To figure out the common prefix for the build programs run
      which arm-linux-gnueabi-gcc
      • This should give you an output similar to
        /usr/bin/arm-linux-gnueabi-gcc
    2. Set the environment variable CCPREFIX to the proper path we found out previously
      • In this case, we will omit the 'gcc' at the end of the path, the configure script should add that manually otherwise it will not configure properly
        export CCPREFIX='/usr/bin/arm-linux-gnueabi-'
    3. Apply the configuration we stole from the raspberry pi (ensure you are in the top directory of the kernel source)
      make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
  8. Make Changes to the Kernel Configuration
    1. To start the menu-based config editor, run
      make ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
    2. Under Device Drivers -> PPS Support, highlight PPS Support and hit M to configure it as a module
    3. Scroll down and hit M on PPS client using GPIO to configure it as well
      • To exit the menu, hit the right arrow key to highlight exit and hit enter
    4. Exit the menu. When asked, save the configuration
  9. Configure PPS Support
    • At this point, you must decide what GPIO pin that will be used for the PPS signal, in this case we will be using GPIO #18
    1. Edit arch/arm/mach-bcm2708/bcm2708.c to make 3 changes
      1. Include the header linux/pps-gpio.h under the line "#include "
        #include <linux/delay.h>
        #include <linux/pps-gpio.h>
      2. Under "#endif" at the end of the headers, add the following information to specify what GPIO pin we are using
        /* PPS-GPIO platform data */
        static struct pps_gpio_platform_data pps_gpio_info = {
           .assert_falling_edge = false,
           .capture_clear= false,
           .gpio_pin=18,
           .gpio_label="PPS",
        };
        
        static struct platform_device pps_gpio_device = {
           .name = "pps-gpio",
           .id = -1,
           .dev = { .platform_data = &pps_gpio_info },
        };
        • You can modify .gpio_pin=18 to the pin that you choose, as long as it is a GPIO input/output pin it shouldn't matter
      3. Call bcm_register_device(&pps_gpio_device); under "bcm_register_device(&bcm2708_gpio_device);" (near the end of the file) to register the PPS signal as a device
                bcm_register_device(&bcm2708_dmaman_device);
                bcm_register_device(&bcm2708_vcio_device);
        #ifdef CONFIG_BCM2708_GPIO
                bcm_register_device(&bcm2708_gpio_device);
                bcm_register_device(&pps_gpio_device);
        #endif
    2. Return to the top level of the kernel source folder and build the kernel
      make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j5
  10. Install Modules and Update GPU Firmware/Libraries
    • We need to also get the modules for the kernel we built, while in the same directory as before, run the following command (replace cscf-op/pi-compile with the path to your working directory we created earlier)
      make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=~cscf-op/pi-compile/temp_modules modules_install
    1. Download the GPU firmware/libraries and extract them, run this while in your working directory
      wget 'https://github.com/raspberrypi/firmware/archive/next.tar.gz'
      tar xvzf next.tar.gz
    2. Move up a directory and SCP the files back over to the Pi (Replacing the correct information for the Pi)
      scp -r pi-compile cscf-op@192.168.1.114:/home/cscf-op/
  11. Apply the updates
    1. Copy linux/arch/arm/boot/zImage to /boot/kernel.img
    2. Copy temp_modules/lib/modules/3.6.11 to /lib/modules/3.6.11
    3. Copy temp_modules/lib/firmware to /lib/firmware
    4. Copy boot loader files
      1. firmware-next/boot/bootcode.bin to /boot/bootcode.bin
      2. firmware-next/boot/fixup.dat to /boot/fixup.dat
      3. firmware-next/boot/start.elf to /boot/start.elf
      4. firmware-next/hardfp/opt/vc to /opt/vc
    5. Run sync twice
    6. Reboot
    7. Add pps-gpio to the end of /etc/modules
    8. Reboot
    9. Confirm that the pps modules are loaded by running lsmod
      • pps_gpio and pps_core should appear
  12. Change the cpu_scaling and the serial latency
    1. echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    2. setserial /dev/ttyAMA0 low_latency
  13. Install and Configure NTP
    1. Remove the default NTP installation
      apt-get remove ntp --purge
    2. Copy the ntp-compile installation folder from the rpi folder under Asimov's CORE share.
      • Normally when compiling this (retrieving the source from apt-get source ntp) it's just a matter of adding --with-ATOM but the source isn't downloading the config folder anymore, the last main version change for ntp was in 2012 so having a precompiled version shouldn't make much of a difference
    3. Install the modified NTP
      dpkg -i ntp_4.2.6.p5+dfsg-3~pps1_armhf.deb
    4. If using DHCP, remove ntp-servers from the request line in /etc/dhcp/dhclient.conf
    5. Remove /var/lib/ntp/ntp.conf.dhcp if present
    6. Edit /etc/init.d/ntp and change
      if [ -e /var/lib/ntp/ntp.conf.dhcp ]; then
      to
      if [ -e /etc/ntp.conf ]; then 
          NTPD_OPTS="$NTPD_OPTS -c /etc/ntp.conf" 
      elif [ -e /var/lib/ntp/ntp.conf.dhcp ]; then
    7. Replace the current /etc/ntp.conf with the version in the rpi folder on the CORE Asimov share.
    8. Restart NTP
      service ntp restart
    9. Verify configuration
      • You can run ntpq -p to check any peers and ntpq -c rl and ntpq -c rv to check the status of the server (such as stratum level)

References

Topic revision: r15 - 2018-10-24 - DaveGawley
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback