Adds capabilities to support certain HAL functionality from LabVIEW (#382)

They can only include HAL/LV/HAL.h, HAL/cpp/*.h, and HAL/handles/*.h.
Nothing else will work properly.
This commit is contained in:
Thad House
2016-12-02 00:32:01 -08:00
committed by Peter Johnson
parent 351ff5eb48
commit bff67887fd
5 changed files with 66 additions and 24 deletions

View File

@@ -104,6 +104,8 @@ int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble);
double HAL_GetMatchTime(int32_t* status);
#ifndef HAL_USE_LABVIEW
void HAL_WaitForDSData(void);
void HAL_InitializeDriverStation(void);
@@ -112,6 +114,9 @@ void HAL_ObserveUserProgramDisabled(void);
void HAL_ObserveUserProgramAutonomous(void);
void HAL_ObserveUserProgramTeleop(void);
void HAL_ObserveUserProgramTest(void);
#endif // HAL_USE_LABVIEW
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -9,6 +9,8 @@
#include <stdint.h>
#ifndef HAL_USE_LABVIEW
#include "FRC_NetworkCommunication/UsageReporting.h"
#include "HAL/Accelerometer.h"
#include "HAL/AnalogAccumulator.h"
@@ -33,6 +35,9 @@
#include "HAL/SPI.h"
#include "HAL/SerialPort.h"
#include "HAL/Solenoid.h"
#endif // HAL_USE_LABVIEW
#include "HAL/Types.h"
namespace HALUsageReporting = nUsageReporting;
@@ -42,13 +47,11 @@ enum HAL_RuntimeType : int32_t { HAL_Athena, HAL_Mock };
#ifdef __cplusplus
extern "C" {
#endif
HAL_PortHandle HAL_GetPort(int32_t channel);
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
const char* HAL_GetErrorMessage(int32_t code);
int32_t HAL_GetFPGAVersion(int32_t* status);
int64_t HAL_GetFPGARevision(int32_t* status);
uint64_t HAL_GetFPGATime(int32_t* status);
HAL_RuntimeType HAL_GetRuntimeType();
HAL_Bool HAL_GetFPGAButton(int32_t* status);
@@ -56,6 +59,15 @@ HAL_Bool HAL_GetFPGAButton(int32_t* status);
HAL_Bool HAL_GetSystemActive(int32_t* status);
HAL_Bool HAL_GetBrownedOut(int32_t* status);
void HAL_BaseInitialize(int32_t* status);
#ifndef HAL_USE_LABVIEW
HAL_PortHandle HAL_GetPort(int32_t channel);
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
uint64_t HAL_GetFPGATime(int32_t* status);
int32_t HAL_Initialize(int32_t mode);
// ifdef's definition is to allow for default parameters in C++.
@@ -66,6 +78,8 @@ int64_t HAL_Report(int32_t resource, int32_t instanceNumber,
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
const char* feature);
#endif
#endif // HAL_USE_LABVIEW
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,14 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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 the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#define HAL_USE_LABVIEW
#include "HAL/DriverStation.h"
#include "HAL/HAL.h"
#include "HAL/Types.h"

View File

@@ -5,13 +5,14 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits>
#include "FRC_NetworkCommunication/FRCComm.h"
#include "HAL/HAL.h"
#include "HAL/DriverStation.h"
#include "HAL/cpp/priority_condition_variable.h"
#include "HAL/cpp/priority_mutex.h"
@@ -41,16 +42,24 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
static constexpr int KEEP_MSGS = 5;
std::lock_guard<priority_mutex> lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static uint64_t prevMsgTime[KEEP_MSGS] = {0, 0, 0};
static std::chrono::time_point<std::chrono::steady_clock>
prevMsgTime[KEEP_MSGS];
static bool initialized = false;
if (!initialized) {
for (int i = 0; i < KEEP_MSGS; i++) {
prevMsgTime[i] =
std::chrono::steady_clock::now() - std::chrono::seconds(2);
}
initialized = true;
}
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
auto curTime = std::chrono::steady_clock::now();
int i;
for (i = 0; i < KEEP_MSGS; ++i) {
if (prevMsg[i] == details) break;
}
int retval = 0;
if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= 1000000) {
if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= std::chrono::seconds(1)) {
retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode,
details, location, callStack);
if (printMsg) {
@@ -66,7 +75,7 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
if (i == KEEP_MSGS) {
// replace the oldest one
i = 0;
uint64_t first = prevMsgTime[0];
auto first = prevMsgTime[0];
for (int j = 1; j < KEEP_MSGS; ++j) {
if (prevMsgTime[j] < first) {
first = prevMsgTime[j];

View File

@@ -255,20 +255,21 @@ HAL_Bool HAL_GetBrownedOut(int32_t* status) {
return !(watchdog->readStatus_PowerAlive(status));
}
static void HALCleanupAtExit() {
global = nullptr;
watchdog = nullptr;
// Unregister our new data condition variable.
setNewDataSem(nullptr);
}
static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) {
// reschedule timer for next rollover
int32_t status = 0;
HAL_UpdateNotifierAlarm(handle, currentTime + 0x80000000ULL, &status);
}
void HAL_BaseInitialize(int32_t* status) {
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
global.reset(tGlobal::create(status));
watchdog.reset(tSysWatchdog::create(status));
}
/**
* Call this to start up HAL. This is required for robot programs.
*/
@@ -279,15 +280,14 @@ int32_t HAL_Initialize(int32_t mode) {
prctl(PR_SET_PDEATHSIG, SIGTERM);
FRC_NetworkCommunication_Reserve(nullptr);
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
std::atexit([]() {
// Unregister our new data condition variable.
setNewDataSem(nullptr);
});
int32_t status = 0;
global.reset(tGlobal::create(&status));
watchdog.reset(tSysWatchdog::create(&status));
std::atexit(HALCleanupAtExit);
HAL_BaseInitialize(&status);
if (!rolloverNotifier)
rolloverNotifier = HAL_InitializeNotifier(timerRollover, nullptr, &status);