mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +00:00
JNI for java
Normal vs recursive mutex HAL delineation
This commit is contained in:
@@ -44,7 +44,7 @@ bool analogSystemInitialized = false;
|
||||
*/
|
||||
void initializeAnalog(int32_t *status) {
|
||||
if (analogSystemInitialized) return;
|
||||
analogRegisterWindowSemaphore = initializeMutex(SEMAPHORE_Q_PRIORITY | SEMAPHORE_DELETE_SAFE | SEMAPHORE_INVERSION_SAFE);
|
||||
analogRegisterWindowSemaphore = initializeMutexRecursive();
|
||||
analogSystem = tAI::create(status);
|
||||
setAnalogNumChannelsToActivate(kAnalogPins);
|
||||
setAnalogSampleRate(kDefaultSampleRate, status);
|
||||
|
||||
@@ -67,15 +67,15 @@ void initializeDigital(int32_t *status) {
|
||||
if (digitalSystemsInitialized) return;
|
||||
|
||||
// Create a semaphore to protect changes to the digital output values
|
||||
digitalDIOSemaphore = initializeMutex(SEMAPHORE_Q_PRIORITY | SEMAPHORE_DELETE_SAFE | SEMAPHORE_INVERSION_SAFE);
|
||||
digitalDIOSemaphore = initializeMutexRecursive();
|
||||
|
||||
// Create a semaphore to protect changes to the relay values
|
||||
digitalRelaySemaphore = initializeMutex(SEMAPHORE_Q_PRIORITY | SEMAPHORE_DELETE_SAFE | SEMAPHORE_INVERSION_SAFE);
|
||||
digitalRelaySemaphore = initializeMutexRecursive();
|
||||
|
||||
// Create a semaphore to protect changes to the DO PWM config
|
||||
digitalPwmSemaphore = initializeMutex(SEMAPHORE_Q_PRIORITY | SEMAPHORE_DELETE_SAFE | SEMAPHORE_INVERSION_SAFE);
|
||||
digitalPwmSemaphore = initializeMutexRecursive();
|
||||
|
||||
digitalI2CSemaphore = initializeMutex(SEMAPHORE_Q_PRIORITY | SEMAPHORE_DELETE_SAFE | SEMAPHORE_INVERSION_SAFE);
|
||||
digitalI2CSemaphore = initializeMutexRecursive();
|
||||
|
||||
Resource::CreateResourceObject(&DIOChannels, tDIO::kNumSystems * kDigitalPins);
|
||||
Resource::CreateResourceObject(&DO_PWMGenerators, tDIO::kNumPWMDutyCycleElements);
|
||||
@@ -420,9 +420,9 @@ bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status) {
|
||||
uint32_t bitToSet = 1 << (remapDigitalChannel(port->port.pin - 1, status));
|
||||
tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status);
|
||||
if (input) {
|
||||
outputEnable.value = outputEnable.value & (~bitToSet); // clear the bit for read
|
||||
outputEnable.Headers = outputEnable.Headers & (~bitToSet); // clear the bit for read
|
||||
} else {
|
||||
outputEnable.value = outputEnable.value | bitToSet; // set the bit for write
|
||||
outputEnable.Headers = outputEnable.Headers | bitToSet; // set the bit for write
|
||||
}
|
||||
digitalSystem->writeOutputEnable(outputEnable, status);
|
||||
}
|
||||
@@ -497,7 +497,7 @@ bool getDIODirection(void* digital_port_pointer, int32_t *status) {
|
||||
//AND it against the currentOutputEnable
|
||||
//if it == 0, then return false
|
||||
//else return true
|
||||
return ((currentOutputEnable.value >> remapDigitalChannel(port->port.pin - 1, status)) & 1) != 0;
|
||||
return ((currentOutputEnable.Headers >> remapDigitalChannel(port->port.pin - 1, status)) & 1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,7 +510,7 @@ bool getDIODirection(void* digital_port_pointer, int32_t *status) {
|
||||
void pulse(void* digital_port_pointer, double pulseLength, int32_t *status) {
|
||||
DigitalPort* port = (DigitalPort*) digital_port_pointer;
|
||||
tDIO::tPulse pulse;
|
||||
pulse.value = 1 << remapDigitalChannel(port->port.pin - 1, status);
|
||||
pulse.Headers = 1 << remapDigitalChannel(port->port.pin - 1, status);
|
||||
digitalSystem->writePulseLength((uint8_t)(1.0e9 * pulseLength / (pwmSystem->readLoopTiming(status) * 25)), status);
|
||||
digitalSystem->writePulse(pulse, status);
|
||||
}
|
||||
@@ -524,7 +524,7 @@ bool isPulsing(void* digital_port_pointer, int32_t *status) {
|
||||
DigitalPort* port = (DigitalPort*) digital_port_pointer;
|
||||
uint16_t mask = 1 << remapDigitalChannel(port->port.pin - 1, status);
|
||||
tDIO::tPulse pulseRegister = digitalSystem->readPulse(status);
|
||||
return (pulseRegister.value & mask) != 0;
|
||||
return (pulseRegister.Headers & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -543,7 +543,7 @@ bool isAnyPulsing(int32_t *status) {
|
||||
*/
|
||||
bool isAnyPulsingWithModule(uint8_t module, int32_t *status) {
|
||||
tDIO::tPulse pulseRegister = digitalSystem->readPulse(status);
|
||||
return pulseRegister.value != 0;
|
||||
return pulseRegister.Headers != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "Port.h"
|
||||
#include "HAL/Errors.h"
|
||||
#include "ChipObject.h"
|
||||
#include "NetworkCommunication/FRCComm.h"
|
||||
#include "NetworkCommunication/UsageReporting.h"
|
||||
|
||||
// XXX: What to do with solenoids? const uint32_t solenoid_kNumDO7_0Elements = tSolenoid::kNumDO7_0Elements;
|
||||
const uint32_t dio_kNumSystems = tDIO::kNumSystems;
|
||||
@@ -107,6 +109,80 @@ int32_t getFPGALED(int32_t *status) {
|
||||
return 0; // XXX: Dummy value
|
||||
}
|
||||
|
||||
int HALSetErrorData(const char *errors, int errorsLength, int wait_ms)
|
||||
{
|
||||
return setErrorData(errors, errorsLength, wait_ms);
|
||||
}
|
||||
|
||||
int HALSetUserDsLcdData(const char *userDsLcdData, int userDsLcdDataLength, int wait_ms)
|
||||
{
|
||||
return setUserDsLcdData(userDsLcdData, userDsLcdDataLength, wait_ms);
|
||||
}
|
||||
|
||||
int HALOverrideIOConfig(const char *ioConfig, int wait_ms)
|
||||
{
|
||||
return overrideIOConfig(ioConfig, wait_ms);
|
||||
}
|
||||
|
||||
int HALGetDynamicControlData(uint8_t type, char *dynamicData, int32_t maxLength, int wait_ms)
|
||||
{
|
||||
return getDynamicControlData( type, dynamicData, maxLength, wait_ms);
|
||||
}
|
||||
|
||||
int HALGetCommonControlData(HALCommonControlData *data, int wait_ms)
|
||||
{
|
||||
return getCommonControlData( (FRCCommonControlData*)data, wait_ms );
|
||||
}
|
||||
|
||||
void HALSetNewDataSem(pthread_mutex_t * param)
|
||||
{
|
||||
setNewDataSem(param);
|
||||
}
|
||||
|
||||
int HALSetStatusData(float battery, uint8_t dsDigitalOut, uint8_t updateNumber,
|
||||
const char *userDataHigh, int userDataHighLength,
|
||||
const char *userDataLow, int userDataLowLength, int wait_ms)
|
||||
{
|
||||
return setStatusData(battery, dsDigitalOut, updateNumber, userDataHigh, userDataHighLength, userDataLow, userDataLowLength, wait_ms);
|
||||
}
|
||||
|
||||
|
||||
void HALNetworkCommunicationReserve()
|
||||
{
|
||||
FRC_NetworkCommunication_Reserve();
|
||||
}
|
||||
|
||||
void HALNetworkCommunicationObserveUserProgramStarting(void)
|
||||
{
|
||||
FRC_NetworkCommunication_observeUserProgramStarting();
|
||||
}
|
||||
|
||||
void HALNetworkCommunicationObserveUserProgramDisabled(void)
|
||||
{
|
||||
FRC_NetworkCommunication_observeUserProgramDisabled();
|
||||
}
|
||||
|
||||
void HALNetworkCommunicationObserveUserProgramAutonomous(void)
|
||||
{
|
||||
FRC_NetworkCommunication_observeUserProgramAutonomous();
|
||||
}
|
||||
|
||||
void HALNetworkCommunicationObserveUserProgramTeleop(void)
|
||||
{
|
||||
FRC_NetworkCommunication_observeUserProgramTeleop();
|
||||
}
|
||||
|
||||
void HALNetworkCommunicationObserveUserProgramTest(void)
|
||||
{
|
||||
FRC_NetworkCommunication_observeUserProgramTest();
|
||||
}
|
||||
|
||||
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context, const char *feature)
|
||||
{
|
||||
return FRC_NetworkCommunication_nUsageReporting_report( resource, instanceNumber, context, feature);
|
||||
}
|
||||
|
||||
|
||||
// TODO: HACKS
|
||||
void NumericArrayResize() {}
|
||||
void RTSetCleanupProc() {}
|
||||
|
||||
@@ -188,6 +188,8 @@ extern "C" {
|
||||
void EXPORT_FUNC FRC_NetworkCommunication_observeUserProgramAutonomous(void);
|
||||
void EXPORT_FUNC FRC_NetworkCommunication_observeUserProgramTeleop(void);
|
||||
void EXPORT_FUNC FRC_NetworkCommunication_observeUserProgramTest(void);
|
||||
void EXPORT_FUNC FRC_NetworkCommunication_Reserve();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
#include "HAL/Semaphore.h"
|
||||
|
||||
#include "ChipObject.h"
|
||||
#include "Log.h"
|
||||
|
||||
// set the logging level
|
||||
TLogLevel semaphoreLogLevel = logDEBUG;
|
||||
|
||||
#define SEMAPHORE_LOG(level) \
|
||||
if (level > semaphoreLogLevel) ; \
|
||||
else Log().Get(level)
|
||||
|
||||
// See: http://www.vxdev.com/docs/vx55man/vxworks/ref/semMLib.html
|
||||
const uint32_t SEMAPHORE_Q_FIFO= 0x01; // TODO: Support
|
||||
@@ -15,7 +23,8 @@ const int32_t SEMAPHORE_WAIT_FOREVER = -1;
|
||||
const uint32_t SEMAPHORE_EMPTY = 0;
|
||||
const uint32_t SEMAPHORE_FULL = 1;
|
||||
|
||||
MUTEX_ID initializeMutex(uint32_t flags) {
|
||||
MUTEX_ID initializeMutexRecursive()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
@@ -25,38 +34,47 @@ MUTEX_ID initializeMutex(uint32_t flags) {
|
||||
return sem;
|
||||
}
|
||||
|
||||
void deleteMutex(MUTEX_ID sem) {
|
||||
pthread_mutex_destroy(sem);
|
||||
delete sem;
|
||||
MUTEX_ID initializeMutexNormal()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
|
||||
MUTEX_ID sem = new pthread_mutex_t();
|
||||
pthread_mutex_init(sem, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return sem;
|
||||
}
|
||||
|
||||
void deleteMutex(MUTEX_ID sem)
|
||||
{
|
||||
pthread_mutex_destroy(sem);
|
||||
delete sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the semaphore, blocking until it's available.
|
||||
* @return 0 for success, -1 for error. If -1, the error will be in errno.
|
||||
*/
|
||||
int8_t takeMutex(MUTEX_ID sem, int32_t timeout) {
|
||||
if (timeout == SEMAPHORE_NO_WAIT) {
|
||||
return pthread_mutex_trylock(sem);
|
||||
} else if (timeout == SEMAPHORE_WAIT_FOREVER) {
|
||||
int8_t takeMutex(MUTEX_ID sem)
|
||||
{
|
||||
return pthread_mutex_lock(sem);
|
||||
} else {
|
||||
// struct timespec test;
|
||||
// return pthread_mutex_timedlock(sem, );
|
||||
return -1; // TODO: implement timed wait
|
||||
}
|
||||
}
|
||||
|
||||
int8_t tryTakeMutex(MUTEX_ID sem)
|
||||
{
|
||||
return pthread_mutex_trylock(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the semaphore.
|
||||
* @return 0 for success, -1 for error. If -1, the error will be in errno.
|
||||
*/
|
||||
int8_t giveMutex(MUTEX_ID sem) {
|
||||
// return semGive(sem);
|
||||
// return sem_post(sem);
|
||||
return pthread_mutex_unlock(sem);
|
||||
int8_t giveMutex(MUTEX_ID sem)
|
||||
{
|
||||
return pthread_mutex_unlock(sem);
|
||||
}
|
||||
|
||||
SEMAPHORE_ID initializeSemaphore(uint32_t flags, uint32_t initial_value) {
|
||||
SEMAPHORE_ID initializeSemaphore(uint32_t initial_value) {
|
||||
SEMAPHORE_ID sem = new sem_t;
|
||||
sem_init(sem, 0, initial_value);
|
||||
return sem;
|
||||
@@ -71,22 +89,22 @@ void deleteSemaphore(SEMAPHORE_ID sem) {
|
||||
* Lock the semaphore, blocking until it's available.
|
||||
* @return 0 for success, -1 for error. If -1, the error will be in errno.
|
||||
*/
|
||||
int8_t takeSemaphore(SEMAPHORE_ID sem, int32_t timeout) {
|
||||
if (timeout == SEMAPHORE_NO_WAIT) {
|
||||
return sem_trywait(sem);
|
||||
} else if (timeout == SEMAPHORE_WAIT_FOREVER) {
|
||||
int8_t takeSemaphore(SEMAPHORE_ID sem)
|
||||
{
|
||||
return sem_wait(sem);
|
||||
} else {
|
||||
// return sem_timedwait(sem, );
|
||||
return -1; // TODO: implement timed wait
|
||||
}
|
||||
}
|
||||
|
||||
int8_t tryTakeSemaphore(SEMAPHORE_ID sem)
|
||||
{
|
||||
return sem_trywait(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the semaphore.
|
||||
* @return 0 for success, -1 for error. If -1, the error will be in errno.
|
||||
*/
|
||||
int8_t giveSemaphore(SEMAPHORE_ID sem) {
|
||||
int8_t giveSemaphore(SEMAPHORE_ID sem)
|
||||
{
|
||||
return sem_post(sem);
|
||||
}
|
||||
|
||||
@@ -106,8 +124,8 @@ void deleteMultiWait(MULTIWAIT_ID sem) {
|
||||
}
|
||||
|
||||
int8_t takeMultiWait(MULTIWAIT_ID sem, int32_t timeout) {
|
||||
MUTEX_ID m = initializeMutex(NULL);
|
||||
takeMutex(m, SEMAPHORE_WAIT_FOREVER);
|
||||
MUTEX_ID m = initializeMutexNormal();
|
||||
takeMutex(m);
|
||||
int8_t val = pthread_cond_wait(sem, m);
|
||||
deleteMutex(m);
|
||||
return val;
|
||||
|
||||
@@ -19,21 +19,21 @@ Synchronized::Synchronized(MUTEX_ID semaphore)
|
||||
{
|
||||
m_mutex = semaphore;
|
||||
m_semaphore = NULL;
|
||||
takeMutex(m_mutex, SEMAPHORE_WAIT_FOREVER);
|
||||
takeMutex(m_mutex);
|
||||
}
|
||||
|
||||
Synchronized::Synchronized(SEMAPHORE_ID semaphore)
|
||||
{
|
||||
m_mutex = NULL;
|
||||
m_semaphore = semaphore;
|
||||
takeSemaphore(m_semaphore, SEMAPHORE_WAIT_FOREVER);
|
||||
takeSemaphore(m_semaphore);
|
||||
}
|
||||
|
||||
Synchronized::Synchronized(ReentrantSemaphore& semaphore)
|
||||
{
|
||||
m_mutex = semaphore.m_semaphore;
|
||||
m_semaphore = NULL;
|
||||
takeMutex(m_mutex, SEMAPHORE_WAIT_FOREVER);
|
||||
takeMutex(m_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user