5 #include <native/task.h>
6 #include <native/timer.h>
7 #include <native/sem.h>
8 #include <native/mutex.h>
9 #include <native/cond.h>
10 #include <native/alarm.h>
13 #include "can_driver.h"
16 #define TIMERLOOP_TASK_CREATED 1
18 TimerCallback_t exitall;
20 RT_MUTEX condition_mutex;
21 RT_SEM CanFestival_mutex;
24 RT_TASK timerloop_task;
27 RTIME last_occured_alarm;
28 RTIME last_timeout_set;
33 * Init Mutex, Semaphores and Condition variable
40 mlockall(MCL_CURRENT | MCL_FUTURE);
42 snprintf(taskname, sizeof(taskname), "S1-%d", getpid());
43 rt_sem_create(&CanFestival_mutex, taskname, 1, S_FIFO);
45 snprintf(taskname, sizeof(taskname), "S2-%d", getpid());
46 rt_sem_create(&control_task, taskname, 0, S_FIFO);
48 snprintf(taskname, sizeof(taskname), "M1-%d", getpid());
49 rt_mutex_create(&condition_mutex, taskname);
51 snprintf(taskname, sizeof(taskname), "C1-%d", getpid());
52 rt_cond_create(&timer_set, taskname);
59 void StopTimerLoop(TimerCallback_t exitfunction)
61 exitall = exitfunction;
63 rt_cond_signal(&timer_set);
66 void cleanup_all(void)
68 rt_task_delete(&timerloop_task);
72 * Clean all Semaphores, mutex, condition variable and main task
74 void TimerCleanup(void)
76 rt_sem_delete(&CanFestival_mutex);
77 rt_mutex_delete(&condition_mutex);
78 rt_cond_delete(&timer_set);
79 rt_sem_delete(&control_task);
87 rt_sem_p(&CanFestival_mutex, TM_INFINITE);
91 * Signaling a semaphore
95 rt_sem_v(&CanFestival_mutex);
98 static TimerCallback_t init_callback;
103 void timerloop_task_proc(void *arg)
106 // lock process in to RAM
107 mlockall(MCL_CURRENT | MCL_FUTURE);
110 last_timeout_set = 0;
111 last_occured_alarm = last_time_read;
113 /* trigger first alarm */
114 SetAlarm(NULL, 0, init_callback, 0, 0);
119 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
120 if(last_timeout_set == TIMEVAL_MAX)
126 ); /* Then sleep until next message*/
127 rt_mutex_release(&condition_mutex);
129 current_time = rt_timer_read();
130 real_alarm = last_time_read + last_timeout_set;
131 ret = rt_cond_wait( /* sleep until next deadline */
134 (real_alarm - current_time)); /* else alarm consider expired */
135 if(ret == -ETIMEDOUT){
136 last_occured_alarm = real_alarm;
137 rt_mutex_release(&condition_mutex);
142 rt_mutex_release(&condition_mutex);
145 }while ((ret == 0 || ret == -EINTR || ret == -ETIMEDOUT) && !stop_timer);
153 rt_task_delete(&timerloop_task);
157 * Create the Timer Task
158 * @param _init_callback
160 void StartTimerLoop(TimerCallback_t _init_callback)
164 init_callback = _init_callback;
167 snprintf(taskname, sizeof(taskname), "timerloop-%d", getpid());
169 /* create timerloop_task */
170 ret = rt_task_create(&timerloop_task, taskname, 0, 50, 0);
172 printf("Failed to create timerloop_task, code %d\n",errno);
176 /* start timerloop_task */
177 ret = rt_task_start(&timerloop_task,&timerloop_task_proc,NULL);
179 printf("Failed to start timerloop_task, code %u\n",errno);
190 * Create the CAN Receiver Task
191 * @param fd0 CAN port
192 * @param *ReceiveLoop_task CAN receiver task
193 * @param *ReceiveLoop_task_proc CAN receiver function
195 void CreateReceiveTask(CAN_PORT fd0, TASK_HANDLE *ReceiveLoop_task, void* ReceiveLoop_task_proc)
200 snprintf(taskname, sizeof(taskname), "canloop%d-%d", id, getpid());
203 /* create ReceiveLoop_task */
204 ret = rt_task_create(ReceiveLoop_task,taskname,0,50,0);
206 printf("Failed to create ReceiveLoop_task number %d, code %d\n", id, errno);
209 /* start ReceiveLoop_task */
210 ret = rt_task_start(ReceiveLoop_task, ReceiveLoop_task_proc,(void*)fd0);
212 printf("Failed to start ReceiveLoop_task number %d, code %d\n", id, errno);
215 rt_sem_v(&control_task);
219 * Wait for the CAN Receiver Task end
220 * @param *ReceiveLoop_task CAN receiver thread
222 void WaitReceiveTaskEnd(TASK_HANDLE *ReceiveLoop_task)
224 rt_task_delete(ReceiveLoop_task);
228 * Set timer for the next wakeup
231 void setTimer(TIMEVAL value)
233 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
234 last_timeout_set = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : value;
235 rt_mutex_release(&condition_mutex);
236 rt_cond_signal(&timer_set);
240 * Get the elapsed time since the last alarm
241 * @return a time in nanoseconds
243 TIMEVAL getElapsedTime(void)
246 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
247 last_time_read = rt_timer_read();
248 res = last_time_read - last_occured_alarm;
249 rt_mutex_release(&condition_mutex);