LIN: Legacy API

This commit is contained in:
Kyle Johannes
2023-04-05 15:43:26 +00:00
parent 0fa7494eab
commit 63c81b1c3d
17 changed files with 1134 additions and 104 deletions
+5
View File
@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.2)
project(libicsneoc-legacy-lin-example VERSION 0.2.0)
add_executable(libicsneoc-legacy-lin-example lin/main.c)
target_link_libraries(libicsneoc-legacy-lin-example icsneolegacy)
+80
View File
@@ -0,0 +1,80 @@
# libicsneo C Example
This is an example console application that uses the icsneoc library to control an Intrepid Control Systems hardware device.
## Cloning
This will create a copy of the repository on your local machine.
Run:
```shell
git clone https://github.com/intrepidcs/libicsneo-examples -b v0.2.0-dev --recursive
```
Alternatively, if you cloned without the `--recursive` flag, you must enter the `libicsneo-examples` folder and run the following:
```shell
git submodule update --recursive --init
```
If you haven't done this, `third-party/libicsneo` will be empty and you won't be able to build!
## Windows using Visual Studio 2017+
### Building the DLL
First, we are going to build the icsneoc library into a .dll file that we can later use in order to access the library functions.
1. Launch Visual Studio and open the `libicsneo-examples` folder.
2. Choose `File->Open->Cmake...`
3. Navigate to `third-party/libicsneo` and select the `CMakeLists.txt` there.
4. Visual Studio will process the CMake project.
5. Select `Build->Rebuild All`
6. Visual Studio will generate the `icsneoc.dll` file, which can then be found by selecting `Project->Cmake Cache (x64-Debug Only)->Open in Explorer`. If the file cannot be found, search in `libicsneo-examples/third-party/libicsneo/out/build/x64-Debug` and double-check that the build succeeded in step 5.
7. Move the `icsneoc.dll` file to the `/C/Windows/System32` folder. This will allow it to be found by icsneo_init(), which loads all the library functions.
* Alternatively, the `icsneoc.dll` file can be placed in the same directory as `libicsneoc-example.exe`, which is typically `libicsneo-examples/libicsneoc-example/out/build/x64-Debug`, although this is not recommended. For more information, refer to [the Microsoft documentation](https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order).
### Building the example program
Although the example program will build without successfully completing the steps above, it will exit immediately upon running due to a failure to load any library functions.
1. Choose `File->Open->Cmake...`
2. Navigate to `libicsneo-examples/libicsneoc-example` and select the `CMakeLists.txt` there.
3. Visual Studio will process the CMake project.
4. Select `Build->Rebuild All`
5. Click on the dropdown arrow attached to the green play button (labelled "Select Startup Item") and select `libicsneoc-example.exe`
6. Click on the green play button to run the example.
## Ubuntu 18.04 LTS
### Building the .so
First, we are going to build the icsneoc library into a .so file that we can later use in order to access the library functions.
1. Install dependencies with `sudo apt update` then `sudo apt install build-essential cmake libusb-1.0-0-dev libpcap0.8-dev`
2. Change directories to `libicsneo-examples/third-party/libicsneo` and create a build directory by running `mkdir -p build`
3. Enter the build directory with `cd build`
4. Run `cmake ..` to generate your Makefile.
* Hint! Running `cmake -DCMAKE_BUILD_TYPE=Debug ..` will generate the proper scripts to build debug, and `cmake -DCMAKE_BUILD_TYPE=Release ..` will generate the proper scripts to build with all optimizations on.
5. Run `make` to build the library.
* Hint! Speed up your build by using multiple processors! Use `make -j#` where `#` is the number of cores/threads your system has plus one. For instance, on a standard 8 thread Intel i7, you might use `-j9` for an ~8x speedup.
6. Run `sudo cp libicsneoc.so /usr/lib` so that it can be found via the default ubuntu .so search path. For more information, see the [ld.so.8 man page](http://man7.org/linux/man-pages/man8/ld.so.8.html).
### Building the example program
Although the example program will build without successfully completing the steps above, it will exit immediately upon running due to a failure to load any library functions.
1. Change directories to `libicsneo-examples/libicsneoc-example`
2. Create a build directory by running `mkdir -p build`
3. Enter the build directory with `cd build`
4. Run `cmake ..` to generate your Makefile.
* Hint! Running `cmake -DCMAKE_BUILD_TYPE=Debug ..` will generate the proper scripts to build debug, and `cmake -DCMAKE_BUILD_TYPE=Release ..` will generate the proper scripts to build with all optimizations on.
5. Run `make` to build the library.
* Hint! Speed up your build by using multiple processors! Use `make -j#` where `#` is the number of cores/threads your system has plus one. For instance, on a standard 8 thread Intel i7, you might use `-j9` for an ~8x speedup.
6. Run `sudo ./libicsneoc-example` to run the example.
* Hint! In order to run without sudo, you will need to set up the udev rules. Copy `libicsneo-examples/third-party/libicsneo/99-intrepidcs.rules` to `/etc/udev/rules.d`, then run `udevadm control --reload-rules && udevadm trigger` afterwards. While the program will still run without setting up these rules, it will fail to open any devices.
## macOS
Instructions coming soon™
+165
View File
@@ -0,0 +1,165 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdbool.h>
#if defined _WIN32
#include "icsneo/platform/windows.h"
#define SLEEP(msecs) Sleep(msecs)
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
#include <time.h>
#define SLEEP(msecs) do { \
struct timespec ts; \
ts.tv_sec = msecs/1000; \
ts.tv_nsec = msecs%1000*1000; \
nanosleep(&ts, NULL); \
} while (0)
#else
#error "Platform unknown"
#endif
// Get the PRIu64 macro for timestamps
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
// Include icsneo/icsneolegacy.h to access library functions
#include "icsneo/icsneolegacy.h"
int main() {
int ver = icsneoGetDLLVersion();
printf("ICS icsneolegacy.dll version %u\n\n", ver);
// Find and attempt to open device
//legacy open device
int numDevices = 10;
NeoDevice devices[10];
void* hObject; // holds a handle to the neoVI object
int iRetVal = 0;
int deviceTypes = 0;
int iResult = 0;
iRetVal = icsneoFindNeoDevices(deviceTypes, devices, &numDevices);
if(iRetVal) {
// Attempt to open the selected device, enable message polling, and go online
iRetVal = icsneoOpenNeoDevice(&devices[0], &hObject, NULL, 1, 0);
if(iRetVal) {
printf("Device found and opened!\n");
} else {
printf("Device found but failed to open!\n");
}
} else {
printf("No new devices found!\n");
}
// Send message LIN
{
//lin responder frame
icsSpyMessageJ1850 msg1 = {0};
int lNetworkID;
msg1.Protocol = SPY_PROTOCOL_LIN;
msg1.StatusBitField = 0;
msg1.StatusBitField2 = 0;
lNetworkID = NETID_LIN2;
msg1.Header[0] = 0x11; //protected ID
msg1.Header[1] = 0xaa;
msg1.Header[2] = 0xbb;
msg1.Data[0] = 0xcc;
msg1.Data[1] = 0xdd;
msg1.Data[2] = 0x11;
msg1.Data[3] = 0x22;
msg1.Data[4] = 0x33;
msg1.Data[5] = 0x44;
msg1.Data[6] = 0x44; //checksum 0x33 enhanced
msg1.NumberBytesData = 7;
msg1.NumberBytesHeader = 3;
iRetVal = icsneoTxMessages(hObject, (icsSpyMessage*)&msg1, lNetworkID, 1);
if(!iRetVal)
printf("Device failed to transmit LIN responder update\n");
else
printf("Transmitted successfully!\n");
icsSpyMessageJ1850 msg2 = {0};
msg2.Protocol = SPY_PROTOCOL_LIN;
msg2.StatusBitField = SPY_STATUS_INIT_MESSAGE;
lNetworkID = NETID_LIN;
msg2.Header[0] = 0x11; //protected ID
msg2.NumberBytesData = 0;
msg2.NumberBytesHeader = 1;
iRetVal = icsneoTxMessages(hObject, (icsSpyMessage*)&msg2, lNetworkID, 1);
if(!iRetVal)
printf("Device failed to transmit LIN commander header\n");
else
printf("Transmitted successfully!\n");
SLEEP(250);
icsSpyMessageJ1850 msg3 = {0};
msg3.Protocol = SPY_PROTOCOL_LIN;
msg3.StatusBitField = SPY_STATUS_INIT_MESSAGE;
msg3.StatusBitField2 = 0;
lNetworkID = NETID_LIN;
msg3.Header[0] = 0xe2; //protected ID
msg3.Header[1] = 0x44;
msg3.Header[2] = 0x33;
msg3.Data[0] = 0x22;
msg3.Data[1] = 0x11;
msg3.Data[2] = 0x11;
msg3.Data[3] = 0x22;
msg3.Data[4] = 0x33;
msg3.Data[5] = 0x44;
msg3.Data[6] = 0xc7; //checksum
msg3.NumberBytesData = 7;
msg3.NumberBytesHeader = 3;
iRetVal = icsneoTxMessages(hObject, (icsSpyMessage*)&msg3, lNetworkID, 1);
if(!iRetVal)
printf("Device failed to transmit LIN commander message\n");
else
printf("Transmitted successfully!\n");
}
SLEEP(1000);
// Get messages
{
static icsSpyMessage rxMsg[30000];
int numMessages = 0;
int numErrors = 0;
iRetVal = icsneoGetMessages(hObject, rxMsg, &numMessages, &numErrors);
if(!iRetVal)
printf("Get Messages failed!\n");
else
for(int idx = 0; idx < numMessages; ++idx)
{
if(rxMsg[idx].Protocol == SPY_PROTOCOL_LIN) {
const icsSpyMessageJ1850* linMsg = (icsSpyMessageJ1850*)&rxMsg[idx];
size_t frameLen = (linMsg->NumberBytesHeader + linMsg->NumberBytesData);
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
if(linMsg->NetworkID == NETID_LIN) {
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
else if (linMsg->NetworkID == NETID_LIN2) {
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
for(size_t i = 0; i < dataLen; ++i) {
if (i < 2) {
printf("%02x ", linMsg->Header[i+1]);
} else {
printf("%02x ", linMsg->Data[i-2]);
}
}
if(linMsg->NumberBytesData > 0)
printf("| Checksum: 0x%02x\n", linMsg->Data[linMsg->NumberBytesData-1]);
else
printf("| Checksum: 0x%02x\n", linMsg->Header[linMsg->NumberBytesHeader-1]);
}
}
}
int iNumberOfErrors = 0;
// Attempt to close the device
{
// Close Communication
iResult = icsneoClosePort(hObject, &iNumberOfErrors);
}
printf("Exiting program\n");
return iResult;
}