mirror of
https://github.com/intrepidcs/icsscand.git
synced 2026-09-21 16:48:21 +02:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7db3cbcf0 | ||
|
|
616a8ddbce | ||
|
|
dcec89f2da | ||
|
|
919bcccffc | ||
|
|
26b676b474 | ||
|
|
c506f274c2 | ||
|
|
8cc37c9df0 | ||
|
|
028538cc90 | ||
|
|
8d21b98ac6 | ||
|
|
f254ee2515 | ||
|
|
e83021258f |
@@ -1,3 +1,8 @@
|
|||||||
|
v2.0.3
|
||||||
|
Update copyright date
|
||||||
|
Update to libicsneo v0.2.0
|
||||||
|
Ensure lock is held when accessing open devices
|
||||||
|
|
||||||
v2.0.2
|
v2.0.2
|
||||||
Use libicsneo v0.1.2 to resolve LEDs not indicating device status
|
Use libicsneo v0.1.2 to resolve LEDs not indicating device status
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.2)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
project(libicsneo-socketcan-daemon VERSION 2.0.2)
|
project(libicsneo-socketcan-daemon VERSION 2.1.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2016-2019 Intrepid Control Systems, Inc.
|
Copyright (c) 2016-2021 Intrepid Control Systems, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
Version 2.0.2
|
Version 2.0.3
|
||||||
|
|
||||||
This is the usermode daemon for the Intrepid Control Systems SocketCAN support. This daemon requires that ```intrepid.ko``` is loaded on your system.
|
This is the usermode daemon for the Intrepid Control Systems SocketCAN support. This daemon requires that ```intrepid.ko``` is loaded on your system.
|
||||||
|
|
||||||
1. Build and load the kernel module follwowing the instructions in [intrepid-socketcan-kernel-module](https://github.com/intrepidcs/intrepid-socketcan-kernel-module).
|
1. Build and load the kernel module follwowing the instructions in [intrepid-socketcan-kernel-module](https://github.com/intrepidcs/intrepid-socketcan-kernel-module).
|
||||||
|
|
||||||
2. Install the dependencies needed. These are CMake 3.2+, GCC 4.8+, git, and libusb-1.0-0-dev.
|
2. Install the dependencies needed. These are CMake 3.2+, GCC 4.8+, git, libusb-1.0-0-dev, and libpcap.
|
||||||
|
|
||||||
On Ubuntu or other Debian-based systems, run `sudo apt install git cmake gcc libusb-1.0-0-dev build-essential`.
|
On Ubuntu or other Debian-based systems, run `sudo apt install git cmake gcc libusb-1.0-0-dev libpcap-dev build-essential`.
|
||||||
|
|
||||||
3. Clone this repository recursively by running `git clone --recursive https://github.com/intrepidcs/icsscand.git`
|
3. Clone this repository recursively by running `git clone --recursive https://github.com/intrepidcs/icsscand.git`
|
||||||
|
|
||||||
4. Switch into the cloned directory, `cd icsscand`
|
4. Switch into the cloned directory, `cd icsscand`
|
||||||
|
|
||||||
5. Make a build directory and switch into it, `mkdir -p build && cd build`
|
5. Make a build directory and switch into it, `mkdir build && cd build`
|
||||||
|
|
||||||
6. Invoke CMake, `cmake .. -DCMAKE_BUILD_TYPE=Release`
|
6. Invoke CMake, `cmake .. -DCMAKE_BUILD_TYPE=Release`
|
||||||
|
|
||||||
@@ -24,6 +24,6 @@ On Ubuntu or other Debian-based systems, run `sudo apt install git cmake gcc lib
|
|||||||
|
|
||||||
10. CAN interfaces will have been created, but are "down" or, in other words, not enabled for transmit and receive yet. You can see them with `ip link`. They will be labelled `can0`, `can1`, and etc. They will have an alias listed which corresponds to the serial number of the device and network on that device.
|
10. CAN interfaces will have been created, but are "down" or, in other words, not enabled for transmit and receive yet. You can see them with `ip link`. They will be labelled `can0`, `can1`, and etc. They will have an alias listed which corresponds to the serial number of the device and network on that device.
|
||||||
|
|
||||||
11. Enable the CAN interface with `sudo ip link set up can0`, replacing `can0` with whichever interface you'd like to enable
|
11. Enable the CAN interface with `sudo ip link set can0 up`, replacing `can0` with whichever interface you'd like to enable
|
||||||
|
|
||||||
12. You can now use any SocketCAN application with this interface. A good package for testing is the `can-utils` package. You can get this package with `sudo apt install can-utils`. A good testing tool which comes with this package is `candump`. Running `candump can0` will print a line for every incoming frame.
|
12. You can now use any SocketCAN application with this interface. A good package for testing is the `can-utils` package. You can get this package with `sudo apt install can-utils`. A good testing tool which comes with this package is `candump`. Running `candump can0` will print a line for every incoming frame.
|
||||||
|
|||||||
+40
-19
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <icsneo/icsneocpp.h>
|
#include <icsneo/icsneocpp.h>
|
||||||
#include <icsneo/communication/message/neomessage.h>
|
#include <icsneo/communication/message/neomessage.h>
|
||||||
|
#include <icsneo/communication/message/message.h>
|
||||||
|
#include <icsneo/communication/network.h>
|
||||||
#include <icsneo/communication/message/callback/canmessagecallback.h>
|
#include <icsneo/communication/message/callback/canmessagecallback.h>
|
||||||
#include <generated/buildinfo.h>
|
#include <generated/buildinfo.h>
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ int driverPatch = 0;
|
|||||||
int maxInterfaces = 0; // From driver
|
int maxInterfaces = 0; // From driver
|
||||||
int sharedMemSize = 0; // From driver
|
int sharedMemSize = 0; // From driver
|
||||||
void* sharedMemory = nullptr;
|
void* sharedMemory = nullptr;
|
||||||
|
std::string serialFilter;
|
||||||
|
|
||||||
std::atomic<bool> stopRunning(false);
|
std::atomic<bool> stopRunning(false);
|
||||||
|
|
||||||
@@ -85,8 +88,15 @@ public:
|
|||||||
const std::string& getName() const { return name; }
|
const std::string& getName() const { return name; }
|
||||||
uint8_t* getRxBox() { return rxBox; }
|
uint8_t* getRxBox() { return rxBox; }
|
||||||
const uint8_t* getRxBox() const { return rxBox; }
|
const uint8_t* getRxBox() const { return rxBox; }
|
||||||
void addReceivedMessageToQueue(const std::shared_ptr<icsneo::Message>& msg) {
|
void addReceivedMessageToQueue(const std::shared_ptr<icsneo::CANMessage>& msg) {
|
||||||
auto neomessage = icsneo::CreateNeoMessage(msg);
|
const auto neomessageGeneric = icsneo::CreateNeoMessage(msg);
|
||||||
|
if (neomessageGeneric.messageType != neomessagetype_t(icsneo::Message::Type::Frame)) {
|
||||||
|
LOG(LOG_DEBUG, "could not create a neomessage_can_t\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& neomessage = *reinterpret_cast<const neomessage_can_t*>(&neomessageGeneric);
|
||||||
|
|
||||||
size_t bytesNeeded = sizeof(neomessage) + neomessage.length;
|
size_t bytesNeeded = sizeof(neomessage) + neomessage.length;
|
||||||
std::lock_guard<std::mutex> lg(rxBoxLock);
|
std::lock_guard<std::mutex> lg(rxBoxLock);
|
||||||
if(ssize_t((rxBoxCurrentPosition - rxBox) + bytesNeeded) > RX_BOX_SIZE) {
|
if(ssize_t((rxBoxCurrentPosition - rxBox) + bytesNeeded) > RX_BOX_SIZE) {
|
||||||
@@ -187,12 +197,13 @@ void header() {
|
|||||||
|
|
||||||
void usage(std::string executableName) {
|
void usage(std::string executableName) {
|
||||||
std::cerr << "The libicsneo SocketCAN Usermode Daemon\n";
|
std::cerr << "The libicsneo SocketCAN Usermode Daemon\n";
|
||||||
std::cerr << "Copyright Intrepid Control Systems, Inc. 2019\n\n";
|
std::cerr << "Copyright 2019-2020 Intrepid Control Systems, Inc.\n\n";
|
||||||
std::cerr << "Usage: " << executableName << " [option]\n\n";
|
std::cerr << "Usage: " << executableName << " [option]\n\n";
|
||||||
std::cerr << "Options:\n";
|
std::cerr << "Options:\n";
|
||||||
std::cerr << "\t-d, --daemon\t\tRun as a daemon in the background\n";
|
std::cerr << "\t-d, --daemon\t\tRun as a daemon in the background\n";
|
||||||
std::cerr << "\t-h, -?, --help, --usage\t\tShow this help page\n";
|
std::cerr << "\t-h, -?, --help, --usage\t\tShow this help page\n";
|
||||||
std::cerr << "\t --devices\t\tList supported devices\n";
|
std::cerr << "\t --devices\t\tList supported devices\n";
|
||||||
|
std::cerr << "\t --filter <serial>\tOnly connect to devices with serial\n\t\t\t\t\tnumbers starting with this filter\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void terminateSignal(int signal) {
|
void terminateSignal(int signal) {
|
||||||
@@ -215,16 +226,21 @@ void searchForDevices() {
|
|||||||
if(alreadyOpen)
|
if(alreadyOpen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const std::string serial = dev->getSerial();
|
||||||
|
|
||||||
|
// If we have a serial filter, make sure our serial starts with the given filter
|
||||||
|
if(!serialFilter.empty() && serial.rfind(serialFilter, 0) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Now open the device
|
// Now open the device
|
||||||
OpenDevice newDevice(dev);
|
OpenDevice newDevice(dev);
|
||||||
const std::string serial = newDevice.device->getSerial();
|
|
||||||
Lazy<bool> firstTimeFailedToOpen([&serial]() {
|
Lazy<bool> firstTimeFailedToOpen([&serial]() {
|
||||||
return std::find(failedToOpen.begin(), failedToOpen.end(), serial) == failedToOpen.end();
|
return std::find(failedToOpen.begin(), failedToOpen.end(), serial) == failedToOpen.end();
|
||||||
});
|
});
|
||||||
if(!newDevice.device->open() || !newDevice.device->goOnline()) {
|
if(!newDevice.device->open() || !newDevice.device->goOnline()) {
|
||||||
if(firstTimeFailedToOpen) {
|
if(firstTimeFailedToOpen) {
|
||||||
icsneo::APIEvent err = icsneo::GetLastError();
|
const std::string err = icsneo::GetLastError().describe();
|
||||||
LOGF(LOG_INFO, "%s failed to connect. Will keep trying...\n%s\n", newDevice.device->describe().c_str(), err.describe().c_str());
|
LOGF(LOG_INFO, "%s failed to connect. Will keep trying...\n%s\n", newDevice.device->describe().c_str(), err.c_str());
|
||||||
failedToOpen.push_back(serial);
|
failedToOpen.push_back(serial);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -270,10 +286,9 @@ void searchForDevices() {
|
|||||||
|
|
||||||
// Create rx listener
|
// Create rx listener
|
||||||
newDevice.device->addMessageCallback(icsneo::CANMessageCallback([serial](std::shared_ptr<icsneo::Message> message) {
|
newDevice.device->addMessageCallback(icsneo::CANMessageCallback([serial](std::shared_ptr<icsneo::Message> message) {
|
||||||
if(message->transmitted)
|
|
||||||
return;
|
|
||||||
auto canMessage = std::static_pointer_cast<icsneo::CANMessage>(message);
|
auto canMessage = std::static_pointer_cast<icsneo::CANMessage>(message);
|
||||||
const OpenDevice* openDevice = nullptr;
|
const OpenDevice* openDevice = nullptr;
|
||||||
|
std::lock_guard<std::mutex> lg(openDevicesMutex);
|
||||||
for(const auto& dev : openDevices) {
|
for(const auto& dev : openDevices) {
|
||||||
if(dev.device->getSerial() == serial) {
|
if(dev.device->getSerial() == serial) {
|
||||||
openDevice = &dev;
|
openDevice = &dev;
|
||||||
@@ -343,13 +358,8 @@ void deviceSearchThread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
if(argc > 2) {
|
for(int i = 1; i != argc; i++) {
|
||||||
usage(argv[0]);
|
const std::string arg = argv[i];
|
||||||
return EX_USAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc == 2) {
|
|
||||||
const std::string arg = argv[1];
|
|
||||||
if(arg == "-d" || arg == "--daemon") {
|
if(arg == "-d" || arg == "--daemon") {
|
||||||
runningAsDaemon = true;
|
runningAsDaemon = true;
|
||||||
} else if(arg == "-h" || arg == "--help" || arg == "-?" || arg == "--usage") {
|
} else if(arg == "-h" || arg == "--help" || arg == "-?" || arg == "--usage") {
|
||||||
@@ -361,6 +371,9 @@ int main(int argc, char** argv) {
|
|||||||
for(auto& dev : icsneo::GetSupportedDevices())
|
for(auto& dev : icsneo::GetSupportedDevices())
|
||||||
std::cout << '\t' << dev << std::endl;
|
std::cout << '\t' << dev << std::endl;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
} else if(arg == "--filter" && i + 1 <= argc) {
|
||||||
|
serialFilter = argv[++i];
|
||||||
|
transform(serialFilter.begin(), serialFilter.end(), serialFilter.begin(), ::toupper);
|
||||||
} else {
|
} else {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return EX_USAGE;
|
return EX_USAGE;
|
||||||
@@ -476,18 +489,26 @@ int main(int argc, char** argv) {
|
|||||||
// Send!
|
// Send!
|
||||||
uint8_t* currentPosition = GET_TX_BOX(info.tx_box_index);
|
uint8_t* currentPosition = GET_TX_BOX(info.tx_box_index);
|
||||||
while(info.count--) {
|
while(info.count--) {
|
||||||
neomessage_t* msg = reinterpret_cast<neomessage_t*>(currentPosition);
|
neomessage_frame_t* msg = reinterpret_cast<neomessage_frame_t*>(currentPosition);
|
||||||
currentPosition += sizeof(neomessage_t);
|
currentPosition += sizeof(neomessage_frame_t);
|
||||||
msg->data = currentPosition;
|
msg->data = currentPosition;
|
||||||
currentPosition += msg->length;
|
currentPosition += msg->length;
|
||||||
|
|
||||||
|
if(msg->type != neonettype_t(icsneo::Network::Type::CAN)) {
|
||||||
|
LOG(LOG_ERR, "Message dropped, kernel sent a non-CAN message\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool sent = false;
|
bool sent = false;
|
||||||
|
std::lock_guard<std::mutex> lg(openDevicesMutex);
|
||||||
for(auto& dev : openDevices) {
|
for(auto& dev : openDevices) {
|
||||||
for(auto& netifPair : dev.interfaces) {
|
for(auto& netifPair : dev.interfaces) {
|
||||||
if(netifPair.second->getKernelHandle() != msg->netid)
|
if(netifPair.second->getKernelHandle() != msg->netid)
|
||||||
continue;
|
continue;
|
||||||
msg->netid = static_cast<uint16_t>(netifPair.first);
|
msg->netid = static_cast<uint16_t>(netifPair.first);
|
||||||
auto tx = icsneo::CreateMessageFromNeoMessage(msg);
|
auto txMsg = icsneo::CreateMessageFromNeoMessage(reinterpret_cast<neomessage_t*>(msg));
|
||||||
if(!dev.device->transmit(tx))
|
auto tx = std::dynamic_pointer_cast<icsneo::Frame>(txMsg);
|
||||||
|
if(!tx || !dev.device->transmit(tx))
|
||||||
break;
|
break;
|
||||||
sent = true;
|
sent = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Vendored
+1
-1
Submodule third-party/libicsneo updated: f16ee630ee...0ff12300f3
Reference in New Issue
Block a user