我试图用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跟踪中的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跟踪中的CAN帧
调用tagData.read() (第475行)后,用零在这里输入图像描述初始化数据
发布于 2019-09-18 17:58:30
0
的返回值指示在本机端正确预先设置的函数,但尚未将本机内存复制回Java。
这通常是在函数中传递Structure
时自动完成的,但是您已经将Pointer
传递给了结构。你的最后一个论点是eventMsg.getPointer()
。在您告诉JNA之前,JNA不知道Pointer
如何映射到您的结构,按照当前的调用方式,它需要使用read()
将值复制回JNA。
调用函数后执行eventMsg.read()
可能会得到您想要的结果,但是最好的方法是首先将Structure
传递给函数,然后让JNA为您完成指针和自动read()
的转换。将函数调用更改为传递eventMsg
作为参数。
https://stackoverflow.com/questions/57995326
复制相似问题