Kvaser Linux CANLIB
|
To set the mask to 0xF0 and the code to 0x60:
stat = canAccept(handle1, 0x0F0L, canFILTER_SET_MASK_STD); if (stat < 0) printf("canAccept failed, stat = %d\n", stat); stat = canAccept(handle1, 0x060L, canFILTER_SET_CODE_STD); if (stat < 0) printf("canAccept failed, stat = %d\n", stat);
or, alternatively,
stat = canSetAcceptanceFilter(handle1, 0x060, 0x0F0, FALSE); if (stat < 0) printf("canSetAcceptanceFilter failed, stat = %d\n", stat);
Result
Messages having a standard identifier with bit7-bit4 in the identifier equal to 0110 (binary) will pass through. Other messages with standard identifiers will be rejected.
This example takes an open channel off-bus and then takes it on-bus again, for what purpose it may serve.
int stat; int handle; . . . stat = canBusOff(handle); if (stat < 0) { printf("canBusOff failed, status=%d\n", stat); exit(1); } stat = canBusOn(handle); if (stat < 0) { printf("canBusOn failed, status=%d\n", stat); exit(1); }
This example opens a channel (see canOpenChannel()), sets the bit rate to 125 kbit/s using default bit timing parameters, and goes on bus.
int stat; int handle; . . . handle = canOpenChannel(0, 0); stat = canSetBusParams(handle, BAUD_125K, 0, 0, 0, 0, 0); if (stat < 0) { printf("canBusParams failed, status=%d\n", stat); exit(1); } stat = canBusOn(handle); if (stat < 0) { printf("canBusOn failed, status=%d\n", stat); exit(1); }
This example closes the specified handle.
int stat = canClose(hnd); if (stat < 0) { printf("Close failed."); }
Here's a procedure that prints an error message when the passed status code means failure.
void Check(canStatus stat) { char buf[100]; if (stat != canOK) { buf[0] = '\0'; canGetErrorText(stat, buf, sizeof(buf)); printf("Failed, stat=%d (%s)\n", (int)stat, buf); exit(1); } }
This example initializes the library.
This example opens channel 0 for exclusive usage by this application.
int hnd; hnd = canOpenChannel(0, canOPEN_EXCLUSIVE); if (hnd < 0) { printf("Open failed, stat=%d\n", hnd); }
The following code fragment reads the next available CAN message, if any.
int handle; long id; unsigned char data[8]; unsigned int dlc, flags; unsigned long timestamp; stat = canRead(handle, &id, data, &dlc, &flags, ×tamp); if (stat != canERR_NOMSG) { printf("Failed, status == %d\n", stat); }
This example opens a channel (see canOpenChannel()), sets the bit rate to 125 kbit/s using default bit timing parameters, and goes on bus.
int stat; int handle; . . . handle = canOpenChannel(0, canOPEN_EXCLUSIVE); stat = canSetBusParams(handle, BAUD_125K, 0, 0, 0, 0, 0); if (stat < 0) { printf("canSetBusParams failed, status=%d\n", stat); exit(1); } stat = canBusOn(handle); if (stat < 0) { printf("canBusOn failed, status=%d\n", stat); exit(1); }
If we had used this call instead:
stat = canSetBusParams(handle, 125000, 4, 3, 1, 1, 0);
the result would have been:
125 kbit/s, each bit comprising 8 (= 1 + 4 + 3) quanta, the sampling point occurs at 5/8 of a bit; SJW = 1; one sampling point.
canHnd = canOpenChannel(...); ... stat = canSetNotify(canHnd, wndHandle, canNOTIFY_RX);
When a CAN message is received and the receive queue is empty, a WM__CANLIB
message will be sent to the window whose handle is wndHandle. The WM__CANLIB
message will have
wParam == canHnd HIWORD(lParam) == 0 LOWORD(lParam) == canEVENT_RX
In the routine that handles WM__CANLIB
, you should call canRead() repeatedly, using the handle found in wParam, until it returns canERR_NOMSG or some other error code.
This code snippet enumerates all CAN channels in the computer and prints the type of the CAN card they're on.
stat = canGetNumberOfChannels(&chanCount); if (stat < 0) ... ; if (chanCount < 0 || chanCount > 300) { printf("ChannelCount = %d but I don't believe it.\n", chanCount); exit(1); // Error } else { printf("%d channels.\n", chanCount); } for (i=0; i < chanCount; i++) { DWORD tmp; printf("== Channel %d ===============================\n", i); stat = canGetChannelData(i, canCHANNELDATA_CARD_TYPE, &tmp, sizeof(tmp)); if (stat < 0) ...; // Error printf("cardtype = 0x%08lx\n", tmp); }
The following code fragment sends a CAN message on an already open channel. The CAN message will have identifier 1234 (extended) and DLC = 8. The contents of the data bytes will be whatever the data array happens to contain.
int handle, stat; unsigned char data[8]; stat = canWrite(handle, 1234, data, 8, canMSG_EXT); if (stat < 0) { printf("Failed, status == %d\n", stat); }
int h; // Make a version check for channel 0. h = canOpenChannel(0, 0); if (canProbeVersion(h, 3, 6, 0, 0)) { printf("This is either 3.6 or later, or a beta\n"); } else { printf("This is 3.5 or earlier\n"); // Hmm.. that is not entirely true, because this program wouldn't // run on 3.5 or earlier. canProbeVersion() wasn't implemented then.. } if (canProbeVersion(h, 3, 6, 0, canVERSION_DONT_ACCEPT_LATER)) { printf("This is precisely 3.6, or a beta\n"); } else { printf("This is not 3.6\n"); } if (canProbeVersion(h, 3, 6, 0, canVERSION_DONT_ACCEPT_LATER|canVERSION_DONT_ACCEPT_BETAS)) { printf("This is precisely 3.6\n"); } else { printf("This is not 3.6, or it is a beta\n"); }
while (!ready) { if (canWaitForEvent(h, 100) == canOK) { while (canRead(h, ...) == canOK) { // Handle incoming messages here } canReadStatus(h, &can_status); } }
The following code fragment resets the time for some already opened channels. It also collects and interprets some data from a domain.
#define NUMBER_OF_CHANNELS 3 int h[NUMBER_OF_CHANNELS]; int stat, i; kvTimeDomain tDomain; kvTimeDomainData tData; ... // Create a time domain for my handles. stat = kvTimeDomainCreate(&tDomain); if (stat < 0) { printf("Failed, status == %d\n", stat); } // Add the handles to the domain. for (i = 0; i < NUMBER_OF_CHANNELS; i++) { stat = kvTimeDomainAddHandle(tDomain, h[i]); if (stat < 0) { printf("Failed to add handle %u to tDomain, ", i); printf("status == %d\n", stat); } } // Request some data from the domain and try to interpret it. stat = kvTimeDomainGetData(tDomain, &tData; sizeof(tData)); if (stat < 0) { printf("Failed, status == %d\n", stat); } if (tData.nMagiSyncGroups > 1) { printf("Consider connecting the Kvaser MagiSync&tm; enabled "); printf("interfaces through the same USB root hub!"); } if (tData.nMagiSyncGroups == 1) { printf("All my Kvaser MagiSync&tm; enabled interfaces are "); printf("connected through the same USB root hub and hence "); printf("perfectly synchronized!"); } if (tData.nMagiSyncedMembers == NUMBER_OF_CHANNELS) { printf("All handles have the Kvaser MagiSync&tm; feature enabled!"); } // Reset the time on all handles in tDomain. stat = kvTimeDomainResetTime(tDomain); if (stat < 0) { printf("Failed, status == %d\n", stat); } ... // Final cleanup stat = kvTimeDomainDelete(tDomain); if (stat < 0) { printf("Failed, status == %d\n", stat); } else { printf("All resources used by tDomain and its members "); printf("returned to system"); }
The following code fragment shows how to load scripts from PC and from SD card, start scripts and how to stop running scripts.
int stat; int handle; ... // Load a script that is stored locally (on SD) into script slot 0 stat = kvScriptLoadFileOnDevice(handle, 0, "script0.txe"); if (stat < 0) { printf("Load failed (0), status == %d\n", stat); } // Load another script stored on the host (PC) into script slot 3 stat = kvScriptLoadFile(handle, 3, "script3.txe"); if (stat < 0) { printf("Load on device failed (3), status == %d\n", stat); } // Start script in slot 0 stat = kvScriptStart(handle, 0); if (stat < 0) { printf("Start failed (0), status == %d\n", stat); } // Start script in slot 3 stat = kvScriptStart(handle, 0); if (stat < 0) { printf("Start failed (3), status == %d\n", stat); } ... // Try to stop script in slot 3 stat = kvScriptStop(handle, 3, kvSCRIPT_STOP_NORMAL); if (stat < 0) { printf("Stop (3) failed, status == %d\n", stat); // For some reason this failed (script is busy?) so we request it to stop. // Note that this is an request and that the script might still be running // when this call returns. stat = kvScriptStop(handle, 3, kvSCRIPT_STOP_FORCED); if (stat < 0) { printf("Forced stop failed (3), status == %d\n", stat); } Sleep(100); // make sure it has stopped. } ... // Load a script that is stored locally (on SD) into script slot 3 stat = kvScriptLoadFileOnDevice(handle, 3, "script3x.txe"); if (stat < 0) { printf("Load failed (3), status == %d\n", stat); } // Start script in slot 3 stat = kvScriptStart(handle, 3); if (stat < 0) { printf("Start failed (3), status == %d\n", stat); }
The following code fragment shows how to use environment variables, envvars for communication between a PC and a script.
CanHandle handle; kvEnvHandle env_handle; int stat; int envvar_size; int envvar_type; int int_val = 0; float float_val = 0; char buffer_val[10] = {0,0,0,0,0,0,0,0,0,0}; ... // Open an int envvar called "ev1_int" and set its value to 55 env_handle = kvScriptEnvvarOpen(handle, "ev1_int", &envvar_type, &envvar_size); if (env_handle < 0) { printf("Open failed, env_handle = %d\n", env_handle); } else { printf("envvar_size = %d, envvar_type = %d\n", envvar_size, envvar_type); stat = kvScriptEnvvarSetInt(env_handle, 55); if (stat < 0) { printf("Failed, stat = %d\n", stat); } // Read back the value of "ev1_int" and close. stat = kvScriptEnvvarGetInt(env_handle, &int_val); if (stat < 0) { printf("Failed, stat = %d\n", stat); } else { printf("int_val = %d\n", int_val); } stat = kvScriptEnvvarClose(env_handle); if (stat < 0) { printf("Failed, stat = %d\n", stat); } } // Open a float envvar called "ev1_float" and set its value to 55.55 env_handle = kvScriptEnvvarOpen(handle, "ev1_float", &envvar_type, &envvar_size); if (env_handle < 0) { printf("Open failed, env_handle = %d\n", env_handle); } else { printf("envvar_size = %d, envvar_type = %d\n", envvar_size, envvar_type); stat = kvScriptEnvvarSetFloat(env_handle, (float)55.55); if (stat < 0) { printf("Failed, stat = %d\n", stat); } // Read back the value of "ev1_int" and close. stat = kvScriptEnvvarGetFloat(env_handle, &float_val); if (stat < 0) { printf("Failed, stat == %d\n", stat); } printf("float_val = %f\n", float_val); stat = kvScriptEnvvarClose(env_handle); if (stat < 0) { printf("Failed, stat = %d\n", stat); } } // Open a buffer envvar called "ev1_buffer" and set its value to ""hello1234"" env_handle = kvScriptEnvvarOpen(handle, "ev1_float", &envvar_type, &envvar_size); if (env_handle < 0) { printf("Open failed, env_handle = %d\n", env_handle); } else { printf("envvar_size = %d, envvar_type = %d\n", envvar_size, envvar_type); // Set value, starting at index 0 in buffer and length 10 stat = kvScriptEnvvarSetData(env_handle, "hello1234", 0, 10); if (stat < 0) { printf("Failed, stat = %d\n", stat); } // Read back the value of "ev1_buffer" and close. stat = kvScriptEnvvarGetData(env_handle, buffer_val, 0, 10); if (stat < 0) { printf("Failed, stat = %d\n", stat); } printf("buffer_val = %s\n", buffer_val); stat = kvScriptEnvvarClose(env_handle); if (stat < 0) { printf("Failed, stat = %d\n", stat); } }
The following code fragment shows how to send a key to a script.
CanHandle handle; int stat; int slot_number; ... // Send key 'a' to scripts running in slot 0...3 for (slot_number = 0; slot_number < 4; slot_number++) { stat = kvScriptSendEvent( handle, slot_number, kvEVENT_TYPE_KEY, 'a', 0 ); }