mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Fix FlexRay extension bugs and implement FlexRay example
This commit is contained in:
@@ -10,6 +10,7 @@ option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE "Build the FlexRay example." ON)
|
||||
|
||||
if(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE)
|
||||
add_subdirectory(c/interactive)
|
||||
@@ -58,3 +59,7 @@ endif()
|
||||
if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE)
|
||||
add_subdirectory(cpp/apperror)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE)
|
||||
add_subdirectory(cpp/flexray)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
add_executable(libicsneocpp-flexray-example src/FlexRayExample.cpp)
|
||||
target_link_libraries(libicsneocpp-flexray-example icsneocpp)
|
||||
@@ -0,0 +1,204 @@
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include "icsneo/icsneocpp.h"
|
||||
#include "icsneo/device/extensions/flexray/cluster.h"
|
||||
|
||||
/* Modifiable Configuration Variables*/
|
||||
|
||||
static size_t NumMessages = 300;
|
||||
static size_t FramePayloadSize = 134;
|
||||
static uint16_t SlotOne = 1;
|
||||
static uint16_t SlotTwo = 3;
|
||||
static bool SuppressRxTxDebugMessages = true;
|
||||
|
||||
static const icsneo::FlexRay::Controller::Configuration DefaultControllerConfig {
|
||||
160, // uint16_t AcceptStartupRangeMicroticks INIT(0); // pdAcceptedStartupRange
|
||||
true, // bool AllowHaltDueToClock INIT(false); // pAllowHaltDueToClock
|
||||
|
||||
15, // uint8_t AllowPassiveToActiveCyclePairs INIT(0); // pAllowPassiveToActive
|
||||
|
||||
2, // uint8_t ClusterDriftDamping INIT(0); // pClusterDriftDamping
|
||||
|
||||
true, // bool ChannelA INIT(false); // pChannels
|
||||
true, // bool ChannelB INIT(false); // pChannels
|
||||
|
||||
56, // uint8_t DecodingCorrectionMicroticks INIT(0); // pDecodingCorrection
|
||||
28, // uint8_t DelayCompensationAMicroticks INIT(0); // pDelayCompensation[A]
|
||||
28, // uint8_t DelayCompensationBMicroticks INIT(0); // pDelayCompensation[B]
|
||||
0, // uint8_t ExternOffsetCorrectionControl INIT(0); // pExternOffsetControl
|
||||
0, // uint8_t ExternRateCorrectionControl INIT(0); // pExternRateControl
|
||||
0, // uint8_t ExternOffsetCorrectionMicroticks INIT(0); // pExternOffsetCorrection
|
||||
0, // uint8_t ExternRateCorrectionMicroticks INIT(0); // pExternRateCorrection
|
||||
|
||||
0, // uint16_t KeySlotID INIT(0);
|
||||
|
||||
false, // bool KeySlotOnlyEnabled INIT(false); // pSingleSlotEnabled (TSM)
|
||||
true, // bool KeySlotUsedForStartup INIT(false); // pKeySlotUsedForStartup (TXST)
|
||||
true, // bool KeySlotUsedForSync INIT(false); // pKeySlotUsedForSync (TXSY)
|
||||
|
||||
226, // uint16_t LatestTxMinislot INIT(0); // pLatestTx
|
||||
401202, // uint32_t ListenTimeout INIT(0); // pdListenTimeout
|
||||
|
||||
7, // uint8_t MacroInitialOffsetA INIT(0); // pMacroInitialOffset[A], Valid 2..72
|
||||
7, // uint8_t MacroInitialOffsetB INIT(0); // pMacroInitialOffset[B], Valid 2..72
|
||||
|
||||
36, // uint8_t MicroInitialOffsetA INIT(0); // pMicroInitialOffset[A], Valid 0..240
|
||||
36, // uint8_t MicroInitialOffsetB INIT(0); // pMicroInitialOffset[B], Valid 0..240
|
||||
|
||||
200000, // uint32_t MicroPerCycle INIT(0); // pMicroPerCycle
|
||||
|
||||
false, // bool MTSOnA INIT(false);
|
||||
false, // bool MTSOnB INIT(false);
|
||||
|
||||
189, // uint16_t OffsetCorrectionOutMicroticks INIT(0); // pOffsetCorrectionOut
|
||||
601, // uint16_t RateCorrectionOutMicroticks INIT(0); // pdMaxDrift and pRateCorrectionOut
|
||||
|
||||
0, // uint16_t SecondKeySlotID INIT(0);
|
||||
false, // bool TwoKeySlotMode INIT(false);
|
||||
|
||||
55, // uint8_t WakeupPattern INIT(0);
|
||||
false, // bool WakeupOnChannelB INIT(false); // pWakeupChannel
|
||||
};
|
||||
|
||||
namespace Cluster = icsneo::FlexRay::Cluster;
|
||||
|
||||
static const Cluster::Configuration DefaultClusterConfig {
|
||||
Cluster::SpeedType::FLEXRAY_BAUDRATE_10M, // neoflexray_speed_t Speed INIT(FLEXRAY_BAUDRATE_10M /* = 0 */); // gdSampleClockPeriod, pSamplesPerMicrotick, Baud Rate Prescaler
|
||||
Cluster::SPPType::FLEXRAY_SPP_5, // neoflexray_spp_t StrobePointPosition INIT(FLEXRAY_SPP_5 /* = 0 */);
|
||||
|
||||
4, // uint8_t ActionPointOffset INIT(0); // gdActionPointOffset
|
||||
64, // uint8_t CASRxLowMax INIT(0); // gdCASRxLowMax
|
||||
8, // uint8_t ColdStartAttempts INIT(0); // gColdStartAttempts
|
||||
5000, // uint16_t CycleDurationMicroSec INIT(0); // gdCycle
|
||||
1, // uint8_t DynamicSlotIdlePhaseMinislots INIT(0); // gdDynamicSlotIdlePhase, In Minislot increments [0..2]
|
||||
4, // uint8_t ListenNoiseMacroticks INIT(0); // gListenNoise
|
||||
5000, // uint16_t MacroticksPerCycle INIT(0); // gMacroPerCycle
|
||||
1, // uint8_t MacrotickDurationMicroSec INIT(0); // gdMacroTick
|
||||
2, // uint8_t MaxWithoutClockCorrectionFatal INIT(0); // gMaxWithoutClockCorrectionFatal
|
||||
2, // uint8_t MaxWithoutClockCorrectionPassive INIT(0); // gMaxWithoutClockCorrectionPassive
|
||||
4, // uint8_t MinislotActionPointOffsetMacroticks INIT(0); // gdMinislotActionPointOffset
|
||||
10, // uint32_t MinislotDurationMacroticks INIT(0); // gdMinislot
|
||||
40, // uint32_t NetworkIdleTimeMacroticks INIT(0); // gdNIT
|
||||
1, // uint8_t NetworkManagementVectorLengthBytes INIT(0); // gNetworkManagementVectorLength
|
||||
0, // uint32_t NumberOfMinislots INIT(0); // gNumberOfMinislots
|
||||
32, // uint16_t NumberOfStaticSlots INIT(0); // gdNumberOfStaticSlots
|
||||
4991, // uint32_t OffsetCorrectionStartMacroticks INIT(0); // gOffsetCorrectionStart
|
||||
67, // uint8_t PayloadLengthOfStaticSlotInWords INIT(0); // gPayloadLengthStatic
|
||||
|
||||
155, // uint16_t StaticSlotMacroticks INIT(0); // gdStaticSlot
|
||||
0, // uint32_t SymbolWindowMacroticks INIT(0); // gdSymbolWindow
|
||||
0, // uint32_t SymbolWindowActionPointOffsetMacroticks INIT(0);
|
||||
15, // uint16_t SyncFrameIDCountMax INIT(0); // gSyncNodeMax
|
||||
|
||||
11, // uint8_t TransmissionStartSequenceDurationBits INIT(0); // gdTSSTransmitter
|
||||
40, // uint8_t WakeupRxIdleBits INIT(0); // gdWakeupSymbolRxIdle
|
||||
40, // uint8_t WakeupRxLowBits INIT(0); // gdWakeupSymbolRxLow
|
||||
301, // uint16_t WakeupRxWindowBits INIT(0); // gdWakeupSymbolRxWindow
|
||||
60, // uint8_t WakeupTxActiveBits INIT(0); // gdWakeupSymbolTxLow (active = low here)
|
||||
180, // uint8_t WakeupTxIdleBits INIT(0); // gdWakeupSymbolTxIdle
|
||||
};
|
||||
|
||||
static std::condition_variable cv;
|
||||
static std::mutex msgRcvdMutex;
|
||||
|
||||
void configureFlexRayDevice(std::shared_ptr<icsneo::Device> device) {
|
||||
auto controllers = device->getFlexRayControllers();
|
||||
for (uint16_t i = 0; i < controllers.size(); i++) {
|
||||
auto controller = controllers[i];
|
||||
icsneo::FlexRay::Cluster::Configuration clusterConfig = DefaultClusterConfig;
|
||||
icsneo::FlexRay::Controller::Configuration controllerConfig = DefaultControllerConfig;
|
||||
controller->setAllowColdstart(true);
|
||||
controllerConfig.KeySlotID = (i == 0) ? SlotOne : SlotTwo;
|
||||
controller->setConfiguration(clusterConfig, controllerConfig);
|
||||
controller->setStartWhenGoingOnline(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> makeDummyFlexRayMessages(size_t msgCount, size_t msgLen) {
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> messages;
|
||||
messages.reserve(msgCount);
|
||||
std::random_device rd;
|
||||
std::mt19937 engine(rd());
|
||||
std::uniform_int_distribution<unsigned short> dist(0, 255);
|
||||
for (size_t i = 0; i < msgCount; i++) {
|
||||
auto msg = std::make_shared<icsneo::FlexRayMessage>();
|
||||
msg->network = icsneo::Network::NetID::FLEXRAY_01;
|
||||
msg->cycleRepetition = 1;
|
||||
msg->channel = icsneo::FlexRay::Channel::AB;
|
||||
msg->data.reserve(msgLen);
|
||||
for (size_t j = 0; j < msgLen; j++) {
|
||||
msg->data.push_back(static_cast<uint8_t>(dist(engine)));
|
||||
}
|
||||
msg->slotid = (i % 2 == 0) ? SlotOne : SlotTwo;
|
||||
messages.push_back(msg);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto devices = icsneo::FindAllDevices();
|
||||
std::shared_ptr<icsneo::Device> flexrayDevice = nullptr;
|
||||
for (auto&& device : devices) {
|
||||
if (device->getExtension("FlexRay")) {
|
||||
flexrayDevice = device;
|
||||
}
|
||||
}
|
||||
|
||||
if (flexrayDevice) {
|
||||
std::cout << "Found device " << flexrayDevice->getProductName() << " " << flexrayDevice->getSerial() << " which supports FlexRay." << std::endl;
|
||||
auto&& controllers = flexrayDevice->getFlexRayControllers();
|
||||
if (controllers.size() > 0) {
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> messages;
|
||||
size_t currentMessage = 0;
|
||||
auto filter = std::make_shared<icsneo::MessageFilter>(icsneo::Network::NetID::FLEXRAY_01);
|
||||
auto rxCallback = [&messages, ¤tMessage](std::shared_ptr<icsneo::Message> message) -> void {
|
||||
std::unique_lock lk(msgRcvdMutex);
|
||||
auto frmsg = std::static_pointer_cast<icsneo::FlexRayMessage>(message);
|
||||
if (currentMessage < messages.size() && frmsg->data.size() > 1 && frmsg->data == messages[currentMessage]->data) {
|
||||
if (!SuppressRxTxDebugMessages) {
|
||||
std::cout << "Message Number " << currentMessage + 1 << " received." << std::endl;
|
||||
}
|
||||
currentMessage++;
|
||||
lk.unlock();
|
||||
cv.notify_all();
|
||||
}
|
||||
};
|
||||
|
||||
auto cb = std::make_shared<icsneo::MessageCallback>(rxCallback, filter);
|
||||
auto cbId = flexrayDevice->addMessageCallback(cb);
|
||||
messages = makeDummyFlexRayMessages(NumMessages, FramePayloadSize);
|
||||
configureFlexRayDevice(flexrayDevice);
|
||||
if (!flexrayDevice->open()) {
|
||||
std::cerr << "Device open failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (!flexrayDevice->goOnline()) {
|
||||
std::cerr << "Device go online failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "Transmitting " << NumMessages << " FlexRay frames." << std::endl;
|
||||
for (auto msg : messages) {
|
||||
std::unique_lock lk(msgRcvdMutex);
|
||||
if (!flexrayDevice->transmit(msg)) {
|
||||
std::cerr << "Failed to transmit message." << std::endl;
|
||||
return -1;
|
||||
} else if (!SuppressRxTxDebugMessages) {
|
||||
std::cout << "Message Number " << currentMessage + 1 << " transmitted." << std::endl;
|
||||
}
|
||||
|
||||
cv.wait(lk);
|
||||
lk.unlock();
|
||||
}
|
||||
std::cout << "All transmitted frames received." << std::endl;
|
||||
flexrayDevice->removeMessageCallback(cbId);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Unable to find a device which supports FlexRay." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << "Finished." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user