Hi Guys,
Firstly, I apologize for this taking a year to get a real answer...
This is one little quirk with the way Build compiles the code that I don't believe we have documented well... So I'll document here.
The CanComms.RxOpenStandard() function is used by Build in two ways. The line of code is extracted from your scheduled method and used at ECU startup to configure the CAN driver and receive buffer. So where you have written -
- Code: Select all
local canBus = CAN Bus.AsInteger() -1;
CanComms.RxOpenStandard(canBus, 0xXXX, 0x000, true);
Only the CanComms line is extracted and used at startup, the canBus local variable does not exist and so 'canBus' in the function returns 0 when this line is processed at startup. The same applies for the other variables used in the function.
This means only parameters or hard coded values can be used within the function. I did some testing a long time ago and I think flash backed channels may also work, but the ECU still requires a reset to update the details of messages sent to the buffer by the system, so it's not possible to set the CAN ID dynamically as the ECU is running. If we did allow some sort of reset of the Rx details, it can get quite messy in terms of change over time and what messages make it through. There is a better way to handle this.
The code that is actually used periodically is only a link to retrieve the handle for the receive buffer in question. The data passed there periodically is never used.
It works this way so that immediately after startup the system can start receiving CAN messages and pushes them off to the receive buffer (with matching bus, ID and mask). You don't have to read the data as the RxMessage() function can be called conditionally, the data will wait there. Up to 32 CAN messages can be buffered before the oldest message is over written and lost if you don't call RxMessage() soon enough.
The ideal way to code the bus number to the function is like this -
- Code: Select all
CanComms.RxOpenStandard(CAN Bus eq CAN Bus.Not in Use ? 0 : CAN Bus.AsInteger() -1, 0xXXX, 0x000, true);
The reason for the ternary operator usage is because if we just use CAN Bus.As Interger() - 1, if the CAN Bus parameter is set to Not in Use (0) then -1 is passed to RxOpenStandard() which gives an error condition to the system and a debug message is written. We are locked to using Not in Use as 0 so that the object hiding in Tune functions correctly. It ends up a bit messy, but no strain on the CPU since all of this is only used at startup.
This assumes using our standard enumeration with Not in Use, CAN Bus 1, 2 and 3. If you don't want to take advantage of the object hiding in Tune, an enumeration of CAN Bus 1, 2 and 3 with integer values of 0, 1 and 2 respectively can be used also and the parameter with .AsInteger() can be used without the - 1 or ternary operator.
The functions that have this dual usage are -
- CanComms.RxOpenStandard()
- CanComms.RxOpenExtended()
- CanComms.RxOpenStandardBuffered()
- CanComms.RxOpenExtendedBuffered()
- CanComms.TxOpen()
- J1939.Open()
- J1939.DTC()
- J1939.RxParameterGroup()
- J1939.TxParameterGroup()
The CanComms.TxStandard() function does not suffer from the same issue as the variables passed to the function are used periodically.