AGHAF  4.5.1
Annecy electronique Generic Hardware Access Framework
LIN_EventTriggered/main.cpp

Event Triggered example

The event-triggered frame 0x10 is associatted with unconditional frames 0x11 from slave 1 and 0x12 from slave 2.
Schedule table contains event-triggered frame 0x10.
The collision resolving schedule table contains unconditionnal frames 0x11 and 0x12.

#include <vector>
#include <iostream>
#include <thread>
#include <array>
#include <string>
#define AGHAF_DYNAMIC_LIBRARY_INIT
#include <aghaf.h>
#include <iostream>
#include <iomanip>
void onLinMasterTx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
if (data != nullptr) {
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
} else {
std::cout << "no data" << std::endl;
}
}
void onLinMasterRx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
}
void onLinMasterError(
uint64_t timestamp,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "error: " << static_cast<int>(error) << std::endl;
}
void onLinSlave1Tx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
if (data != nullptr) {
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
} else {
std::cout << "no data" << std::endl;
}
}
void onLinSlave1Rx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
}
void onLinSlave1Error(
uint64_t timestamp,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "error: " << static_cast<int>(error) << std::endl;
}
void onLinSlave2Tx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
if (data != nullptr) {
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
} else {
std::cout << "no data" << std::endl;
}
}
void onLinSlave2Rx(
uint64_t timestamp,
uint8_t fid,
uint8_t datalen,
uint8_t const* data,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "datalen: " << static_cast<int>(datalen) << std::endl;
std::cout << "fid: " << static_cast<int>(fid) << std::endl;
std::cout << "0x";
for (uint8_t i = 0; i < datalen; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
}
std::cout << std::endl;
}
void onLinSlave2Error(
uint64_t timestamp,
void *userContext)
{
(void) timestamp;
(void) userContext;
std::cout << __FUNCTION__ << std::endl;
std::cout << "error: " << static_cast<int>(error) << std::endl;
}
int main()
{
#ifdef _WIN32
AGHAF_loadLibrary(AGHAF_DEFAULT_FILENAME);
#endif
uint32_t count = AGHAF_getDeviceCount();
if (count > 0) {
AGHAF_DeviceInfo *devicesInfo = nullptr;
uint32_t deviceInfoNumber = 0;
AGHAF_getDeviceList(&devicesInfo, &deviceInfoNumber);
if (deviceInfoNumber > 2) {
int serialNumber1 = std::stoi(devicesInfo[0].serialNo);
int serialNumber2 = std::stoi(devicesInfo[1].serialNo);
int serialNumber3 = std::stoi(devicesInfo[2].serialNo);
AGHAF_Device deviceMaster = nullptr;
AGHAF_Device deviceSlave1 = nullptr;
AGHAF_Device deviceSlave2 = nullptr;
if (serialNumber1 > serialNumber2) {
if (serialNumber1 > serialNumber3) {
deviceMaster = AGHAF_getDeviceBySN(
devicesInfo[0].productNo,
devicesInfo[0].serialNo);
deviceSlave1 = AGHAF_getDeviceBySN(
devicesInfo[1].productNo,
devicesInfo[1].serialNo);
deviceSlave2 = AGHAF_getDeviceBySN(
devicesInfo[2].productNo,
devicesInfo[2].serialNo);
} else {
deviceMaster = AGHAF_getDeviceBySN(
devicesInfo[2].productNo,
devicesInfo[2].serialNo);
deviceSlave1 = AGHAF_getDeviceBySN(
devicesInfo[0].productNo,
devicesInfo[0].serialNo);
deviceSlave2 = AGHAF_getDeviceBySN(
devicesInfo[1].productNo,
devicesInfo[1].serialNo);
}
} else {
if (serialNumber2 > serialNumber3) {
deviceMaster = AGHAF_getDeviceBySN(
devicesInfo[1].productNo,
devicesInfo[1].serialNo);
deviceSlave1 = AGHAF_getDeviceBySN(
devicesInfo[0].productNo,
devicesInfo[0].serialNo);
deviceSlave2 = AGHAF_getDeviceBySN(
devicesInfo[2].productNo,
devicesInfo[2].serialNo);
} else {
deviceMaster = AGHAF_getDeviceBySN(
devicesInfo[2].productNo,
devicesInfo[2].serialNo);
deviceSlave1 = AGHAF_getDeviceBySN(
devicesInfo[0].productNo,
devicesInfo[0].serialNo);
deviceSlave2 = AGHAF_getDeviceBySN(
devicesInfo[1].productNo,
devicesInfo[1].serialNo);
}
}
AGHAF_openDevice(deviceMaster);
AGHAF_openDevice(deviceSlave1);
AGHAF_openDevice(deviceSlave2);
uint8_t linCount1 = AGHAF_LIN_getCount(deviceMaster);
uint8_t linCount2 = AGHAF_LIN_getCount(deviceSlave1);
uint8_t linCount3 = AGHAF_LIN_getCount(deviceSlave2);
if (linCount1 > 0 && linCount2 > 0 && linCount3 > 0) {
AGHAF_LIN linMaster = AGHAF_LIN_get(deviceMaster, 0);
AGHAF_LIN_setOnMessageRxCallback(linMaster, &onLinMasterRx, nullptr);
AGHAF_LIN_setOnMessageTxCallback(linMaster, &onLinMasterTx, nullptr);
AGHAF_LIN_setOnErrorCallback(linMaster, &onLinMasterError, nullptr);
AGHAF_LIN_setParam(linMaster,
19200);
AGHAF_LIN_setParam(linMaster,
AGHAF_LIN linSlave1 = AGHAF_LIN_get(deviceSlave1, 0);
AGHAF_LIN_setOnMessageRxCallback(linSlave1, &onLinSlave1Rx, nullptr);
AGHAF_LIN_setOnMessageTxCallback(linSlave1, &onLinSlave1Tx, nullptr);
AGHAF_LIN_setOnErrorCallback(linSlave1, &onLinSlave1Error, nullptr);
AGHAF_LIN_setParam(linSlave1,
19200);
AGHAF_LIN_setParam(linSlave1,
AGHAF_LIN linSlave2 = AGHAF_LIN_get(deviceSlave2, 0);
AGHAF_LIN_setOnMessageRxCallback(linSlave2, &onLinSlave2Rx, nullptr);
AGHAF_LIN_setOnMessageTxCallback(linSlave2, &onLinSlave2Tx, nullptr);
AGHAF_LIN_setOnErrorCallback(linSlave2, &onLinSlave2Error, nullptr);
AGHAF_LIN_setParam(linSlave2,
19200);
AGHAF_LIN_setParam(linSlave2,
std::array<uint8_t, 1> event1 = { 0x12 };
std::array<uint8_t, 2> frame1 = { 0x00, 0x85 };
std::array<uint8_t, 1> event2 = { 0x11 };
std::array<uint8_t, 2> frame2 = { 0x00, 0xF0 };
AGHAF_LIN_SCHEDULE_addEventTriggered(linMaster, 0, 2, 0x10, 1);
AGHAF_LIN_SCHEDULE_addUnconditional(linMaster, 1, 0x12, 2);
AGHAF_LIN_SCHEDULE_addUnconditional(linMaster, 1, 0x11, 2);
linMaster,
0x10,
0,
static_cast<uint8_t>(frame2.size()),
nullptr);
linMaster,
0x11,
0,
static_cast<uint8_t>(frame2.size()),
nullptr);
linMaster,
0x12,
0,
static_cast<uint8_t>(frame1.size()),
nullptr);
linSlave1,
0x10,
static_cast<uint8_t>(event2.size()),
event2.data());
linSlave1,
0x11,
static_cast<uint8_t>(frame2.size()),
frame2.data());
linSlave2,
0x10,
static_cast<uint8_t>(event1.size()),
event1.data());
linSlave2,
0x12,
static_cast<uint8_t>(frame1.size()),
frame1.data());
AGHAF_LIN_activate(linMaster);
AGHAF_LIN_activate(linSlave1);
AGHAF_LIN_activate(linSlave2);
AGHAF_LIN_SCHEDULE_start(linMaster, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
frame1[1] = 0xC0;
AGHAF_LIN_updateFrame(linSlave2, 0x12, static_cast<uint8_t>(frame1.size()), frame1.data());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
AGHAF_closeDevice(deviceMaster);
AGHAF_closeDevice(deviceSlave1);
AGHAF_closeDevice(deviceSlave2);
}
AGHAF_freeDeviceList(devicesInfo);
}
#ifdef _WIN32
AGHAF_unloadLibrary();
#endif
return 0;
}
AGHAF_LIN_Error
enumerator to describe the error on the bus
Definition: aghaf_lin_enums.h:27
#define AGHAF_LIN_PUBLISH_AUTO_PID
Definition: aghaf_lin_enums.h:18
#define AGHAF_LIN_PUBLISH_EVT_TRIG
Definition: aghaf_lin_enums.h:21
@ AGHAF_LIN_MODE_MASTER
LIN master.
Definition: aghaf_lin_enums.h:63
@ AGHAF_LIN_MODE_SLAVE
LIN slave.
Definition: aghaf_lin_enums.h:62
@ AGHAF_LIN_FRAME_KIND_SUBSCRIBE
Receive the response.
Definition: aghaf_lin_enums.h:70
@ AGHAF_LIN_FRAME_KIND_PUBLISH
Transmits the response.
Definition: aghaf_lin_enums.h:69
@ AGHAF_LIN_SCHEDULE_KIND_LOOP
Schedule table run in loop.
Definition: aghaf_lin_enums.h:76
@ AGHAF_LIN_SCHEDULE_KIND_ONCE
Schedule table run once.
Definition: aghaf_lin_enums.h:75
@ AGHAF_LIN_PARAM_BAUDRATE
Definition: aghaf_lin_enums.h:100
@ AGHAF_LIN_PARAM_MODE
Definition: aghaf_lin_enums.h:94
void AGHAF_LIN_setOnMessageTxCallback(AGHAF_LIN lin, AGHAF_LIN_onMessageTx callback, void *userContext)
Set the callback called on tx event.
Definition: aghaf_lin.cpp:15
AGHAF_Status AGHAF_LIN_SCHEDULE_configure(AGHAF_LIN lin, uint8_t scheduleIndex, AGHAF_LIN_ScheduleKind kind)
AGHAF_LIN_SCHEDULE_configure.
Definition: aghaf_lin.cpp:310
void * AGHAF_LIN
handle on a LIN bus
Definition: aghaf_lin.h:21
AGHAF_Status AGHAF_LIN_activate(AGHAF_LIN lin)
Start the communication with the LIN.
Definition: aghaf_lin.cpp:108
AGHAF_Status AGHAF_LIN_deactivate(AGHAF_LIN lin)
Stop the communication with the LIN.
Definition: aghaf_lin.cpp:119
AGHAF_Status AGHAF_LIN_SCHEDULE_stop(AGHAF_LIN lin)
Stop the schedule currently executed on the LIN.
Definition: aghaf_lin.cpp:334
AGHAF_Status AGHAF_LIN_SCHEDULE_addUnconditional(AGHAF_LIN lin, uint8_t scheduleIndex, uint8_t fid, uint8_t timeBaseCount)
Add an unconditionale frame in a schedule.
Definition: aghaf_lin.cpp:254
AGHAF_Status AGHAF_LIN_configureFrame(AGHAF_LIN lin, uint8_t fid, AGHAF_LIN_FrameKind kind, uint8_t publishFlags, uint8_t dataLen, uint8_t const *initialData)
Configure the frame associated with the frame identifier.
Definition: aghaf_lin.cpp:211
void AGHAF_LIN_setOnMessageRxCallback(AGHAF_LIN lin, AGHAF_LIN_onMessageRx callback, void *userContext)
Set the callback called on rx event.
Definition: aghaf_lin.cpp:27
AGHAF_LIN AGHAF_LIN_get(AGHAF_Device device, uint8_t index)
Return the LIN bus at the index specified.
Definition: aghaf_lin.cpp:75
AGHAF_Status AGHAF_LIN_SCHEDULE_start(AGHAF_LIN lin, uint8_t scheduleIndex)
Start a schedule.
Definition: aghaf_lin.cpp:323
AGHAF_Status AGHAF_LIN_setParam(AGHAF_LIN lin, AGHAF_LIN_Param param, uint32_t value)
Set a parameter from a LIN.
Definition: aghaf_lin.cpp:160
AGHAF_Status AGHAF_LIN_updateFrame(AGHAF_LIN lin, uint8_t fid, uint8_t dataLen, uint8_t const *data)
Update the datas associated to a frame identifier.
Definition: aghaf_lin.cpp:190
void AGHAF_LIN_setOnErrorCallback(AGHAF_LIN lin, AGHAF_LIN_onError callback, void *userContext)
Set the callback called on an error event.
Definition: aghaf_lin.cpp:39
AGHAF_Status AGHAF_LIN_SCHEDULE_addEventTriggered(AGHAF_LIN lin, uint8_t scheduleIndex, uint8_t timeBaseCount, uint8_t eventTriggerId, uint8_t collisionTable)
Add an event triggered in a schedule.
Definition: aghaf_lin.cpp:284
uint8_t AGHAF_LIN_getCount(AGHAF_Device device)
Return the number of LINs available on a device.
Definition: aghaf_lin.cpp:97
uint32_t AGHAF_getDeviceCount()
Return the number of devices onnected.
Definition: aghaf_global.cpp:111
AGHAF_Status AGHAF_getDeviceList(AGHAF_DeviceInfo **devices, uint32_t *size)
Provide the list of devices connected.
Definition: aghaf_global.cpp:123
AGHAF_Device AGHAF_getDeviceBySN(const char *productNumber, const char *serialNumber)
Return the handle on the specified device.
Definition: aghaf_global.cpp:156
void AGHAF_freeDeviceList(AGHAF_DeviceInfo *devices)
Free the memory allocated with AGHAF_getDeviceList.
Definition: aghaf_global.cpp:135
void * AGHAF_Device
handle on an exxotest device
Definition: aghaf_global.h:145
AGHAF_Status AGHAF_closeDevice(AGHAF_Device device)
close the device
Definition: aghaf_global.cpp:266
AGHAF_Status AGHAF_openDevice(AGHAF_Device device)
Open a device.
Definition: aghaf_global.cpp:255
structure containing the informtions about a device
Definition: aghaf_global.h:188