mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 09:28:40 +02:00
LIN: Legacy API
This commit is contained in:
@@ -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)
|
||||
@@ -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™
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user