mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
Simplify JNI interfaces.
These changes both simplify the Java code and improve performance across the JNI boundary. This also fixes the AnalogCrossConnectTest by adding delays to setInterruptHigh() and setInterruptLow() to ensure the change in voltage has time to propagate and extends the timeouts in AbstractInterruptTest. Detailed changes: Hoisted status checks to C. This avoids the need to create direct byte buffers (expensive) and significantly simplifies the Java code. The C code now directly generates the exception or reports the error to the DS. The JVM pointer is now a global across the JNI, initialized by the OnLoad function, avoiding the need for some of the class-specific initializers to get this pointer for callbacks. Opaque pointers (such as ports) are now passed as long values rather than with a ByteBuffer wrapper. Added extern "C" to source files. This allows earlier detection of JNI definition mismatches to the Java source headers. Changed JNI signatures to more closely match HAL signatures (in particular, boolean is now universally used instead of byte for HAL bool, which cleans up mapping back and forth to 1/0 from true/false). Change-Id: I4ea0032cabb0871cd74106a3a70d947258c29d2d
This commit is contained in:
committed by
Brad Miller (WPI)
parent
927400a43c
commit
7023013c4b
@@ -5,6 +5,7 @@
|
||||
#include "edu_wpi_first_wpilibj_hal_DIOJNI.h"
|
||||
|
||||
#include "HAL/Digital.hpp"
|
||||
#include "HALUtil.h"
|
||||
|
||||
// set the logging level
|
||||
TLogLevel dioJNILogLevel = logWARNING;
|
||||
@@ -13,101 +14,92 @@ TLogLevel dioJNILogLevel = logWARNING;
|
||||
if (level > dioJNILogLevel) ; \
|
||||
else Log().Get(level)
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: initializeDigitalPort
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)Ljava/nio/ByteBuffer;
|
||||
* Signature: (J)J;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_initializeDigitalPort
|
||||
(JNIEnv * env, jclass, jobject id, jobject status)
|
||||
JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_initializeDigitalPort
|
||||
(JNIEnv * env, jclass, jlong id)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI initializeDigitalPort";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
void** dioPtr = (void**)new unsigned char[4];
|
||||
*statusPtr = 0;
|
||||
*dioPtr = initializeDigitalPort(*javaId, statusPtr);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "DIO Ptr = " << *dioPtr;
|
||||
return env->NewDirectByteBuffer( dioPtr, 4);
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
void* dio = initializeDigitalPort((void*)id, &status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "DIO Ptr = " << dio;
|
||||
CheckStatus(env, status);
|
||||
return (jlong)dio;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: allocateDIO
|
||||
* Signature: (Ljava/nio/ByteBuffer;BLjava/nio/IntBuffer;)B
|
||||
* Signature: (JZ)Z
|
||||
*/
|
||||
JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_allocateDIO
|
||||
(JNIEnv * env, jclass, jobject id, jbyte value, jobject status)
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_allocateDIO
|
||||
(JNIEnv * env, jclass, jlong id, jboolean value)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI allocateDIO";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
jbyte returnValue = allocateDIO(*javaId, value, statusPtr);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = allocateDIO((void*)id, value, &status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "allocateDIOResult = " << (jint)returnValue;
|
||||
return returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: freeDIO
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)V
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_freeDIO
|
||||
(JNIEnv * env, jclass, jobject id, jobject status)
|
||||
(JNIEnv * env, jclass, jlong id)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDIO";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
freeDIO(*javaId, statusPtr);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
freeDIO((void*)id, &status);
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: setDIO
|
||||
* Signature: (Ljava/nio/ByteBuffer;SLjava/nio/IntBuffer;)V
|
||||
* Signature: (JS)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_setDIO
|
||||
(JNIEnv *env, jclass, jobject id, jshort value, jobject status)
|
||||
(JNIEnv *env, jclass, jlong id, jshort value)
|
||||
{
|
||||
//DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDIO";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
//DIOJNI_LOG(logDEBUG) << "Value = " << value;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
setDIO(*javaId, value, statusPtr);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
int32_t status = 0;
|
||||
setDIO((void*)id, value, &status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: getDIO
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)B
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getDIO
|
||||
(JNIEnv * env, jclass, jobject id, jobject status)
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getDIO
|
||||
(JNIEnv * env, jclass, jlong id)
|
||||
{
|
||||
//DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIO";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
jbyte returnValue = getDIO(*javaId, statusPtr);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = getDIO((void*)id, &status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
//DIOJNI_LOG(logDEBUG) << "getDIOResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
|
||||
}
|
||||
@@ -115,59 +107,53 @@ JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getDIO
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: getDIODirection
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)B
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getDIODirection
|
||||
(JNIEnv *env, jclass, jobject id, jobject status)
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getDIODirection
|
||||
(JNIEnv *env, jclass, jlong id)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIODirection (RR upd)";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
jbyte returnValue = getDIODirection(*javaId, statusPtr);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "getDIODirectionResult = " << (jbyte)returnValue;
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = getDIODirection((void*)id, &status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "getDIODirectionResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: pulse
|
||||
* Signature: (Ljava/nio/ByteBuffer;DLjava/nio/IntBuffer;)V
|
||||
* Signature: (JD)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_pulse
|
||||
(JNIEnv *env, jclass, jobject id, jdouble value, jobject status)
|
||||
(JNIEnv *env, jclass, jlong id, jdouble value)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI pulse (RR upd)";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
//DIOJNI_LOG(logDEBUG) << "Value = " << value;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
pulse(*javaId, value, statusPtr);
|
||||
DIOJNI_LOG(logDEBUG) << "Did it work? Status = " << *statusPtr;
|
||||
int32_t status = 0;
|
||||
pulse((void*)id, value, &status);
|
||||
DIOJNI_LOG(logDEBUG) << "Did it work? Status = " << status;
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: isPulsing
|
||||
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/IntBuffer;)B
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_isPulsing
|
||||
(JNIEnv *env, jclass, jobject id, jobject status)
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_isPulsing
|
||||
(JNIEnv *env, jclass, jlong id)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isPulsing (RR upd)";
|
||||
void ** javaId = (void**)env->GetDirectBufferAddress(id);
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << *javaId;
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status Ptr = " << statusPtr;
|
||||
*statusPtr = 0;
|
||||
jbyte returnValue = isPulsing(*javaId, statusPtr);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "isPulsingResult = " << (jbyte)returnValue;
|
||||
//DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = isPulsing((void*)id, &status);
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "isPulsingResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
|
||||
|
||||
@@ -176,34 +162,36 @@ JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_isPulsing
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: isAnyPulsing
|
||||
* Signature: (Ljava/nio/IntBuffer;)B
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jbyte JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_isAnyPulsing
|
||||
(JNIEnv *env, jclass, jobject status)
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_isAnyPulsing
|
||||
(JNIEnv *env, jclass)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isAnyPulsing (RR upd)";
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
*statusPtr = 0;
|
||||
jbyte returnValue = isAnyPulsing( statusPtr );
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
DIOJNI_LOG(logDEBUG) << "isAnyPulsingResult = " << (jbyte)returnValue;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = isAnyPulsing( &status );
|
||||
//DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "isAnyPulsingResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_DIOJNI
|
||||
* Method: getLoopTiming
|
||||
* Signature: (Ljava/nio/IntBuffer;)S
|
||||
* Signature: ()S
|
||||
*/
|
||||
JNIEXPORT jshort JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_getLoopTiming
|
||||
(JNIEnv * env, jclass, jobject status)
|
||||
(JNIEnv * env, jclass)
|
||||
{
|
||||
DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getLoopTimeing";
|
||||
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
|
||||
*statusPtr = 0;
|
||||
jshort returnValue = getLoopTiming( statusPtr );
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << *statusPtr;
|
||||
int32_t status = 0;
|
||||
jshort returnValue = getLoopTiming( &status );
|
||||
DIOJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
DIOJNI_LOG(logDEBUG) << "LoopTiming = " << returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user