etisserant@391: /* edouard@629: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@391: etisserant@391: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@391: etisserant@391: See COPYING file for copyrights details. etisserant@391: etisserant@391: This library is free software; you can redistribute it and/or etisserant@391: modify it under the terms of the GNU Lesser General Public etisserant@391: License as published by the Free Software Foundation; either etisserant@391: version 2.1 of the License, or (at your option) any later version. etisserant@391: etisserant@391: This library is distributed in the hope that it will be useful, etisserant@391: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@391: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@391: Lesser General Public License for more details. etisserant@391: etisserant@391: You should have received a copy of the GNU Lesser General Public etisserant@391: License along with this library; if not, write to the Free Software etisserant@391: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@391: */ etisserant@391: etisserant@391: #include <linux/spinlock.h> etisserant@391: #include <linux/jiffies.h> etisserant@391: #include <linux/timer.h> etisserant@391: #include <linux/errno.h> etisserant@391: etisserant@391: #include "timer.h" etisserant@391: #include "applicfg.h" etisserant@391: etisserant@391: static spinlock_t lock = SPIN_LOCK_UNLOCKED; etisserant@391: etisserant@391: static struct timer_list timer; etisserant@391: etisserant@391: static TIMEVAL last_time_read, etisserant@391: last_occured_alarm, etisserant@391: last_alarm_set; etisserant@391: greg@467: void TimerInit(void) greg@467: { greg@467: /* only used in realtime apps */ greg@467: } greg@467: greg@467: void TimerCleanup(void) greg@467: { greg@467: /* only used in realtime apps */ greg@467: } etisserant@391: etisserant@391: void EnterMutex(void) etisserant@391: { etisserant@391: spin_lock (&lock); etisserant@391: } etisserant@391: etisserant@391: void LeaveMutex(void) etisserant@391: { etisserant@391: spin_unlock (&lock); etisserant@391: } etisserant@391: etisserant@391: void timer_notify(unsigned long data) etisserant@391: { etisserant@391: last_occured_alarm = last_alarm_set; etisserant@391: etisserant@391: EnterMutex(); etisserant@391: TimeDispatch(); etisserant@391: LeaveMutex(); etisserant@391: } etisserant@391: etisserant@391: void StartTimerLoop(TimerCallback_t init_callback) etisserant@391: { etisserant@391: getElapsedTime(); etisserant@391: last_alarm_set = last_time_read; etisserant@391: last_occured_alarm = last_alarm_set; etisserant@391: etisserant@391: init_timer(&timer); etisserant@391: timer.function = timer_notify; etisserant@391: etisserant@391: EnterMutex(); etisserant@391: // At first, TimeDispatch will call init_callback. etisserant@391: SetAlarm(NULL, 0, init_callback, 0, 0); etisserant@391: LeaveMutex(); etisserant@391: } etisserant@391: greg@467: void StopTimerLoop(TimerCallback_t exitfunction) etisserant@391: { etisserant@391: EnterMutex(); etisserant@391: del_timer (&timer); greg@467: exitfunction(NULL,0); etisserant@391: LeaveMutex(); etisserant@391: } etisserant@391: etisserant@391: void setTimer(TIMEVAL value) etisserant@391: { etisserant@391: if (value == TIMEVAL_MAX) etisserant@391: return; etisserant@391: etisserant@391: last_alarm_set = last_time_read + value; etisserant@391: mod_timer (&timer, last_alarm_set); etisserant@391: } etisserant@391: etisserant@391: TIMEVAL getElapsedTime(void) etisserant@391: { etisserant@391: last_time_read = jiffies; etisserant@391: etisserant@391: return (long)last_time_read - (long)last_occured_alarm; etisserant@391: } etisserant@391: etisserant@391: void CreateReceiveTask(CAN_PORT port, TASK_HANDLE *Thread, void* ReceiveLoopPtr) etisserant@391: { etisserant@391: *Thread = kthread_run(ReceiveLoopPtr, port, "canReceiveLoop"); etisserant@391: } etisserant@391: greg@467: void WaitReceiveTaskEnd(TASK_HANDLE *Thread) etisserant@391: { edouard@629: /* join thread here because force_sig() does not work */ edouard@629: while((*Thread)->state <= 0) edouard@629: { edouard@629: ; /* >0 means stopped */ edouard@629: } etisserant@391: }