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 // lock process in to RAM
41 mlockall(MCL_CURRENT | MCL_FUTURE);
43 snprintf(taskname, sizeof(taskname), "S1-%d", getpid());
44 rt_sem_create(&CanFestival_mutex, taskname, 1, S_FIFO);
46 snprintf(taskname, sizeof(taskname), "S2-%d", getpid());
47 rt_sem_create(&control_task, taskname, 0, S_FIFO);
49 snprintf(taskname, sizeof(taskname), "M1-%d", getpid());
50 rt_mutex_create(&condition_mutex, taskname);
52 snprintf(taskname, sizeof(taskname), "C1-%d", getpid());
53 rt_cond_create(&timer_set, taskname);
60 void StopTimerLoop(TimerCallback_t exitfunction)
62 exitall = exitfunction;
64 rt_cond_signal(&timer_set);
67 void cleanup_all(void)
69 if (rt_task_join(&timerloop_task) != 0){
70 printf("Failed to join with Timerloop task\n");
72 rt_task_delete(&timerloop_task);
76 * Clean all Semaphores, mutex, condition variable and main task
78 void TimerCleanup(void)
80 rt_sem_delete(&CanFestival_mutex);
81 rt_mutex_delete(&condition_mutex);
82 rt_cond_delete(&timer_set);
83 rt_sem_delete(&control_task);
84 if (rt_task_join(&timerloop_task) != 0){
85 printf("Failed to join with Timerloop task\n");
87 rt_task_delete(&timerloop_task);
95 rt_sem_p(&CanFestival_mutex, TM_INFINITE);
99 * Signaling a semaphore
101 void LeaveMutex(void)
103 rt_sem_v(&CanFestival_mutex);
106 static TimerCallback_t init_callback;
111 void timerloop_task_proc(void *arg)
116 last_timeout_set = 0;
117 last_occured_alarm = last_time_read;
119 /* trigger first alarm */
120 SetAlarm(NULL, 0, init_callback, 0, 0);
125 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
126 if(last_timeout_set == TIMEVAL_MAX)
132 ); /* Then sleep until next message*/
133 rt_mutex_release(&condition_mutex);
135 current_time = rt_timer_read();
136 real_alarm = last_time_read + last_timeout_set;
137 ret = rt_cond_wait( /* sleep until next deadline */
140 (real_alarm - current_time)); /* else alarm consider expired */
141 if(ret == -ETIMEDOUT){
142 last_occured_alarm = real_alarm;
143 rt_mutex_release(&condition_mutex);
148 rt_mutex_release(&condition_mutex);
151 }while ((ret == 0 || ret == -EINTR || ret == -ETIMEDOUT) && !stop_timer);
161 * Create the Timer Task
162 * @param _init_callback
164 void StartTimerLoop(TimerCallback_t _init_callback)
168 init_callback = _init_callback;
171 snprintf(taskname, sizeof(taskname), "timerloop-%d", getpid());
173 /* create timerloop_task */
174 ret = rt_task_create(&timerloop_task, taskname, 0, 50, T_JOINABLE);
176 printf("Failed to create timerloop_task, code %d\n",errno);
180 /* start timerloop_task */
181 ret = rt_task_start(&timerloop_task,&timerloop_task_proc,NULL);
183 printf("Failed to start timerloop_task, code %u\n",errno);
194 * Create the CAN Receiver Task
195 * @param fd0 CAN port
196 * @param *ReceiveLoop_task CAN receiver task
197 * @param *ReceiveLoop_task_proc CAN receiver function
199 void CreateReceiveTask(CAN_PORT fd0, TASK_HANDLE *ReceiveLoop_task, void* ReceiveLoop_task_proc)
204 snprintf(taskname, sizeof(taskname), "canloop%d-%d", id, getpid());
207 /* create ReceiveLoop_task */
208 ret = rt_task_create(ReceiveLoop_task,taskname,0,50,T_JOINABLE);
210 printf("Failed to create ReceiveLoop_task number %d, code %d\n", id, errno);
213 /* start ReceiveLoop_task */
214 ret = rt_task_start(ReceiveLoop_task, ReceiveLoop_task_proc,(void*)fd0);
216 printf("Failed to start ReceiveLoop_task number %d, code %d\n", id, errno);
219 rt_sem_v(&control_task);
223 * Wait for the CAN Receiver Task end
224 * @param *ReceiveLoop_task CAN receiver thread
226 void WaitReceiveTaskEnd(TASK_HANDLE *ReceiveLoop_task)
228 if (rt_task_join(ReceiveLoop_task) != 0){
229 printf("Failed to join with Receive task\n");
231 rt_task_delete(ReceiveLoop_task);
235 * Set timer for the next wakeup
238 void setTimer(TIMEVAL value)
240 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
241 last_timeout_set = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : value;
242 rt_mutex_release(&condition_mutex);
243 rt_cond_signal(&timer_set);
247 * Get the elapsed time since the last alarm
248 * @return a time in nanoseconds
250 TIMEVAL getElapsedTime(void)
253 rt_mutex_acquire(&condition_mutex, TM_INFINITE);
254 last_time_read = rt_timer_read();
255 res = last_time_read - last_occured_alarm;
256 rt_mutex_release(&condition_mutex);