Commit ade70793 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Builds for atsam

using:   $ ./configure --host arm-none-eabihf --disable-vesp --disable-am335x --disable-ethercat CFLAGS=-specs /usr/local/arm-none-eabihf/lib/atsamx70x21_flash.specs
(add quotes to spec argument)
parent 51502aac
......@@ -23,8 +23,6 @@
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdarg.h>
// Keep this enum in sync with the list in controller_block_term_type2str() in
......
......@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <pthread.h>
#include <controller/controller_block.h>
#include <controller/controller_time.h>
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2018
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <dlfcn.h>
#include <stdlib.h>
#include <log/log.h>
#include <controller/controller_lib.h>
void *controller_lib_sym(char *symbol_name)
{
void *sym;
void *handle;
handle = dlopen(NULL, RTLD_NOW);
if (!handle) {
log_send(LOG_T_ERROR,
"Could not get handle from dlopen(): %s", dlerror());
return NULL;
}
sym = dlsym(handle, symbol_name);
if (!sym) {
dlclose(handle);
}
return sym;
}
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2018
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INCLUDE_CONTROLLER_LIB_H_
#define _INCLUDE_CONTROLLER_LIB_H_
void *controller_lib_sym(char *symbol_name);
#endif /*_INCLUDE_CONTROLLER_LIB_H_*/
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2018
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <controller/controller_lib.h>
#include <stdlib.h>
void *controller_lib_sym(char *symbol_name)
{
//TODO stub for now
return NULL;
}
......@@ -551,7 +551,11 @@ int controller_load_import(yyscan_t scanner, char *rel_name)
return -1;
}
#ifdef HAVE_FILEIO
char *realname = realpath(file_name, NULL);
#else
char *realname = file_name;
#endif
if (!realname) {
log_send(LOG_T_ERROR, "Could not find realpath");
......@@ -631,6 +635,8 @@ int controller_load_yy_input(char *buf, size_t *readbytes, size_t sizebytes, yys
}
#ifdef BUILD_TCP
static int controller_load_shell(char *args, char *out, int *outlen)
{
int ret;
......@@ -679,6 +685,7 @@ static int controller_load_shell(char *args, char *out, int *outlen)
return *outlen;
}
static int controller_load_file_shell(char *args, char *out, int *outlen)
{
int ret;
......@@ -704,6 +711,7 @@ static int controller_load_file_shell(char *args, char *out, int *outlen)
return *outlen;
}
static struct shell_cmd controller_cmd[] = {
{ "controller",
"parse arguments as controller commands",
......@@ -726,6 +734,8 @@ int controller_load_shell_add(void)
return ret;
}
#endif
// This routine is called (possibly recursively) to load a single file.
// Linking all inputs/outputs is allowed to fail here, since there might be
// links that go to/come from blocks that will be instantiated in other files
......
......@@ -520,6 +520,7 @@ trace : BRACEOPENSYM
stringvar
BRACECLOSESYM
{
#ifdef HAVE_TCP
struct controller_trace_name trace;
trace.name = $2;
......@@ -528,6 +529,7 @@ trace : BRACEOPENSYM
trace.termname = $8;
controller_trace_list_add(&trace);
#endif
}
| BRACEOPENSYM
stringvar COMMASYM
......@@ -535,6 +537,7 @@ trace : BRACEOPENSYM
ALIASVARIABLESYM
BRACECLOSESYM
{
#ifdef HAVE_TCP
struct controller_trace_name trace;
trace.name = $2;
......@@ -543,5 +546,6 @@ trace : BRACEOPENSYM
trace.termname = controller_load_variable_alias_get_term($6);
controller_trace_list_add(&trace);
#endif
}
;
......@@ -24,18 +24,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h>
#include <time.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <signal.h>
#include <sched.h>
#include <dirent.h>
#include <ctype.h>
#include <inttypes.h>
#include <dlfcn.h>
#ifdef HAVE_PTHREAD
#include <sys/mman.h>
#include <sched.h>
#include <dirent.h>
#include <pthread.h>
#endif
#include <controller/controller_block.h>
#include <controller/controller_sample.h>
......@@ -43,6 +45,7 @@
#include <controller/controller_time.h>
#include <controller/controller_trigger.h>
#include <controller/controller_load.h>
#include <controller/controller_lib.h>
#include <log/log.h>
#include <shell/shell.h>
......@@ -53,8 +56,7 @@ static uint32_t controller_samplenr = 0;
controller_trigger_time controller_sample_timestamp;
static pthread_t controller_sample_thread;
static bool controller_sample_thread_running = false;
static bool controller_sample_running_flag = false;
struct sample_timing {
controller_trigger_time min;
......@@ -97,7 +99,7 @@ static void sample_timing_add(struct sample_timing *st,
return;
}
#if defined(HAVE_TCP) || defined(HAVE_PTHREAD)
static ssize_t sample_timing_snprintf(struct sample_timing *st,
char *dest, size_t n)
{
......@@ -107,7 +109,20 @@ static ssize_t sample_timing_snprintf(struct sample_timing *st,
((double)st->sum / 1000.0) / (double)st->n,
(double)st->max/1000.0);
}
#endif
struct controller_trigger *controller_sample_trigger = NULL;
static controller_trigger_time (*wait_next)(struct controller_trigger *) = NULL;
static controller_trigger_time (*timestamp)(void) = NULL;
controller_trigger_time controller_sample_latency;
controller_trigger_time controller_sample_duration_blocks;
controller_trigger_time controller_sample_duration_sample;
#ifdef HAVE_PTHREAD
static pthread_t controller_sample_thread;
static void alarm_handler(int d)
{
......@@ -117,7 +132,7 @@ static void alarm_handler(int d)
static void cpu_bind(void)
{
#ifndef __FreeBSD__
#ifdef __linux__
unsigned int cpus = 2;
cpu_set_t set_sample, set_others;
int r, n;
......@@ -192,24 +207,12 @@ static void cpu_bind(void)
}
struct controller_trigger *controller_sample_trigger = NULL;
static controller_trigger_time (*wait_next)(struct controller_trigger *) = NULL;
static controller_trigger_time (*timestamp)(void) = NULL;
controller_trigger_time controller_sample_latency;
controller_trigger_time controller_sample_duration_blocks;
controller_trigger_time controller_sample_duration_sample;
/*
This thread should be realtime....
*/
static void *sample_thread(void *arg)
{
struct timespec t;
struct sched_param param;
controller_trigger_time t_trig;
controller_trigger_time t_start;
controller_trigger_time t_block;
controller_trigger_time t_end;
param.sched_priority = 90;
sigset_t sigset;
struct sigaction sigact;
......@@ -223,7 +226,6 @@ static void *sample_thread(void *arg)
sigaction(SIGALRM, &sigact, NULL);
log_send(LOG_T_DEBUG, "Starting sample thread");
controller_sample_thread_running = true;
cpu_bind();
......@@ -237,45 +239,11 @@ static void *sample_thread(void *arg)
strerror(errno));
}
t.tv_sec = 0;
t.tv_nsec = nsec_interval;
controller_sample_trigger->init(controller_sample_trigger, &t);
log_time_source_set(controller_sample_trigger->timestamp,
controller_sample_trigger->timestamp2timespec);
while (1) {
/* Pre sample stuff: */
controller_samplenr++;
/* Wait for the right moment...
(Internal timer or external interrupt) */
t_trig = wait_next(controller_sample_trigger);
controller_sample_trigger->timestamp2timespec(&t, t_trig);
controller_sample_timestamp = t_trig;
controller_time_seconds = t.tv_sec;
controller_time_nsec = t.tv_nsec;
t_start = timestamp();
/* Do sample stuff */
controller_block_calculate();
t_block = timestamp();
controller_sample_iteration(wait_next(controller_sample_trigger));
controller_block_trace();
controller_sample_task_exec();
t_end = timestamp();
controller_sample_latency = t_start - t_trig;
controller_sample_duration_blocks = t_block - t_start;
controller_sample_duration_sample = t_end - t_start;
sample_timing_add(&st_start, controller_sample_latency);
sample_timing_add(&st_block, controller_sample_duration_blocks);
sample_timing_add(&st_end, t_end - t_trig);
sample_timing_add(&st_sample, controller_sample_duration_sample);
// alarm(1);
}
return NULL;
......@@ -286,11 +254,6 @@ bool controller_sample_context(void)
return pthread_equal(controller_sample_thread, pthread_self());
}
bool controller_sample_running(void)
{
return controller_sample_thread_running;
}
static void *sample_monitor(void *arg)
{
......@@ -298,7 +261,7 @@ static void *sample_monitor(void *arg)
linebuf[200] = 0;
while(1) {
log_send(LOG_T_DEBUG, "Samplenr: %d\tOverruns: %d",
log_send(LOG_T_DEBUG, "Samplenr: %"PRId32"\tOverruns: %d",
controller_samplenr,
controller_sample_trigger->overruns(controller_sample_trigger));
sample_timing_snprintf(&st_start, linebuf, 200);
......@@ -314,10 +277,74 @@ static void *sample_monitor(void *arg)
return NULL;
}
#else
bool controller_sample_context(void)
{
//TODO stub for now!!!
return false;
}
#endif
bool controller_sample_running(void)
{
return controller_sample_running_flag;
}
void controller_sample_iteration(controller_trigger_time t_trig)
{
struct timespec t;
controller_trigger_time t_start;
controller_trigger_time t_block;
controller_trigger_time t_end;
controller_samplenr++;
controller_sample_trigger->timestamp2timespec(&t, t_trig);
controller_sample_timestamp = t_trig;
controller_time_seconds = t.tv_sec;
controller_time_nsec = t.tv_nsec;
t_start = timestamp();
/* Do sample stuff */
controller_block_calculate();
t_block = timestamp();
#ifdef HAVE_TCP
controller_block_trace();
#endif
controller_sample_task_exec();
t_end = timestamp();
controller_sample_latency = t_start - t_trig;
controller_sample_duration_blocks = t_block - t_start;
controller_sample_duration_sample = t_end - t_start;
sample_timing_add(&st_start, controller_sample_latency);
sample_timing_add(&st_block, controller_sample_duration_blocks);
sample_timing_add(&st_end, t_end - t_trig);
sample_timing_add(&st_sample, controller_sample_duration_sample);
}
#ifdef HAVE_TCP
/********************************************
* Shell interface:
*/
static struct shell_cmd sample_shell_cmd = {
"timing", "reset/print sample timing", controller_sample_timing
};
int controller_sample_shell_add(void)
{
return shell_cmd_add(&sample_shell_cmd);
}
static void controller_sample_timing_reset(void)
{
sample_timing_init(&st_start, "start");
......@@ -357,17 +384,7 @@ static int controller_sample_timing(char *args, char *out, int *outlen)
return *outlen;
}
static struct shell_cmd sample_shell_cmd = {
"timing", "reset/print sample timing", controller_sample_timing
};
int controller_sample_shell_add(void)
{
return shell_cmd_add(&sample_shell_cmd);
}
#endif
void controller_sample_start_hook(void (*func)(void *arg), void *arg)
{
......@@ -382,9 +399,8 @@ void controller_sample_start_hook(void (*func)(void *arg), void *arg)
int controller_sample_start(void)
{
pthread_t thread_id;
pthread_attr_t attr;
int i;
struct timespec t;
if (!controller_sample_trigger) {
log_send(LOG_T_DEBUG, "No trigger defined");
......@@ -401,17 +417,30 @@ int controller_sample_start(void)
sample_timing_init(&st_block, "blocks");
sample_timing_init(&st_sample, "sample");
t.tv_sec = 0;
t.tv_nsec = nsec_interval;
controller_sample_trigger->init(controller_sample_trigger, &t);
log_time_source_set(controller_sample_trigger->timestamp,
controller_sample_trigger->timestamp2timespec);
for (i = 0; i < controller_sample_start_hooks_nr; i++)
controller_sample_start_hooks[i].func(
controller_sample_start_hooks[i].arg);
controller_sample_running_flag = true;
#ifdef HAVE_PTHREAD
pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
#ifndef __FreeBSD__
#ifdef __linux__
pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN * 2);
#endif
pthread_create(&thread_id, &attr, sample_monitor, NULL);
sched_yield();
pthread_create(&controller_sample_thread, &attr, sample_thread, NULL);
#endif
return 0;
}
......@@ -422,21 +451,12 @@ int controller_sample_start(void)
int controller_sample_trigger_create(char *name, int argc, va_list ap,
char **arg_types)
{
void *handle;
struct controller_trigger_create *create;
struct controller_trigger_create *create = NULL;
int ret = 0;
char *symbol;
// Try to load the trigger's module.
handle = dlopen(NULL, RTLD_NOW);
if (!handle) {
log_send(LOG_T_ERROR,
"Could not get handle from dlopen(): %s", dlerror());
return -1;
}
asprintf(&symbol, "%s%s%s", PREFIX, name, POSTFIX);
create = dlsym(handle, symbol);
create = controller_lib_sym(symbol);
free(symbol);
if (!create) {
......@@ -464,6 +484,5 @@ int controller_sample_trigger_create(char *name, int argc, va_list ap,
timestamp = controller_sample_trigger->timestamp;
errout:
dlclose(handle);
return ret;
}
......@@ -29,6 +29,8 @@ int controller_sample_start(void);
void controller_sample_start_hook(void (*func)(void *arg), void *arg);
void controller_sample_iteration(controller_trigger_time t_trig);
bool controller_sample_context(void);
bool controller_sample_running(void);
......
......@@ -19,7 +19,9 @@
#include <controller/controller_sample.h>
#include <stdlib.h>
#ifdef HAVE_SEMAPHORE
#include <semaphore.h>
#endif
struct task_data {
struct task_data *next;
......@@ -28,7 +30,11 @@ struct task_data {
void *arg;
int ret;
#ifdef HAVE_SEMAPHORE
sem_t sem;
#else
volatile bool done;
#endif
};
static struct task_data *tasklist = NULL;
......@@ -43,14 +49,21 @@ int controller_sample_task(int (*task)(void *), void *arg)
data.task = task;
data.arg = arg;
#ifdef HAVE_SEMAPHORE
sem_init(&data.sem, 0, 0);
#else
data.done = false;
#endif
do {
data.next = tasklist;
} while (!__sync_bool_compare_and_swap(&tasklist, data.next, &data));
#ifdef HAVE_SEMAPHORE
sem_wait(&data.sem);
#else
while (!data.done);
#endif
return data.ret;
}
......@@ -65,6 +78,10 @@ void controller_sample_task_exec(void)
data->ret = data->task(data->arg);
#ifdef HAVE_SEMAPHORE
sem_post(&data->sem);
#else
data->done = true;
#endif
}
}
......@@ -326,9 +326,9 @@ static void handler_name(struct trace *trace, int channel, char *name)
termname = hdl->tracename;
while (termname[0] && termname[0] != '.')
termname++;
if (termname[0] == '.') {
termname[0] = 0;
termname++;
if (termname[0] == '.') {
termname[0] = 0;
termname++;
}
}
......
......@@ -44,7 +44,6 @@
#include <controller/controller_time.h>
#include <controller/controller_mem.h>
#include <shell/shell.h>
#include <ec/ec.h>
#include <log/log.h>
#include <dt_port_numbers.h>
......@@ -61,25 +60,23 @@ int main(int argc, char **argv)
int i;
size_t usage_0, usage_r, usage_w, usage_rw;
#ifdef HAVE_FILEIO
sigemptyset (&sigset);
sigaddset(&sigset, SIGALRM);
sigprocmask(SIG_BLOCK, &sigset, NULL);