X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=modules%2Fbase%2Fhostsim%2Fhostsim.c;fp=modules%2Fbase%2Fhostsim%2Fhostsim.c;h=850d23a59f7e1d7331f2599362d17e514da4b343;hp=0000000000000000000000000000000000000000;hb=09fd7b53a60d7201b6d019d88d3fee3d43a14c3f;hpb=e0908eab4d4b00cf19083f91a9921b3e8d0cae63 diff --git a/modules/base/hostsim/hostsim.c b/modules/base/hostsim/hostsim.c new file mode 100644 index 0000000..850d23a --- /dev/null +++ b/modules/base/hostsim/hostsim.c @@ -0,0 +1,151 @@ +/* + * Copyright Droids Corporation + * Olivier Matz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: main.c,v 1.10 2009-11-08 17:24:33 zer0 Exp $ + * + */ + +#ifdef HOST_VERSION +/* + * AVR simulator. This code is used on host (PC for instance) to + * generate a signal that will call other aversive modules like + * scheduler or uart. The goal is to simulate the behaviour of + * hardware interrupts in a unix application. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MODULE_SCHEDULER +#include +#endif + +pthread_mutex_t mut; +static volatile int cpt = 0; + +#ifdef SA_SIGINFO +static void sigusr1(__attribute__((unused)) int sig, + __attribute__((unused)) siginfo_t *info, + __attribute__((unused)) void *uc) +#else +void sigusr1(__attribute__((unused)) int sig) +#endif +{ + pthread_mutex_unlock(&mut); + +#ifdef CONFIG_MODULE_SCHEDULER + scheduler_interrupt(); +#endif +} + +void host_wait_ms(int ms) +{ + struct timeval tv, tv2, diff; + + gettimeofday(&tv, NULL); + diff.tv_sec = (1000 * ms) / 1000000; + diff.tv_usec = (1000 * ms) % 1000000; + timeradd(&tv, &diff, &tv); + gettimeofday(&tv2, NULL); + + while (timercmp(&tv2, &tv, <)) { + usleep(1000); + gettimeofday(&tv2, NULL); + } +} + + +/* sends signal to child */ +void *parent(void *arg) +{ + pthread_t *thread = arg; + struct timeval cur_tv, prev_tv, tv_millisec; + int n; + + gettimeofday(&prev_tv, NULL); + + while (1) { + usleep(1000); + gettimeofday(&cur_tv, NULL); + + n = 0; + while (timercmp(&prev_tv, &cur_tv, <)) { + if (n > 5) { + /* give some time between subsequent + * signals */ + usleep(100); + n = 0; + } + pthread_mutex_lock(&mut); + pthread_kill(*thread, SIGUSR1); + + /* signal was acked */ + tv_millisec.tv_sec = 0; + tv_millisec.tv_usec = 1000; + timeradd(&prev_tv, &tv_millisec, &prev_tv); + n ++; + } + } + + pthread_exit(NULL); + return NULL; +} + +int hostsim_init(void) +{ + struct sigaction sigact; + pthread_t parent_id, child_id; + int ret; + + pthread_mutex_init(&mut, NULL); + + parent_id = pthread_self(); + + pthread_mutex_lock(&mut); + ret = pthread_create(&child_id, NULL, parent, (void *)&parent_id); + if (ret) { + printf("pthread_create() returned %d\n", ret); + pthread_mutex_unlock(&mut); + return -1; + } + + /* register a signal handler, which is interruptible */ + memset(&sigact, 0, sizeof(sigact)); + sigemptyset(&sigact.sa_mask); + sigact.sa_flags |= SA_NODEFER; + sigact.sa_sigaction = sigusr1; + sigaction(SIGUSR1, &sigact, NULL); + + /* */ + if (siginterrupt (SIGUSR1, 0) != 0) + return -1; + + pthread_mutex_unlock(&mut); + + return 0; +} +#endif /* HOST_VERSION */