add an initial version of WPILib

This is our commit 24ccb7836abaa36b0e913474c818da4b6ae7bc9a which
corresponds with FPGA image v23.

Change-Id: I25b999bbcef39aaea6132562c80360d87780b8c3
diff --git a/aos/externals/allwpilib/hal/include/HAL/Accelerometer.hpp b/aos/externals/allwpilib/hal/include/HAL/Accelerometer.hpp
new file mode 100644
index 0000000..103fb2a
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Accelerometer.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+enum AccelerometerRange {
+	kRange_2G = 0,
+	kRange_4G = 1,
+	kRange_8G = 2,
+};
+
+extern "C" {
+	void setAccelerometerActive(bool);
+	void setAccelerometerRange(AccelerometerRange);
+	double getAccelerometerX();
+	double getAccelerometerY();
+	double getAccelerometerZ();
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Analog.hpp b/aos/externals/allwpilib/hal/include/HAL/Analog.hpp
new file mode 100644
index 0000000..981aa9e
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Analog.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+enum AnalogTriggerType
+{
+	kInWindow = 0,
+	kState = 1,
+	kRisingPulse = 2,
+	kFallingPulse = 3
+};
+
+extern "C"
+{
+	// Analog output functions
+	void* initializeAnalogOutputPort(void* port_pointer, int32_t *status);
+	void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status);
+	double getAnalogOutput(void* analog_port_pointer, int32_t *status);
+	bool checkAnalogOutputChannel(uint32_t pin);
+
+	// Analog input functions
+	void* initializeAnalogInputPort(void* port_pointer, int32_t *status);
+	bool checkAnalogModule(uint8_t module);
+	bool checkAnalogInputChannel(uint32_t pin);
+
+	void setAnalogSampleRate(double samplesPerSecond, int32_t *status);
+	float getAnalogSampleRate(int32_t *status);
+	void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
+	uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t *status);
+	void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
+	uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t *status);
+	int16_t getAnalogValue(void* analog_port_pointer, int32_t *status);
+	int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status);
+	int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t *status);
+	float getAnalogVoltage(void* analog_port_pointer, int32_t *status);
+	float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status);
+	uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t *status);
+	int32_t getAnalogOffset(void* analog_port_pointer, int32_t *status);
+
+	bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status);
+	void initAccumulator(void* analog_port_pointer, int32_t *status);
+	void resetAccumulator(void* analog_port_pointer, int32_t *status);
+	void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *status);
+	void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t *status);
+	int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status);
+	uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status);
+	void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *count,
+			int32_t *status);
+
+	void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *status);
+	void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status);
+	void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int32_t upper,
+			int32_t *status);
+	void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower, double upper,
+			int32_t *status);
+	void setAnalogTriggerAveraged(void* analog_trigger_pointer, bool useAveragedValue,
+			int32_t *status);
+	void setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValue,
+			int32_t *status);
+	bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status);
+	bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status);
+	bool getAnalogTriggerOutput(void* analog_trigger_pointer, AnalogTriggerType type,
+			int32_t *status);
+
+	//// Float JNA Hack
+	// Float
+	int getAnalogSampleRateIntHack(int32_t *status);
+	int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t *status);
+	int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t *status);
+
+	// Doubles
+	void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t *status);
+	int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage, int32_t *status);
+	void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer, int lower, int upper,
+			int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/CAN.hpp b/aos/externals/allwpilib/hal/include/HAL/CAN.hpp
new file mode 100644
index 0000000..80b589c
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/CAN.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <stdint.h>
+#include "NetworkCommunication/CANSessionMux.h"
+
+void canTxSend(uint32_t arbID, uint8_t length, int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
+
+void canTxPackInt8 (uint32_t arbID, uint8_t offset, uint8_t  value);
+void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
+void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
+void canTxPackFXP16(uint32_t arbID, uint8_t offset, double   value);
+void canTxPackFXP32(uint32_t arbID, uint8_t offset, double   value);
+
+uint8_t  canTxUnpackInt8 (uint32_t arbID, uint8_t offset);
+uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
+uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
+double   canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
+double   canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
+
+bool canRxReceive(uint32_t arbID);
+
+uint8_t  canRxUnpackInt8 (uint32_t arbID, uint8_t offset);
+uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
+uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
+double   canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
+double   canRxUnpackFXP32(uint32_t arbID, uint8_t offset);
diff --git a/aos/externals/allwpilib/hal/include/HAL/Compressor.hpp b/aos/externals/allwpilib/hal/include/HAL/Compressor.hpp
new file mode 100644
index 0000000..5c222eb
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Compressor.hpp
@@ -0,0 +1,37 @@
+/**
+ * Compressor.h
+ * Methods for interacting with a compressor with the CAN PCM device
+ */
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifndef __HAL_COMPRESSOR_H__
+#define __HAL_COMPRESSOR_H__
+
+extern "C" {
+	void *initializeCompressor(uint8_t module);
+	bool checkCompressorModule(uint8_t module);
+	
+	bool getCompressor(void *pcm_pointer, int32_t *status);
+	
+	void setClosedLoopControl(void *pcm_pointer, bool value, int32_t *status);
+	bool getClosedLoopControl(void *pcm_pointer, int32_t *status);
+	
+	bool getPressureSwitch(void *pcm_pointer, int32_t *status);
+	float getCompressorCurrent(void *pcm_pointer, int32_t *status);
+
+	bool getCompressorCurrentTooHighFault(void *pcm_pointer, int32_t *status);
+	bool getCompressorCurrentTooHighStickyFault(void *pcm_pointer, int32_t *status);
+	bool getCompressorShortedStickyFault(void *pcm_pointer, int32_t *status);
+	bool getCompressorShortedFault(void *pcm_pointer, int32_t *status);
+	bool getCompressorNotConnectedStickyFault(void *pcm_pointer, int32_t *status);
+	bool getCompressorNotConnectedFault(void *pcm_pointer, int32_t *status);
+	void clearAllPCMStickyFaults(void *pcm_pointer, int32_t *status);
+}
+
+#endif
+
diff --git a/aos/externals/allwpilib/hal/include/HAL/Digital.hpp b/aos/externals/allwpilib/hal/include/HAL/Digital.hpp
new file mode 100644
index 0000000..a860381
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Digital.hpp
@@ -0,0 +1,122 @@
+#pragma once
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+#include "HAL/cpp/Synchronized.hpp"
+
+enum Mode
+{
+	kTwoPulse = 0,
+	kSemiperiod = 1,
+	kPulseLength = 2,
+	kExternalDirection = 3
+};
+
+extern "C"
+{
+	void* initializeDigitalPort(void* port_pointer, int32_t *status);
+	bool checkPWMChannel(void* digital_port_pointer);
+	bool checkRelayChannel(void* digital_port_pointer);
+
+	void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status);
+	bool allocatePWMChannel(void* digital_port_pointer, int32_t *status);
+	void freePWMChannel(void* digital_port_pointer, int32_t *status);
+	unsigned short getPWM(void* digital_port_pointer, int32_t *status);
+	void latchPWMZero(void* digital_port_pointer, int32_t *status);
+	void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask, int32_t *status);
+	void* allocatePWM(int32_t *status);
+	void freePWM(void* pwmGenerator, int32_t *status);
+	void setPWMRate(double rate, int32_t *status);
+	void setPWMDutyCycle(void* pwmGenerator, double dutyCycle, int32_t *status);
+	void setPWMOutputChannel(void* pwmGenerator, uint32_t pin, int32_t *status);
+
+	void setRelayForward(void* digital_port_pointer, bool on, int32_t *status);
+	void setRelayReverse(void* digital_port_pointer, bool on, int32_t *status);
+	bool getRelayForward(void* digital_port_pointer, int32_t *status);
+	bool getRelayReverse(void* digital_port_pointer, int32_t *status);
+
+	bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status);
+	void freeDIO(void* digital_port_pointer, int32_t *status);
+	void setDIO(void* digital_port_pointer, short value, int32_t *status);
+	bool getDIO(void* digital_port_pointer, int32_t *status);
+	bool getDIODirection(void* digital_port_pointer, int32_t *status);
+	void pulse(void* digital_port_pointer, double pulseLength, int32_t *status);
+	bool isPulsing(void* digital_port_pointer, int32_t *status);
+	bool isAnyPulsing(int32_t *status);
+
+	void setFilterSelect(void* digital_port_pointer, int filter_index,
+	                   int32_t* status);
+	int getFilterSelect(void* digital_port_pointer, int32_t* status);
+
+	void setFilterPeriod(int filter_index, uint32_t value, int32_t *status);
+	uint32_t getFilterPeriod(int filter_index, int32_t *status);
+
+	void* initializeCounter(Mode mode, uint32_t *index, int32_t *status);
+	void freeCounter(void* counter_pointer, int32_t *status);
+	void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status);
+	void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
+	void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
+			int32_t *status);
+	void clearCounterUpSource(void* counter_pointer, int32_t *status);
+	void setCounterDownSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
+	void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
+			int32_t *status);
+	void clearCounterDownSource(void* counter_pointer, int32_t *status);
+	void setCounterUpDownMode(void* counter_pointer, int32_t *status);
+	void setCounterExternalDirectionMode(void* counter_pointer, int32_t *status);
+	void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod, int32_t *status);
+	void setCounterPulseLengthMode(void* counter_pointer, double threshold, int32_t *status);
+	int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t *status);
+	void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage, int32_t *status);
+	void resetCounter(void* counter_pointer, int32_t *status);
+	int32_t getCounter(void* counter_pointer, int32_t *status);
+	double getCounterPeriod(void* counter_pointer, int32_t *status);
+	void setCounterMaxPeriod(void* counter_pointer, double maxPeriod, int32_t *status);
+	void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled, int32_t *status);
+	bool getCounterStopped(void* counter_pointer, int32_t *status);
+	bool getCounterDirection(void* counter_pointer, int32_t *status);
+	void setCounterReverseDirection(void* counter_pointer, bool reverseDirection, int32_t *status);
+
+	void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_analog_trigger,
+			uint8_t port_b_module, uint32_t port_b_pin, bool port_b_analog_trigger,
+			bool reverseDirection, int32_t *index, int32_t *status); // TODO: fix routing
+	void freeEncoder(void* encoder_pointer, int32_t *status);
+	void resetEncoder(void* encoder_pointer, int32_t *status);
+	int32_t getEncoder(void* encoder_pointer, int32_t *status); // Raw value
+	double getEncoderPeriod(void* encoder_pointer, int32_t *status);
+	void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod, int32_t *status);
+	bool getEncoderStopped(void* encoder_pointer, int32_t *status);
+	bool getEncoderDirection(void* encoder_pointer, int32_t *status);
+	void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection, int32_t *status);
+	void setEncoderSamplesToAverage(void* encoder_pointer, uint32_t samplesToAverage,
+			int32_t *status);
+	uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t *status);
+
+	uint16_t getLoopTiming(int32_t *status);
+
+	void spiInitialize(uint8_t port, int32_t *status);
+	int32_t spiTransaction(uint8_t port, uint8_t *dataToSend, uint8_t *dataReceived, uint8_t size);
+	int32_t spiWrite(uint8_t port, uint8_t* dataToSend, uint8_t sendSize);
+	int32_t spiRead(uint8_t port, uint8_t *buffer, uint8_t count);
+	void spiClose(uint8_t port);
+	void spiSetSpeed(uint8_t port, uint32_t speed);
+	void spiSetBitsPerWord(uint8_t port, uint8_t bpw);
+	void spiSetOpts(uint8_t port, int msb_first, int sample_on_trailing, int clk_idle_high);
+	void spiSetChipSelectActiveHigh(uint8_t port, int32_t *status);
+	void spiSetChipSelectActiveLow(uint8_t port, int32_t *status);
+	int32_t spiGetHandle(uint8_t port);
+	void spiSetHandle(uint8_t port, int32_t handle);
+
+	void i2CInitialize(uint8_t port, int32_t *status);
+	int32_t i2CTransaction(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize);
+	int32_t i2CWrite(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize);
+	int32_t i2CRead(uint8_t port, uint8_t deviceAddress, uint8_t *buffer, uint8_t count);
+	void i2CClose(uint8_t port);
+
+	//// Float JNA Hack
+	// double
+	void setPWMRateIntHack(int rate, int32_t *status);
+	void setPWMDutyCycleIntHack(void* pwmGenerator, int32_t dutyCycle, int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Errors.hpp b/aos/externals/allwpilib/hal/include/HAL/Errors.hpp
new file mode 100644
index 0000000..35ed961
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Errors.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#define CTR_RxTimeout_MESSAGE "CTRE CAN Recieve Timeout"
+#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
+#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
+#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)"
+#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
+#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
+
+#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
+#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
+#define NiFpga_Status_MemoryFull_MESSAGE "NIFPGA: Memory Allocation failed, memory full"
+#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexepected software error"
+#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter"
+#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found"
+#define NiFpga_Status_ResourceNotInitialized_MESSAGE "NIFPGA: Resource not initialized"
+#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault"
+#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout"
+
+#define ERR_CANSessionMux_InvalidBuffer_MESSAGE "CAN: Invalid Buffer"
+#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found"
+#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token"
+#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed"
+#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized" 
+
+#define SAMPLE_RATE_TOO_HIGH 1001
+#define SAMPLE_RATE_TOO_HIGH_MESSAGE "HAL: Analog module sample rate is too high"
+#define VOLTAGE_OUT_OF_RANGE 1002
+#define VOLTAGE_OUT_OF_RANGE_MESSAGE "HAL: Voltage to convert to raw value is out of range [0; 5]"
+#define LOOP_TIMING_ERROR 1004
+#define LOOP_TIMING_ERROR_MESSAGE "HAL: Digital module loop timing is not the expected value"
+#define SPI_WRITE_NO_MOSI 1012
+#define SPI_WRITE_NO_MOSI_MESSAGE "HAL: Cannot write to SPI port with no MOSI output"
+#define SPI_READ_NO_MISO 1013
+#define SPI_READ_NO_MISO_MESSAGE "HAL: Cannot read from SPI port with no MISO input"
+#define SPI_READ_NO_DATA 1014
+#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI"
+#define INCOMPATIBLE_STATE 1015
+#define INCOMPATIBLE_STATE_MESSAGE "HAL: Incompatible State: The operation cannot be completed"
+#define NO_AVAILABLE_RESOURCES -1004
+#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate"
+#define NULL_PARAMETER -1005
+#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL"
+#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010
+#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "HAL: AnalogTrigger limits error.  Lower limit > Upper Limit"
+#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011
+#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output."
+#define PARAMETER_OUT_OF_RANGE -1028
+#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
+#define RESOURCE_IS_ALLOCATED -1029
+#define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated"
+
+#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
+#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
+#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"
+#define VI_ERROR_RSRC_NFOUND_MESSAGE "HAL - VISA: Resource Not Found"
+#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"  
+#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow" 
+#define VI_ERROR_IO_MESSAGE "HAL - VISA: General IO Error"
+#define VI_ERROR_ASRL_PARITY_MESSAGE "HAL - VISA: Parity Error"
+#define VI_ERROR_ASRL_FRAMING_MESSAGE "HAL - VISA: Framing Error"
+#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error" 
+#define VI_ERROR_RSRC_BUSY_MESSAGE "HAL - VISA: Resource Busy"
+#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter" 
diff --git a/aos/externals/allwpilib/hal/include/HAL/HAL.hpp b/aos/externals/allwpilib/hal/include/HAL/HAL.hpp
new file mode 100644
index 0000000..9c6acb7
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/HAL.hpp
@@ -0,0 +1,257 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2013. All Rights Reserved.  			      */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+#include <cmath>
+
+#include "Accelerometer.hpp"
+#include "Analog.hpp"
+#include "Compressor.hpp"
+#include "Digital.hpp"
+#include "Solenoid.hpp"
+#include "Notifier.hpp"
+#include "Interrupts.hpp"
+#include "Errors.hpp"
+#include "PDP.hpp"
+#include "Power.hpp"
+
+#include "Utilities.hpp"
+#include "Semaphore.hpp"
+#include "Task.hpp"
+
+#define HAL_IO_CONFIG_DATA_SIZE 32
+#define HAL_SYS_STATUS_DATA_SIZE 44
+#define HAL_USER_STATUS_DATA_SIZE (984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
+
+#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Input 17
+#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Output 18
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Header 19
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra1 20
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices1 21
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra2 22
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices2 23
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Joystick 24
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Custom 25
+
+namespace HALUsageReporting
+{
+	enum tResourceType
+	{
+		kResourceType_Controller,
+		kResourceType_Module,
+		kResourceType_Language,
+		kResourceType_CANPlugin,
+		kResourceType_Accelerometer,
+		kResourceType_ADXL345,
+		kResourceType_AnalogChannel,
+		kResourceType_AnalogTrigger,
+		kResourceType_AnalogTriggerOutput,
+		kResourceType_CANJaguar,
+		kResourceType_Compressor,
+		kResourceType_Counter,
+		kResourceType_Dashboard,
+		kResourceType_DigitalInput,
+		kResourceType_DigitalOutput,
+		kResourceType_DriverStationCIO,
+		kResourceType_DriverStationEIO,
+		kResourceType_DriverStationLCD,
+		kResourceType_Encoder,
+		kResourceType_GearTooth,
+		kResourceType_Gyro,
+		kResourceType_I2C,
+		kResourceType_Framework,
+		kResourceType_Jaguar,
+		kResourceType_Joystick,
+		kResourceType_Kinect,
+		kResourceType_KinectStick,
+		kResourceType_PIDController,
+		kResourceType_Preferences,
+		kResourceType_PWM,
+		kResourceType_Relay,
+		kResourceType_RobotDrive,
+		kResourceType_SerialPort,
+		kResourceType_Servo,
+		kResourceType_Solenoid,
+		kResourceType_SPI,
+		kResourceType_Task,
+		kResourceType_Ultrasonic,
+		kResourceType_Victor,
+		kResourceType_Button,
+		kResourceType_Command,
+		kResourceType_AxisCamera,
+		kResourceType_PCVideoServer,
+		kResourceType_SmartDashboard,
+		kResourceType_Talon,
+		kResourceType_HiTechnicColorSensor,
+		kResourceType_HiTechnicAccel,
+		kResourceType_HiTechnicCompass,
+		kResourceType_SRF08,
+		kResourceType_DigitalGlitchFilter,
+	};
+
+	enum tInstances
+	{
+		kLanguage_LabVIEW = 1,
+		kLanguage_CPlusPlus = 2,
+		kLanguage_Java = 3,
+		kLanguage_Python = 4,
+
+		kCANPlugin_BlackJagBridge = 1,
+		kCANPlugin_2CAN = 2,
+
+		kFramework_Iterative = 1,
+		kFramework_Simple = 2,
+
+		kRobotDrive_ArcadeStandard = 1,
+		kRobotDrive_ArcadeButtonSpin = 2,
+		kRobotDrive_ArcadeRatioCurve = 3,
+		kRobotDrive_Tank = 4,
+		kRobotDrive_MecanumPolar = 5,
+		kRobotDrive_MecanumCartesian = 6,
+
+		kDriverStationCIO_Analog = 1,
+		kDriverStationCIO_DigitalIn = 2,
+		kDriverStationCIO_DigitalOut = 3,
+
+		kDriverStationEIO_Acceleration = 1,
+		kDriverStationEIO_AnalogIn = 2,
+		kDriverStationEIO_AnalogOut = 3,
+		kDriverStationEIO_Button = 4,
+		kDriverStationEIO_LED = 5,
+		kDriverStationEIO_DigitalIn = 6,
+		kDriverStationEIO_DigitalOut = 7,
+		kDriverStationEIO_FixedDigitalOut = 8,
+		kDriverStationEIO_PWM = 9,
+		kDriverStationEIO_Encoder = 10,
+		kDriverStationEIO_TouchSlider = 11,
+
+		kADXL345_SPI = 1,
+		kADXL345_I2C = 2,
+
+		kCommand_Scheduler = 1,
+
+		kSmartDashboard_Instance = 1,
+	};
+}
+
+struct HALControlWord {
+	uint32_t enabled : 1;
+	uint32_t autonomous : 1;
+	uint32_t test :1;
+	uint32_t eStop : 1;
+	uint32_t fmsAttached:1;
+	uint32_t dsAttached:1;
+	uint32_t control_reserved : 26;
+};
+
+enum HALAllianceStationID {
+	kHALAllianceStationID_red1,
+	kHALAllianceStationID_red2,
+	kHALAllianceStationID_red3,
+	kHALAllianceStationID_blue1,
+	kHALAllianceStationID_blue2,
+	kHALAllianceStationID_blue3,
+};
+
+/* The maximum number of axes that will be stored in a single HALJoystickAxes
+	struct. This is used for allocating buffers, not bounds checking, since
+	there are usually less axes in practice. */
+static constexpr size_t kMaxJoystickAxes = 12;
+static constexpr size_t kMaxJoystickPOVs = 12;
+
+struct HALJoystickAxes {
+	uint16_t count;
+	int16_t axes[kMaxJoystickAxes];
+};
+
+struct HALJoystickPOVs {
+	uint16_t count;
+	int16_t povs[kMaxJoystickPOVs];
+};
+
+struct HALJoystickButtons {
+	uint32_t buttons;
+	uint8_t count;
+};
+
+struct HALJoystickDescriptor {
+	uint8_t isXbox;
+	uint8_t type;
+	char name[256];
+	uint8_t axisCount;
+	uint8_t axisTypes;
+	uint8_t buttonCount;
+	uint8_t povCount;
+};
+
+inline float intToFloat(int value)
+{
+	return (float)value;
+}
+
+inline int floatToInt(float value)
+{
+	return round(value);
+}
+
+extern "C"
+{
+	extern const uint32_t dio_kNumSystems;
+	extern const uint32_t solenoid_kNumDO7_0Elements;
+	extern const uint32_t interrupt_kNumSystems;
+	extern const uint32_t kSystemClockTicksPerMicrosecond;
+
+	void* getPort(uint8_t pin);
+	void* getPortWithModule(uint8_t module, uint8_t pin);
+	const char* getHALErrorMessage(int32_t code);
+
+	uint16_t getFPGAVersion(int32_t *status);
+	uint32_t getFPGARevision(int32_t *status);
+	uint32_t getFPGATime(int32_t *status);
+
+	bool getFPGAButton(int32_t *status);
+
+	int HALSetErrorData(const char *errors, int errorsLength, int wait_ms);
+
+	int HALGetControlWord(HALControlWord *data);
+	int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
+	int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
+	int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
+	int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
+	int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
+	int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
+	int HALGetMatchTime(float *matchTime);
+
+	void HALSetNewDataSem(MULTIWAIT_ID sem);
+	
+	bool HALGetSystemActive(int32_t *status);
+	bool HALGetBrownedOut(int32_t *status);
+
+	int HALInitialize(int mode = 0);
+	void HALNetworkCommunicationObserveUserProgramStarting();
+	void HALNetworkCommunicationObserveUserProgramDisabled();
+	void HALNetworkCommunicationObserveUserProgramAutonomous();
+	void HALNetworkCommunicationObserveUserProgramTeleop();
+	void HALNetworkCommunicationObserveUserProgramTest();
+
+	uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context = 0,
+			const char *feature = NULL);
+}
+
+// TODO: HACKS for now...
+extern "C"
+{
+
+	void NumericArrayResize();
+	void RTSetCleanupProc();
+	void EDVR_CreateReference();
+	void Occur();
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Interrupts.hpp b/aos/externals/allwpilib/hal/include/HAL/Interrupts.hpp
new file mode 100644
index 0000000..636e809
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Interrupts.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+#include <iostream>
+#include "errno.h"
+
+extern "C"
+{
+	typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void *param);
+
+	void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status);
+	void cleanInterrupts(void* interrupt_pointer, int32_t *status);
+
+	uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status);
+	void enableInterrupts(void* interrupt_pointer, int32_t *status);
+	void disableInterrupts(void* interrupt_pointer, int32_t *status);
+	double readRisingTimestamp(void* interrupt_pointer, int32_t *status);
+	double readFallingTimestamp(void* interrupt_pointer, int32_t *status);
+	void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
+			bool routing_analog_trigger, int32_t *status);
+	void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler,
+			void* param, int32_t *status);
+	void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
+			int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Notifier.hpp b/aos/externals/allwpilib/hal/include/HAL/Notifier.hpp
new file mode 100644
index 0000000..987686c
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Notifier.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+extern "C"
+{
+	void* initializeNotifier(void (*ProcessQueue)(uint32_t, void*), int32_t *status);
+	void cleanNotifier(void* notifier_pointer, int32_t *status);
+
+	void updateNotifierAlarm(void* notifier_pointer, uint32_t triggerTime, int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/PDP.hpp b/aos/externals/allwpilib/hal/include/HAL/PDP.hpp
new file mode 100644
index 0000000..3dde22b
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/PDP.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+extern "C"
+{
+	double getPDPTemperature(int32_t *status);
+	double getPDPVoltage(int32_t *status);
+	double getPDPChannelCurrent(uint8_t channel, int32_t *status);
+	double getPDPTotalCurrent(int32_t *status);
+	double getPDPTotalPower(int32_t *status);
+	double getPDPTotalEnergy(int32_t *status);
+	void resetPDPTotalEnergy(int32_t *status);
+	void clearPDPStickyFaults(int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Power.hpp b/aos/externals/allwpilib/hal/include/HAL/Power.hpp
new file mode 100644
index 0000000..b430c1e
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Power.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <stdint.h>
+
+extern "C"
+{
+	float getVinVoltage(int32_t *status);
+	float getVinCurrent(int32_t *status);
+	float getUserVoltage6V(int32_t *status);
+	float getUserCurrent6V(int32_t *status);
+	bool getUserActive6V(int32_t *status);
+	int getUserCurrentFaults6V(int32_t *status);
+	float getUserVoltage5V(int32_t *status);
+	float getUserCurrent5V(int32_t *status);
+	bool getUserActive5V(int32_t *status);
+	int getUserCurrentFaults5V(int32_t *status);
+	float getUserVoltage3V3(int32_t *status);
+	float getUserCurrent3V3(int32_t *status);
+	bool getUserActive3V3(int32_t *status);
+	int getUserCurrentFaults3V3(int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Semaphore.hpp b/aos/externals/allwpilib/hal/include/HAL/Semaphore.hpp
new file mode 100644
index 0000000..e02011f
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Semaphore.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#include <pthread.h>
+#include <semaphore.h>
+#endif
+
+#ifdef __vxworks
+typedef SEM_ID MUTEX_ID;
+typedef SEM_ID SEMAPHORE_ID;
+typedef SEM_ID MULTIWAIT_ID;
+#else
+class MutexInterface;
+typedef MutexInterface* MUTEX_ID;
+typedef sem_t* SEMAPHORE_ID;
+typedef pthread_cond_t* MULTIWAIT_ID;
+#endif
+
+extern "C"
+{
+	extern const uint32_t SEMAPHORE_Q_FIFO;
+	extern const uint32_t SEMAPHORE_Q_PRIORITY;
+	extern const uint32_t SEMAPHORE_DELETE_SAFE;
+	extern const uint32_t SEMAPHORE_INVERSION_SAFE;
+
+	extern const int32_t SEMAPHORE_NO_WAIT;
+	extern const int32_t SEMAPHORE_WAIT_FOREVER;
+
+	extern const uint32_t SEMAPHORE_EMPTY;
+	extern const uint32_t SEMAPHORE_FULL;
+
+	MUTEX_ID initializeMutexRecursive();
+	MUTEX_ID initializeMutexNormal();
+	void deleteMutex(MUTEX_ID sem);
+	int8_t lockMutex(MUTEX_ID sem);
+	int8_t tryLockMutex(MUTEX_ID sem);
+	int8_t unlockMutex(MUTEX_ID sem);
+
+	SEMAPHORE_ID initializeSemaphore(uint32_t initial_value);
+	void deleteSemaphore(SEMAPHORE_ID sem);
+	int8_t takeSemaphore(SEMAPHORE_ID sem);
+	int8_t tryTakeSemaphore(SEMAPHORE_ID sem);
+	int8_t giveSemaphore(SEMAPHORE_ID sem);
+
+	MULTIWAIT_ID initializeMultiWait();
+	void deleteMultiWait(MULTIWAIT_ID sem);
+	int8_t takeMultiWait(MULTIWAIT_ID sem, MUTEX_ID m, int32_t timeout);
+	int8_t giveMultiWait(MULTIWAIT_ID sem);
+}
+
diff --git a/aos/externals/allwpilib/hal/include/HAL/Solenoid.hpp b/aos/externals/allwpilib/hal/include/HAL/Solenoid.hpp
new file mode 100644
index 0000000..1654dc2
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Solenoid.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+extern "C"
+{
+	void* initializeSolenoidPort(void* port_pointer, int32_t *status);
+	bool checkSolenoidModule(uint8_t module);
+
+	bool getSolenoid(void* solenoid_port_pointer, int32_t *status);
+	void setSolenoid(void* solenoid_port_pointer, bool value, int32_t *status);
+	void setSolenoids(void* solenoid_port_pointer, uint8_t value, uint8_t mask, int32_t *status);
+
+	int getPCMSolenoidBlackList(void* solenoid_port_pointer, int32_t *status);
+	bool getPCMSolenoidVoltageStickyFault(void* solenoid_port_pointer, int32_t *status);
+	bool getPCMSolenoidVoltageFault(void* solenoid_port_pointer, int32_t *status);
+	void clearAllPCMStickyFaults_sol(void *solenoid_port_pointer, int32_t *status);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/Task.hpp b/aos/externals/allwpilib/hal/include/HAL/Task.hpp
new file mode 100644
index 0000000..ec3ed9b
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Task.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#include <pthread.h>
+#endif
+
+#ifndef _FUNCPTR_DEFINED
+#define _FUNCPTR_DEFINED
+#ifdef __cplusplus
+typedef int (*FUNCPTR)(...);
+/* ptr to function returning int */
+#else
+typedef int (*FUNCPTR) (); /* ptr to function returning int */
+#endif /* __cplusplus */
+#endif /* _FUNCPTR_DEFINED */
+
+#ifndef _STATUS_DEFINED
+#define _STATUS_DEFINED
+typedef int STATUS;
+#endif /* _STATUS_DEFINED */
+
+#ifdef __vxworks
+#define NULL_TASK -1
+typedef int32_t TASK;
+#else
+#define NULL_TASK NULL
+typedef pthread_t* TASK;
+#endif
+
+extern "C"
+{
+	extern const uint32_t VXWORKS_FP_TASK;
+	extern const int32_t HAL_objLib_OBJ_ID_ERROR;
+	extern const int32_t HAL_objLib_OBJ_DELETED;
+	extern const int32_t HAL_taskLib_ILLEGAL_OPTIONS;
+	extern const int32_t HAL_memLib_NOT_ENOUGH_MEMORY;
+	extern const int32_t HAL_taskLib_ILLEGAL_PRIORITY;
+
+	TASK spawnTask(char * name, int priority, int options, int stackSize, FUNCPTR entryPt,
+			uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4,
+			uint32_t arg5, uint32_t arg6, uint32_t arg7, uint32_t arg8, uint32_t arg9);
+	STATUS restartTask(TASK task);
+	STATUS deleteTask(TASK task);
+	STATUS isTaskReady(TASK task);
+	STATUS isTaskSuspended(TASK task);
+	STATUS suspendTask(TASK task);
+	STATUS resumeTask(TASK task);
+	STATUS verifyTaskID(TASK task);
+	STATUS setTaskPriority(TASK task, int priority);
+	STATUS getTaskPriority(TASK task, int* priority);
+}
+
diff --git a/aos/externals/allwpilib/hal/include/HAL/Utilities.hpp b/aos/externals/allwpilib/hal/include/HAL/Utilities.hpp
new file mode 100644
index 0000000..b24cd29
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/Utilities.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+extern "C"
+{
+	extern const int32_t HAL_NO_WAIT;
+	extern const int32_t HAL_WAIT_FOREVER;
+
+	void delayTicks(int32_t ticks);
+	void delayMillis(double ms);
+	void delaySeconds(double s);
+}
diff --git a/aos/externals/allwpilib/hal/include/HAL/cpp/Resource.hpp b/aos/externals/allwpilib/hal/include/HAL/cpp/Resource.hpp
new file mode 100644
index 0000000..931407f
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/cpp/Resource.hpp
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+#pragma once
+
+#include "../Errors.hpp"
+#include "Synchronized.hpp"
+#ifdef __vxworks
+#include <vxWorks.h>
+#else
+#include <stdint.h>
+#endif
+
+/**
+ * The Resource class is a convenient way to track allocated resources.
+ * It tracks them as indicies in the range [0 .. elements - 1].
+ * E.g. the library uses this to track hardware channel allocation.
+ *
+ * The Resource class does not allocate the hardware channels or other
+ * resources; it just tracks which indices were marked in use by
+ * Allocate and not yet freed by Free.
+ */
+class Resource
+{
+public:
+	virtual ~Resource();
+	static void CreateResourceObject(Resource **r, uint32_t elements);
+	uint32_t Allocate(const char *resourceDesc);
+	uint32_t Allocate(uint32_t index, const char *resourceDesc);
+	void Free(uint32_t index);
+
+private:
+	explicit Resource(uint32_t size);
+
+	bool *m_isAllocated;
+	ReentrantMutex m_allocateLock;
+	uint32_t m_size;
+
+	static ReentrantMutex m_createLock;
+
+	DISALLOW_COPY_AND_ASSIGN(Resource);
+};
+
diff --git a/aos/externals/allwpilib/hal/include/HAL/cpp/Synchronized.hpp b/aos/externals/allwpilib/hal/include/HAL/cpp/Synchronized.hpp
new file mode 100644
index 0000000..af8b149
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/HAL/cpp/Synchronized.hpp
@@ -0,0 +1,144 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+#pragma once
+
+#include <mutex>
+#include "HAL/Semaphore.hpp"
+
+// A macro to disallow the copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&) = delete;      \
+  void operator=(const TypeName&) = delete
+
+class Synchronized;
+
+/**
+ * Wrap a pthead mutex for easier use in C++. For a static
+ * instance, the constructor runs at program load time before main() can spawn
+ * any tasks. Use that to fix race conditions in setup code.
+ *
+ * This uses a pthread mutex which has PTHREAD_MUTEX_RECURSIVE set, making it
+ * "reentrant" in the sense that the owning task can lock it more than once. The
+ * task will need to unlock the mutex the same number of times to make it
+ * available for other threads to acquire.
+ *
+ * This class is safe to use in static variables because it does not depend on
+ * any other C++ static constructors or destructors.
+ */
+class ReentrantMutex {
+ public:
+  typedef pthread_mutex_t *native_handle_type;
+
+  constexpr ReentrantMutex() noexcept = default;
+  ReentrantMutex(const ReentrantMutex &) = delete;
+  ReentrantMutex &operator=(const ReentrantMutex &) = delete;
+
+  /**
+   * Lock the mutex, blocking until it's available.
+   */
+  void lock() { pthread_mutex_lock(&mutex_); }
+
+  /**
+   * Unlock the mutex.
+   */
+  void unlock() { pthread_mutex_unlock(&mutex_); }
+
+  /**
+   * Tries to lock the mutex.
+   */
+  bool try_lock() noexcept { return !pthread_mutex_trylock(&mutex_); }
+
+  pthread_mutex_t *native_handle() { return &mutex_; }
+
+ private:
+  // Do the equivalent of setting PTHREAD_PRIO_INHERIT and
+  // PTHREAD_MUTEX_RECURSIVE_NP.
+#if __WORDSIZE == 64
+  #error "Should work, but need to run test case to verify"
+  pthread_mutex_t mutex_ = {
+      {0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0, 0}}};
+#else
+  pthread_mutex_t mutex_ = {
+      {0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
+#endif
+};
+
+/**
+ * Wrap a pthead mutex for easier use in C++. For a static
+ * instance, the constructor runs at program load time before main() can spawn
+ * any tasks. Use that to fix race conditions in setup code.
+ *
+ * This class is safe to use in static variables because it does not depend on
+ * any other C++ static constructors or destructors.
+ */
+class Mutex {
+ public:
+  typedef pthread_mutex_t *native_handle_type;
+
+  constexpr Mutex() noexcept = default;
+  Mutex(const Mutex &) = delete;
+  Mutex &operator=(const Mutex &) = delete;
+
+  /**
+   * Lock the mutex, blocking until it's available.
+   */
+  void lock() { pthread_mutex_lock(&mutex_); }
+
+  /**
+   * Unlock the mutex.
+   */
+  void unlock() { pthread_mutex_unlock(&mutex_); }
+
+  /**
+   * Tries to lock the mutex.
+   */
+  bool try_lock() noexcept { return !pthread_mutex_trylock(&mutex_); }
+
+  native_handle_type native_handle() { return &mutex_; }
+
+ private:
+  // Do the equivalent of setting PTHREAD_PRIO_INHERIT.
+#if __WORDSIZE == 64
+  #error "Should work, but need to run test case to verify"
+  pthread_mutex_t mutex_ = { { 0, 0, 0, 0, 0x20, 0, { 0, 0 } } };
+#else
+  pthread_mutex_t mutex_ = { { 0, 0, 0, 0x20, 0, { 0 } } };
+#endif
+};
+
+
+/**
+ * Provide easy support for critical regions.
+ *
+ * A critical region is an area of code that is always executed under mutual exclusion. Only
+ * one task can be executing this code at any time. The idea is that code that manipulates data
+ * that is shared between two or more tasks has to be prevented from executing at the same time
+ * otherwise a race condition is possible when both tasks try to update the data. Typically
+ * semaphores are used to ensure only single task access to the data.
+ *
+ * Synchronized objects are a simple wrapper around semaphores to help ensure
+ * that semaphores are always unlocked (semGive) after locking (semTake).
+ *
+ * You allocate a Synchronized as a local variable, *not* on the heap. That
+ * makes it a "stack object" whose destructor runs automatically when it goes
+ * out of scope. E.g.
+ *
+ *   { Synchronized _sync(aReentrantSemaphore); ... critical region ... }
+ */
+class Synchronized
+{
+public:
+#ifndef __vxworks
+	explicit Synchronized(SEMAPHORE_ID);
+#endif
+	virtual ~Synchronized();
+private:
+	SEMAPHORE_ID m_semaphore;
+
+	DISALLOW_COPY_AND_ASSIGN(Synchronized);
+};
+
diff --git a/aos/externals/allwpilib/hal/include/Log.hpp b/aos/externals/allwpilib/hal/include/Log.hpp
new file mode 100644
index 0000000..eb221e7
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/Log.hpp
@@ -0,0 +1,103 @@
+#pragma once
+
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <stdio.h>
+#include <sys/time.h>
+
+inline std::string NowTime();
+
+enum TLogLevel {logNONE, logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
+
+class Log
+{
+public:
+    Log();
+    virtual ~Log();
+    std::ostringstream& Get(TLogLevel level = logINFO);
+public:
+    static TLogLevel& ReportingLevel();
+    static std::string ToString(TLogLevel level);
+    static TLogLevel FromString(const std::string& level);
+protected:
+    std::ostringstream os;
+private:
+    Log(const Log&);
+    Log& operator =(const Log&);
+};
+
+inline Log::Log()
+{
+}
+
+inline std::ostringstream& Log::Get(TLogLevel level)
+{
+    os << "- " << NowTime();
+    os << " " << ToString(level) << ": ";
+    os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
+    return os;
+}
+
+inline Log::~Log()
+{
+    os << std::endl;
+    fprintf(stderr, "%s", os.str().c_str());
+    fflush(stderr);
+}
+
+inline TLogLevel& Log::ReportingLevel()
+{
+    static TLogLevel reportingLevel = logDEBUG4;
+    return reportingLevel;
+}
+
+inline std::string Log::ToString(TLogLevel level)
+{
+	static const char* const buffer[] = {"NONE", "ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
+    return buffer[level];
+}
+
+inline TLogLevel Log::FromString(const std::string& level)
+{
+    if (level == "DEBUG4")
+        return logDEBUG4;
+    if (level == "DEBUG3")
+        return logDEBUG3;
+    if (level == "DEBUG2")
+        return logDEBUG2;
+    if (level == "DEBUG1")
+        return logDEBUG1;
+    if (level == "DEBUG")
+        return logDEBUG;
+    if (level == "INFO")
+        return logINFO;
+    if (level == "WARNING")
+        return logWARNING;
+    if (level == "ERROR")
+        return logERROR;
+    if (level == "NONE")
+    	return logNONE;
+    Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
+    return logINFO;
+}
+
+typedef Log FILELog;
+
+#define FILE_LOG(level) \
+    if (level > FILELog::ReportingLevel()) ; \
+    else Log().Get(level)
+
+inline std::string NowTime()
+{
+    char buffer[11];
+    time_t t;
+    time(&t);
+    tm * r = gmtime(&t);
+    strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    char result[100] = {0};
+    sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
+    return result;
+}