2 * Copyright Droids Corporation
3 * Olivier Matz <zer0@droids-corp.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * Revision : $Id: main.c,v 1.10 2009-11-08 17:24:33 zer0 Exp $
25 * AVR simulator. This code is used on host (PC for instance) to
26 * generate a signal that will call other aversive modules like
27 * scheduler or uart. The goal is to simulate the behaviour of
28 * hardware interrupts in a unix application.
40 #include <sys/types.h>
43 #ifdef CONFIG_MODULE_SCHEDULER
44 #include <scheduler.h>
47 static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
48 static volatile int cpt = 0;
51 static void sigusr1(__attribute__((unused)) int sig,
52 __attribute__((unused)) siginfo_t *info,
53 __attribute__((unused)) void *uc)
55 void sigusr1(__attribute__((unused)) int sig)
58 pthread_mutex_unlock(&mut);
60 #ifdef CONFIG_MODULE_SCHEDULER
61 scheduler_interrupt();
65 static int lock_count = 0;
67 void hostsim_lock(void)
71 pthread_mutex_lock(&mut);
74 void hostsim_unlock(void)
76 if (lock_count-- == 1)
77 pthread_mutex_unlock(&mut);
80 int hostsim_islocked(void)
85 void host_wait_ms(int ms)
87 struct timeval tv, tv2, diff;
89 gettimeofday(&tv, NULL);
90 diff.tv_sec = (1000 * ms) / 1000000;
91 diff.tv_usec = (1000 * ms) % 1000000;
92 timeradd(&tv, &diff, &tv);
93 gettimeofday(&tv2, NULL);
95 while (timercmp(&tv2, &tv, <)) {
97 gettimeofday(&tv2, NULL);
102 /* sends signal to child */
103 void *parent(void *arg)
105 pthread_t *thread = arg;
106 struct timeval cur_tv, prev_tv, tv_millisec;
109 gettimeofday(&prev_tv, NULL);
113 gettimeofday(&cur_tv, NULL);
116 while (timercmp(&prev_tv, &cur_tv, <)) {
118 /* give some time between subsequent
123 pthread_mutex_lock(&mut);
124 pthread_kill(*thread, SIGUSR1);
126 /* signal was acked */
127 tv_millisec.tv_sec = 0;
128 tv_millisec.tv_usec = 1000;
129 timeradd(&prev_tv, &tv_millisec, &prev_tv);
138 int hostsim_init(void)
140 struct sigaction sigact;
141 pthread_t parent_id, child_id;
144 parent_id = pthread_self();
146 pthread_mutex_lock(&mut);
147 ret = pthread_create(&child_id, NULL, parent, (void *)parent_id);
149 printf("pthread_create() returned %d\n", ret);
150 pthread_mutex_unlock(&mut);
154 /* register a signal handler, which is interruptible */
155 memset(&sigact, 0, sizeof(sigact));
156 sigemptyset(&sigact.sa_mask);
157 sigact.sa_flags |= SA_NODEFER;
158 sigact.sa_sigaction = sigusr1;
159 sigaction(SIGUSR1, &sigact, NULL);
162 if (siginterrupt (SIGUSR1, 0) != 0)
165 printf("hostsim_init()\n", ret);
166 pthread_mutex_unlock(&mut);
170 #endif /* HOST_VERSION */