我正在尝试使用xlCanTransmit方法发送CAN帧。问题在于它返回0(XL_SUCCESS),但是该框架为空。框架中只有零。
IVxlApi.s_xl_event eventMsg = new IVxlApi.s_xl_event();
...
...
xlStatus = dll.xlCanTransmit(GlobalConfig.g_xlPortHandle, GlobalConfig.g_xlChannelMask[channelIndex],
pEventCount, eventMsg.getPointer());
在调用函数xlCanTransmit()之后,将发送该帧,但是其中没有数据。该函数是从dll文件中调用的,您无法对其进行调试。
我的映射结构
public static class s_xl_event extends Structure {
public byte tag;
public byte chanIndex;
public byte[] transId = new byte[SHORT];
public byte[] portHandle = new byte[SHORT];
public byte flags;
public byte reserved;
public byte[] timeStamp = new byte[LONG];
public s_xl_tag_data tagData;
@Override
public void read() {
// read from native memory, populate tag
super.read();
// set union type based on tag
switch (tag) {
case XL_RECEIVE_MSG:
case XL_TRANSMIT_MSG:
tagData.setType(s_xl_can_msg.class);
break;
case XL_CHIP_STATE:
tagData.setType(s_xl_chip_state.class);
break;
case XL_LIN_MSG:
tagData.setType(s_xl_lin_msg_api.class);
break;
case XL_SYNC_PULSE:
tagData.setType(s_xl_sync_pulse.class);
break;
case XL_RECEIVE_DAIO_DATA:
tagData.setType(s_xl_daio_data.class);
break;
case XL_TRANSCEIVER:
tagData.setType(s_xl_transceiver.class);
break;
case XL_RECEIVE_DAIO_PIGGY:
tagData.setType(s_xl_daio_piggy_data.class);
break;
case XL_KLINE_MSG:
tagData.setType(s_xl_kline_data.class);
break;
default:
// add default type or throw exception etc.
tagData.setType(s_xl_can_msg.class);
break;
}
// now read tagData from native memory
tagData.read();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("tag", "chanIndex", "transId", "portHandle", "flags", "reserved", "timeStamp", "tagData");
}
}
CANoe Trace中的CAN框架
本机端的函数如下所示
DECL_STDXL_FUNC(xlCanTransmit, XLCANTRANSMIT, (
XLportHandle portHandle,
XLaccess accessMask,
unsigned int* pEventCount,
void* pEvents)
);
我在Java中的映射
short xlCanTransmit(long portHandle, long accessMask, IntByReference pEventCount, Pointer pEvents);
我手动编写了一些随机数据,并调用了xlCanTransmit()函数。
但是在CANoe跟踪中,我只能看到没有数据和ID的空框架。
我的Java发送函数
public short send(String txID, String dlc, String[] data, int channelIndex) {
short xlStatus = IVxlApi.XL_ERROR;
IntByReference pEventCount = new IntByReference(1);
IVxlApi.s_xl_event eventMsg = new IVxlApi.s_xl_event();
eventMsg.tag = IVxlApi.XL_TRANSMIT_MSG;
eventMsg.tagData.msg.id[0] = 2;// = Long.parseLong(txID);
eventMsg.tagData.msg.dlc[0] = 8;// = Short.parseShort(dlc);
eventMsg.tagData.msg.flags[0] = 0;
eventMsg.tagData.msg.data[0] = Byte.parseByte(data[0]);
eventMsg.tagData.msg.data[1] = Byte.parseByte(data[1]);
eventMsg.tagData.msg.data[2] = Byte.parseByte(data[2]);
eventMsg.tagData.msg.data[3] = Byte.parseByte(data[3]);
eventMsg.tagData.msg.data[4] = Byte.parseByte(data[4]);
eventMsg.tagData.msg.data[5] = Byte.parseByte(data[5]);
eventMsg.tagData.msg.data[6] = Byte.parseByte(data[6]);
eventMsg.tagData.msg.data[7] = Byte.parseByte(data[7]);
/*if(true){
eventMsg.tagData.msg.id |= IVxlApi.XL_CAN_EXT_MSG_ID;
}*/
eventMsg.write();
xlStatus = dll.xlCanTransmit(GlobalConfig.g_xlPortHandle, GlobalConfig.g_xlChannelMask[channelIndex],
pEventCount, eventMsg.getPointer());
eventMsg.read();
return xlStatus;
}
CANoe Trace中的CAN框架
在调用tagData.read()(第475行)之后,数据初始化为零 enter image description here
答案 0 :(得分:0)
返回值0
表示在本机端正确执行了该功能,但您尚未将本机内存复制回Java。
通常在您在函数中传递Structure
时自动完成此操作,但是您已经将Pointer
传递给了结构。您的最后一个参数是eventMsg.getPointer()
。直到您告知Pointer
到您的结构,JNA才会知道它如何映射,并且按照当前的调用方式,它需要使用read()
将值复制回JNA。 / p>
调用该函数后,只需执行eventMsg.read()
即可获得所需的结果,但更好的解决方法是首先将Structure
传递给该函数,然后让JNA进行转换指向指针并自动为您read()
。更改函数调用以将eventMsg
作为参数传递。