50 struct timespec StartingTime;
56 #define TIMER_PS_1NS (1UL) 57 #define TIMER_PS_10NS (10UL) 58 #define TIMER_PS_100NS (100UL) 59 #define TIMER_PS_1US (1000UL) 60 #define TIMER_PS_10US (10000UL) 61 #define TIMER_PS_100US (100000UL) 62 #define TIMER_PS_1MS (1000000UL) 63 #define TIMER_PS_10MS (10000000UL) 64 #define TIMER_PS_100MS (100000000UL) 65 #define TIMER_PS_1S (1000000000UL) 68 #if XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_1NS 69 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_1NS) 70 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_10NS 71 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_10NS) 72 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_100NS 73 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_100NS) 74 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_1US 75 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_1US) 76 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_10US 77 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_10US= 78 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_100US 79 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_100US) 80 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_1MS 81 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_1MS) 82 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_10MS 83 #define XCP_HW_TIMER_PRESCALER (TIMER_PS_10MS) 84 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_100MS 85 #define XCP_HW_TIMER_PRESCALRE (TIMER_PS_100MS) 86 #elif XCP_DAQ_TIMESTAMP_UNIT == XCP_DAQ_TIMESTAMP_UNIT_1S 87 #define XCP_HW_TIMER_PRESCALRE (TIMER_PS_1S) 89 #error Timestamp-unit not supported. 90 #endif // XCP_DAQ_TIMESTAMP_UNIT 92 #define TIMER_MASK_1 (0x000000FFUL) 93 #define TIMER_MASK_2 (0x0000FFFFUL) 94 #define TIMER_MASK_4 (0xFFFFFFFFUL) 101 static void XcpHw_InitLocks(
void);
102 static uint64_t XcpHw_GetElapsedTime(uint32_t prescaler);
103 static void XcpHw_DeinitLocks();
104 static struct timespec Timespec_Diff(struct timespec start, struct timespec end);
105 static void InitTUI(
void);
106 static void DeinitTUI(
void);
112 void *XcpHw_MainFunction();
114 bool XcpDaq_QueueEmpty(
void);
115 bool XcpDaq_QueueDequeue(uint16_t *len, uint8_t *data);
122 pthread_t XcpHw_ThreadID[4];
127 #define XCPHW_APPLICATION_STATES (32) 130 volatile uint8_t counter[XCPHW_APPLICATION_STATES];
137 pthread_mutex_t XcpHw_Locks[XCP_HW_LOCK_COUNT];
138 static struct timespec XcpHw_TimerResolution = {0};
139 static timer_t XcpHw_AppMsTimer;
140 static unsigned long long XcpHw_FreeRunningCounter = 0ULL;
142 static pthread_cond_t XcpHw_TransmissionEvent;
143 static pthread_mutex_t XcpHw_TransmissionMutex;
149 static void termination_handler(
int sig) {
150 printf(
"Terminating due to ");
174 printf(
"Signal: %u", sig);
180 static void handler(
int sig, siginfo_t *si,
void *uc) {
193 void XcpHw_Init(
void) {
195 struct sigevent sev = {0};
197 struct itimerspec its = {0};
198 long long freq_nanosecs = 1000 * 1000 * 1000LL;
200 struct sigaction sa = {0};
202 XCP_UNREFERENCED_PARAMETER(timerid);
203 XCP_UNREFERENCED_PARAMETER(status);
205 signal(SIGKILL, termination_handler);
206 signal(SIGSTOP, termination_handler);
207 signal(SIGQUIT, termination_handler);
208 signal(SIGILL, termination_handler);
209 signal(SIGTRAP, termination_handler);
210 signal(SIGABRT, termination_handler);
211 signal(SIGSEGV, termination_handler);
213 XcpHw_FreeRunningCounter = 0ULL;
215 if (clock_getres(CLOCK_MONOTONIC, &XcpHw_TimerResolution) == -1) {
216 XcpHw_ErrorMsg(
"XcpHw_Init::clock_getres()", errno);
219 if (clock_gettime(CLOCK_MONOTONIC, &HwState.StartingTime) == -1) {
220 XcpHw_ErrorMsg(
"XcpHw_Init::clock_gettime()", errno);
224 _setmode(_fileno(stdout), _O_WTEXT);
225 _setmode(_fileno(stdout), _O_U8TEXT);
230 sa.sa_flags = SA_SIGINFO;
231 sa.sa_sigaction = handler;
232 sigemptyset(&sa.sa_mask);
233 if (sigaction(SIG, &sa, NULL) == -1) {
234 XcpHw_ErrorMsg(
"XcpHw_Init::sigaction()", errno);
240 sigaddset(&mask, SIG);
241 if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) {
242 XcpHw_ErrorMsg(
"XcpHw_Init::sigprocmask()", errno);
246 sev.sigev_notify = SIGEV_SIGNAL;
247 sev.sigev_signo = SIG;
248 sev.sigev_value.sival_ptr = &XcpHw_AppMsTimer;
250 if (timer_create(CLOCK_MONOTONIC, &sev, &XcpHw_AppMsTimer) == -1) {
251 XcpHw_ErrorMsg(
"XcpHw_Init::timer_create()", errno);
255 its.it_value.tv_sec = freq_nanosecs / 1000000000;
256 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
257 its.it_interval.tv_sec = its.it_value.tv_sec;
258 its.it_interval.tv_nsec = its.it_value.tv_nsec;
259 if (timer_settime(XcpHw_AppMsTimer, 0, &its, NULL) == -1) {
260 XcpHw_ErrorMsg(
"XcpHw_Init::timer_settime()", errno);
263 if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
264 XcpHw_ErrorMsg(
"XcpHw_Init::sigprocmask()", errno);
267 pthread_cond_init(&XcpHw_TransmissionEvent, NULL);
268 pthread_mutex_init(&XcpHw_TransmissionMutex, NULL);
271 void XcpHw_Deinit(
void) {
273 pthread_cond_destroy(&XcpHw_TransmissionEvent);
274 pthread_cond_destroy(&XcpHw_TransmissionEvent);
275 pthread_mutex_destroy(&XcpHw_TransmissionMutex);
278 static struct timespec Timespec_Diff(struct timespec start, struct timespec end) {
279 struct timespec temp;
281 if ((end.tv_nsec - start.tv_nsec) < 0) {
282 temp.tv_sec = end.tv_sec - start.tv_sec - 1;
283 temp.tv_nsec = 1000000000L + end.tv_nsec - start.tv_nsec;
285 temp.tv_sec = end.tv_sec - start.tv_sec;
286 temp.tv_nsec = end.tv_nsec - start.tv_nsec;
292 static uint64_t XcpHw_GetElapsedTime(uint32_t prescaler)
295 struct timespec now = {0};
296 struct timespec dt = {0};
297 uint64_t timestamp = 0ULL;
299 if (clock_gettime(CLOCK_MONOTONIC_RAW, &now) == -1) {
300 XcpHw_ErrorMsg(
"XcpHw_Init::clock_getres()", errno);
302 dt = Timespec_Diff(HwState.StartingTime, now);
303 XcpHw_FreeRunningCounter =
304 ((
unsigned long long)(dt.tv_sec) * (
unsigned long long)1000 * 1000 * 1000) + ((
unsigned long long)dt.tv_nsec);
305 timestamp = XcpHw_FreeRunningCounter / prescaler;
310 uint32_t XcpHw_GetTimerCounter(
void) {
311 uint64_t timestamp = XcpHw_GetElapsedTime(XCP_HW_TIMER_PRESCALER);
313 timestamp = XcpHw_FreeRunningCounter % UINT_MAX;
315 #if XCP_DAQ_TIMESTAMP_SIZE == XCP_DAQ_TIMESTAMP_SIZE_1 316 timestamp &= TIMER_MASK_1;
317 #elif XCP_DAQ_TIMESTAMP_SIZE == XCP_DAQ_TIMESTAMP_SIZE_2 318 timestamp &= TIMER_MASK_2;
319 #elif XCP_DAQ_TIMESTAMP_SIZE == XCP_DAQ_TIMESTAMP_SIZE_4 320 timestamp &= TIMER_MASK_4;
322 #error Timestamp-size not supported. 323 #endif // XCP_DAQ_TIMESTAMP_SIZE 325 return (uint32_t)timestamp;
329 uint32_t XcpHw_GetTimerCounterMS(
void) {
330 uint64_t timestamp = XcpHw_GetElapsedTime(TIMER_PS_1MS);
332 return (uint32_t)timestamp & TIMER_MASK_4;
336 void XcpHw_TransmitDtos(
void) {
338 uint8_t data[XCP_MAX_DTO + XCP_TRANSPORT_LAYER_BUFFER_OFFSET];
339 uint8_t *dataOut = Xcp_GetDtoOutPtr();
341 while (!XcpDaq_QueueEmpty()) {
342 XcpDaq_QueueDequeue(&len, dataOut);
344 Xcp_SetDtoOutLen(len);
349 static void XcpHw_InitLocks(
void) {
350 uint8_t idx = UINT8(0);
352 for (idx = UINT8(0); idx < XCP_HW_LOCK_COUNT; ++idx) {
353 pthread_mutex_init(&XcpHw_Locks[idx], NULL);
357 static void XcpHw_DeinitLocks(
void) {
358 uint8_t idx = UINT8(0);
360 for (idx = UINT8(0); idx < XCP_HW_LOCK_COUNT; ++idx) {
361 pthread_mutex_destroy(&XcpHw_Locks[idx]);
365 void XcpHw_AcquireLock(uint8_t lockIdx) {
366 if (lockIdx >= XCP_HW_LOCK_COUNT) {
369 pthread_mutex_lock(&XcpHw_Locks[lockIdx]);
372 void XcpHw_ReleaseLock(uint8_t lockIdx) {
373 if (lockIdx >= XCP_HW_LOCK_COUNT) {
376 pthread_mutex_unlock(&XcpHw_Locks[lockIdx]);
379 void XcpHw_SignalTransmitRequest(
void) {
380 pthread_mutex_lock(&XcpHw_TransmissionMutex);
381 pthread_cond_signal(&XcpHw_TransmissionEvent);
384 void XcpHw_WaitTransmitRequest(
void) { pthread_cond_wait(&XcpHw_TransmissionEvent, &XcpHw_TransmissionMutex); }
386 void XcpHw_ErrorMsg(
char *
const fun,
int errorCode) { fprintf(stderr,
"[%s] failed with: [%d]\n", fun, errorCode); }
393 void XcpHw_Sleep(uint64_t usec) { usleep(usec); }