/* * This work is part of the White Rabbit project * * Copyright (C) 2011,2012 CERN (www.cern.ch) * Author: Tomasz Wlostowski * Author: Grzegorz Daniluk * * Released according to the GNU GPL, version 2 or any later version. */ #include #include #include #include #include #include #include "syscon.h" #include "uart.h" #include "endpoint.h" #include "minic.h" #include "pps_gen.h" #include "ptpd_netif.h" #include "i2c.h" #include "storage.h" #include "softpll_ng.h" #include "onewire.h" #include "pps_gen.h" #include "shell.h" #include "lib/ipv4.h" #include "rxts_calibrator.h" #include "flash.h" #include "wrc_ptp.h" #include "system_checks.h" #ifndef CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD #define CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD 0 #endif int wrc_ui_mode = UI_SHELL_MODE; int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */ int wrc_phase_tracking = 1; char wrc_hw_name[HW_NAME_LENGTH]; uint32_t cal_phase_transition[wr_num_ports]; int wrc_vlan_number = CONFIG_VLAN_NR; static uint32_t prev_nanos_for_profile; static uint32_t prev_ticks_for_profile; uint32_t print_task_time_threshold = CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD; uint8_t mac_addr[wr_num_ports][6]; static void wrc_initialize(void) { int port; sdb_find_devices(); uart_init_hw(); pp_printf("WR Core: starting up...\n"); timer_init(1); get_hw_name(wrc_hw_name); #ifdef CONFIG_SDB_STORAGE storage_read_hdl_cfg(); #endif wrpc_w1_init(); wrpc_w1_bus.detail = ONEWIRE_PORT; w1_scan_bus(&wrpc_w1_bus); /*initialize flash*/ flash_init(); /*initialize I2C bus*/ mi2c_init(WRPC_FMC_I2C); /*init storage (Flash / W1 EEPROM / I2C EEPROM*/ storage_init(WRPC_FMC_I2C, FMC_EEPROM_ADR); if (get_persistent_mac(ONEWIRE_PORT, mac_addr[0]) == -1) { pp_printf("Unable to determine MAC address\n"); for (port=0; port TICS_PER_SECOND) { fraction -= TICS_PER_SECOND; uptime_sec++; return 1; } return 0; } DEFINE_WRC_TASK(uptime) = { .name = "uptime", .init = init_uptime, .job = update_uptime, }; DEFINE_WRC_TASK(ptp) = { .name = "ptp", .job = wrc_ptp_update, }; DEFINE_WRC_TASK(shell) = { .name = "shell+gui", .init = shell_boot_script, .job = ui_update, }; DEFINE_WRC_TASK(spll) = { .name = "spll-bh", .job = spll_update, }; static void task_time_normalize(struct wrc_task *t) { if (t->nanos > 1000 * 1000 * 1000) { t->nanos -= 1000 * 1000 * 1000; t->seconds++; } } /* Account the time to either this task or task 0 */ static void account_task(struct wrc_task *t, int done_sth) { uint32_t nanos; signed int delta; uint32_t ticks; signed int delta_ticks; if (!done_sth) t = __task_begin; /* task 0 is special */ shw_pps_gen_get_time(NULL, &nanos); /* get monotonic number of ticks */ ticks = timer_get_tics(); delta = nanos - prev_nanos_for_profile; if (delta < 0) delta += 1000 * 1000 * 1000; t->nanos += delta; task_time_normalize(t); prev_nanos_for_profile = nanos; delta_ticks = ticks - prev_ticks_for_profile; if (delta_ticks < 0) delta_ticks += TICS_PER_SECOND; if (t->max_run_ticks < delta_ticks) {/* update max_run_ticks */ if (print_task_time_threshold) { /* Print only if threshold is set */ pp_printf("New max run time for a task %s, old %ld, " "new %d\n", t->name, t->max_run_ticks, delta_ticks); } t->max_run_ticks = delta_ticks; } if (print_task_time_threshold && delta_ticks > print_task_time_threshold) pp_printf("task %s, run for %d ms\n", t->name, delta_ticks); prev_ticks_for_profile = ticks; } /* Run a task with profiling */ static void wrc_run_task(struct wrc_task *t) { int done_sth = 0; if (!t->job) /* idle task, just count iterations */ t->nrun++; else if (!t->enable || *t->enable) { /* either enabled or without a check variable */ done_sth = t->job(); t->nrun += done_sth; } account_task(t, done_sth); } int main(void) __attribute__ ((weak)); int main(void) { struct wrc_task *t; check_reset(); /* initialization of individual tasks */ for_each_task(t) if (t->init) t->init(); for (;;) { for_each_task(t) wrc_run_task(t); /* better safe than sorry */ check_stack(); } }