mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Update to 2018_v4 image and new build system. (#598)
* Revert "Force OpenCV to 3.1.0 (#602)"
This reverts commit 50ed55e8e2.
* Removes Simulation
* Removes old build system
* Removes old gtest
* Adds new gmock and gtest
* Updates to new ni-libraries
* removes MyRobot (to be replaced)
* moves files to new location
* Adds new sim backend and new test executables
* updates .styleguide and .gitignore
* Changes cpp WPILibVersion to a function
MSVC throws an AV with the old version.
* Disables USBCamera on all systems except for linux
* 2018 NI Libraries
* New build system
This commit is contained in:
committed by
Peter Johnson
parent
50ed55e8e2
commit
e1195e8b9d
126
hal/src/main/native/include/HAL/cpp/Log.h
Normal file
126
hal/src/main/native/include/HAL/cpp/Log.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2016-2017. 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
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include "llvm/SmallString.h"
|
||||
#include "llvm/raw_ostream.h"
|
||||
|
||||
inline std::string NowTime();
|
||||
|
||||
enum TLogLevel {
|
||||
logNONE,
|
||||
logERROR,
|
||||
logWARNING,
|
||||
logINFO,
|
||||
logDEBUG,
|
||||
logDEBUG1,
|
||||
logDEBUG2,
|
||||
logDEBUG3,
|
||||
logDEBUG4
|
||||
};
|
||||
|
||||
class Log {
|
||||
public:
|
||||
Log();
|
||||
virtual ~Log();
|
||||
llvm::raw_ostream& Get(TLogLevel level = logINFO);
|
||||
|
||||
public:
|
||||
static TLogLevel& ReportingLevel();
|
||||
static std::string ToString(TLogLevel level);
|
||||
static TLogLevel FromString(const std::string& level);
|
||||
|
||||
protected:
|
||||
llvm::SmallString<128> buf;
|
||||
llvm::raw_svector_ostream oss{buf};
|
||||
|
||||
private:
|
||||
Log(const Log&);
|
||||
Log& operator=(const Log&);
|
||||
};
|
||||
|
||||
inline Log::Log() {}
|
||||
|
||||
inline llvm::raw_ostream& Log::Get(TLogLevel level) {
|
||||
oss << "- " << NowTime();
|
||||
oss << " " << ToString(level) << ": ";
|
||||
oss << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
|
||||
return oss;
|
||||
}
|
||||
|
||||
inline Log::~Log() {
|
||||
oss << "\n";
|
||||
llvm::errs() << oss.str();
|
||||
}
|
||||
|
||||
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() {
|
||||
llvm::SmallString<128> buf;
|
||||
llvm::raw_svector_ostream oss(buf);
|
||||
|
||||
using std::chrono::duration_cast;
|
||||
|
||||
auto now = std::chrono::system_clock::now().time_since_epoch();
|
||||
|
||||
// Hours
|
||||
auto count = duration_cast<std::chrono::hours>(now).count() % 24;
|
||||
if (count < 10) oss << "0";
|
||||
oss << count << ":";
|
||||
|
||||
// Minutes
|
||||
count = duration_cast<std::chrono::minutes>(now).count() % 60;
|
||||
if (count < 10) oss << "0";
|
||||
oss << count << ":";
|
||||
|
||||
// Seconds
|
||||
count = duration_cast<std::chrono::seconds>(now).count() % 60;
|
||||
if (count < 10) oss << "0";
|
||||
oss << count << ".";
|
||||
|
||||
// Milliseconds
|
||||
oss << duration_cast<std::chrono::milliseconds>(now).count() % 1000;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
15
hal/src/main/native/include/HAL/cpp/NotifierInternal.h
Normal file
15
hal/src/main/native/include/HAL/cpp/NotifierInternal.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. 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
|
||||
|
||||
#include "HAL/Types.h"
|
||||
|
||||
extern "C" {
|
||||
HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
|
||||
HAL_NotifierProcessFunction process, void* param, int32_t* status);
|
||||
}
|
||||
51
hal/src/main/native/include/HAL/cpp/SerialHelper.h
Normal file
51
hal/src/main/native/include/HAL/cpp/SerialHelper.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2016-2017. 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
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "HAL/SerialPort.h"
|
||||
#include "HAL/cpp/priority_mutex.h"
|
||||
#include "llvm/SmallString.h"
|
||||
#include "llvm/SmallVector.h"
|
||||
|
||||
namespace hal {
|
||||
class SerialHelper {
|
||||
public:
|
||||
SerialHelper();
|
||||
|
||||
std::string GetVISASerialPortName(HAL_SerialPort port, int32_t* status);
|
||||
std::string GetOSSerialPortName(HAL_SerialPort port, int32_t* status);
|
||||
|
||||
std::vector<std::string> GetVISASerialPortList(int32_t* status);
|
||||
std::vector<std::string> GetOSSerialPortList(int32_t* status);
|
||||
|
||||
private:
|
||||
void SortHubPathVector();
|
||||
void CoiteratedSort(llvm::SmallVectorImpl<llvm::SmallString<16>>& vec);
|
||||
void QueryHubPaths(int32_t* status);
|
||||
|
||||
int32_t GetIndexForPort(HAL_SerialPort port, int32_t* status);
|
||||
|
||||
// Vectors to hold data before sorting.
|
||||
// Note we will most likely have at max 2 instances, and the longest string
|
||||
// is around 12, so these should never touch the heap;
|
||||
llvm::SmallVector<llvm::SmallString<16>, 4> m_visaResource;
|
||||
llvm::SmallVector<llvm::SmallString<16>, 4> m_osResource;
|
||||
llvm::SmallVector<llvm::SmallString<16>, 4> m_unsortedHubPath;
|
||||
llvm::SmallVector<llvm::SmallString<16>, 4> m_sortedHubPath;
|
||||
|
||||
int32_t m_resourceHandle;
|
||||
|
||||
static hal::priority_mutex m_nameMutex;
|
||||
static std::string m_usbNames[2];
|
||||
};
|
||||
} // namespace hal
|
||||
32
hal/src/main/native/include/HAL/cpp/fpga_clock.h
Normal file
32
hal/src/main/native/include/HAL/cpp/fpga_clock.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. 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
|
||||
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
|
||||
namespace hal {
|
||||
|
||||
class fpga_clock {
|
||||
public:
|
||||
typedef std::chrono::microseconds::rep rep;
|
||||
typedef std::chrono::microseconds::period period;
|
||||
typedef std::chrono::microseconds duration;
|
||||
typedef std::chrono::time_point<fpga_clock> time_point;
|
||||
|
||||
static fpga_clock::time_point now() noexcept;
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
static constexpr fpga_clock::time_point epoch() { return time_point(zero()); }
|
||||
|
||||
static constexpr fpga_clock::duration zero() { return duration(0); }
|
||||
|
||||
static constexpr time_point min_time{
|
||||
time_point(duration(std::numeric_limits<duration::rep>::min()))};
|
||||
};
|
||||
} // namespace hal
|
||||
47
hal/src/main/native/include/HAL/cpp/make_unique.h
Normal file
47
hal/src/main/native/include/HAL/cpp/make_unique.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2016-2017. 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 make_unique for C++11-only compilers
|
||||
#if __cplusplus == 201103L
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace std {
|
||||
template <class T>
|
||||
struct _Unique_if {
|
||||
typedef unique_ptr<T> _Single_object;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct _Unique_if<T[]> {
|
||||
typedef unique_ptr<T[]> _Unknown_bound;
|
||||
};
|
||||
|
||||
template <class T, size_t N>
|
||||
struct _Unique_if<T[N]> {
|
||||
typedef void _Known_bound;
|
||||
};
|
||||
|
||||
template <class T, class... Args>
|
||||
typename _Unique_if<T>::_Single_object make_unique(Args&&... args) {
|
||||
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {
|
||||
typedef typename remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]());
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound make_unique(Args&&...) = delete;
|
||||
} // namespace std
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2016-2017. 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
|
||||
|
||||
/* std::condition_variable provides the native_handle() method to return its
|
||||
* underlying pthread_cond_t*. WPILib uses this to interface with the FRC
|
||||
* network communication library. Since WPILib uses a custom mutex class and
|
||||
* not std::mutex, std::condition_variable_any must be used instead.
|
||||
* std::condition_variable_any doesn't expose its internal handle, so this
|
||||
* class provides the same interface and implementation in addition to a
|
||||
* native_handle() method.
|
||||
*/
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "priority_mutex.h"
|
||||
|
||||
namespace hal {
|
||||
|
||||
class priority_condition_variable {
|
||||
typedef std::chrono::system_clock clock;
|
||||
|
||||
public:
|
||||
typedef std::condition_variable::native_handle_type native_handle_type;
|
||||
|
||||
priority_condition_variable() : m_mutex(std::make_shared<std::mutex>()) {}
|
||||
~priority_condition_variable() = default;
|
||||
|
||||
priority_condition_variable(const priority_condition_variable&) = delete;
|
||||
priority_condition_variable& operator=(const priority_condition_variable&) =
|
||||
delete;
|
||||
|
||||
void notify_one() noexcept {
|
||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
||||
m_cond.notify_one();
|
||||
}
|
||||
|
||||
void notify_all() noexcept {
|
||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
||||
m_cond.notify_all();
|
||||
}
|
||||
|
||||
template <typename Lock>
|
||||
void wait(Lock& _lock) {
|
||||
std::shared_ptr<std::mutex> _mutex = m_mutex;
|
||||
std::unique_lock<std::mutex> my_lock(*_mutex);
|
||||
Unlock<Lock> unlock(_lock);
|
||||
|
||||
// *mutex must be unlocked before re-locking _lock so move
|
||||
// ownership of *_mutex lock to an object with shorter lifetime.
|
||||
std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
|
||||
m_cond.wait(my_lock2);
|
||||
}
|
||||
|
||||
template <typename Lock, typename Predicate>
|
||||
void wait(Lock& lock, Predicate p) {
|
||||
while (!p()) {
|
||||
wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Lock, typename Clock, typename Duration>
|
||||
std::cv_status wait_until(
|
||||
Lock& _lock, const std::chrono::time_point<Clock, Duration>& atime) {
|
||||
std::shared_ptr<std::mutex> _mutex = m_mutex;
|
||||
std::unique_lock<std::mutex> my_lock(*_mutex);
|
||||
Unlock<Lock> unlock(_lock);
|
||||
|
||||
// *_mutex must be unlocked before re-locking _lock so move
|
||||
// ownership of *_mutex lock to an object with shorter lifetime.
|
||||
std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
|
||||
return m_cond.wait_until(my_lock2, atime);
|
||||
}
|
||||
|
||||
template <typename Lock, typename Clock, typename Duration,
|
||||
typename Predicate>
|
||||
bool wait_until(Lock& lock,
|
||||
const std::chrono::time_point<Clock, Duration>& atime,
|
||||
Predicate p) {
|
||||
while (!p()) {
|
||||
if (wait_until(lock, atime) == std::cv_status::timeout) {
|
||||
return p();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Lock, typename Rep, typename Period>
|
||||
std::cv_status wait_for(Lock& lock,
|
||||
const std::chrono::duration<Rep, Period>& rtime) {
|
||||
return wait_until(lock, clock::now() + rtime);
|
||||
}
|
||||
|
||||
template <typename Lock, typename Rep, typename Period, typename Predicate>
|
||||
bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime,
|
||||
Predicate p) {
|
||||
return wait_until(lock, clock::now() + rtime, std::move(p));
|
||||
}
|
||||
|
||||
native_handle_type native_handle() { return m_cond.native_handle(); }
|
||||
|
||||
private:
|
||||
std::condition_variable m_cond;
|
||||
std::shared_ptr<std::mutex> m_mutex;
|
||||
|
||||
// scoped unlock - unlocks in ctor, re-locks in dtor
|
||||
template <typename Lock>
|
||||
struct Unlock {
|
||||
explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); }
|
||||
|
||||
~Unlock() /*noexcept(false)*/ {
|
||||
if (std::uncaught_exception()) {
|
||||
try {
|
||||
m_lock.lock();
|
||||
} catch (...) {
|
||||
}
|
||||
} else {
|
||||
m_lock.lock();
|
||||
}
|
||||
}
|
||||
|
||||
Unlock(const Unlock&) = delete;
|
||||
Unlock& operator=(const Unlock&) = delete;
|
||||
|
||||
Lock& m_lock;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
|
||||
// For backwards compatibility
|
||||
#ifndef NAMESPACED_PRIORITY
|
||||
using hal::priority_condition_variable; // NOLINT
|
||||
#endif
|
||||
92
hal/src/main/native/include/HAL/cpp/priority_mutex.h
Normal file
92
hal/src/main/native/include/HAL/cpp/priority_mutex.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2016-2017. 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
|
||||
|
||||
// Allows usage with std::lock_guard without including <mutex> separately
|
||||
#include <mutex>
|
||||
|
||||
#if defined(_WIN32)
|
||||
namespace hal {
|
||||
// We do not want to use pthreads if in the simulator; however, in the
|
||||
// simulator, we do not care about priority inversion.
|
||||
typedef std::mutex priority_mutex;
|
||||
typedef std::recursive_mutex priority_recursive_mutex;
|
||||
} // namespace hal
|
||||
#else // Covers rest of file.
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace hal {
|
||||
|
||||
class priority_recursive_mutex {
|
||||
public:
|
||||
typedef pthread_mutex_t* native_handle_type;
|
||||
|
||||
constexpr priority_recursive_mutex() noexcept = default;
|
||||
priority_recursive_mutex(const priority_recursive_mutex&) = delete;
|
||||
priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
|
||||
|
||||
// Lock the mutex, blocking until it's available.
|
||||
void lock();
|
||||
|
||||
// Unlock the mutex.
|
||||
void unlock();
|
||||
|
||||
// Tries to lock the mutex.
|
||||
bool try_lock() noexcept;
|
||||
|
||||
pthread_mutex_t* native_handle();
|
||||
|
||||
private:
|
||||
// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
|
||||
// PTHREAD_MUTEX_RECURSIVE_NP.
|
||||
#if __WORDSIZE == 64
|
||||
pthread_mutex_t m_mutex = {
|
||||
{0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
|
||||
#else
|
||||
pthread_mutex_t m_mutex = {
|
||||
{0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
|
||||
#endif
|
||||
};
|
||||
|
||||
class priority_mutex {
|
||||
public:
|
||||
typedef pthread_mutex_t* native_handle_type;
|
||||
|
||||
constexpr priority_mutex() noexcept = default;
|
||||
priority_mutex(const priority_mutex&) = delete;
|
||||
priority_mutex& operator=(const priority_mutex&) = delete;
|
||||
|
||||
// Lock the mutex, blocking until it's available.
|
||||
void lock();
|
||||
|
||||
// Unlock the mutex.
|
||||
void unlock();
|
||||
|
||||
// Tries to lock the mutex.
|
||||
bool try_lock() noexcept;
|
||||
|
||||
pthread_mutex_t* native_handle();
|
||||
|
||||
private:
|
||||
// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
|
||||
#if __WORDSIZE == 64
|
||||
pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
|
||||
#else
|
||||
pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {0}}};
|
||||
#endif
|
||||
};
|
||||
} // namespace hal
|
||||
|
||||
#endif // FRC_SIMULATOR
|
||||
|
||||
// For backwards compatibility
|
||||
#ifndef NAMESPACED_PRIORITY
|
||||
using hal::priority_mutex; // NOLINT
|
||||
using hal::priority_recursive_mutex; // NOLINT
|
||||
#endif
|
||||
Reference in New Issue
Block a user