int serial_ctrl_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * usb = vcom->usb; struct usb_cdc_state prev_state; struct usb_cdc_state state; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); usb_cdc_state_get(usb, &prev_state); while (1) { usb_cdc_ctrl_event_wait(usb, 0); usb_cdc_state_get(usb, &state); #if 0 if (state.cfg != prev_state.cfg) { DCC_LOG1(LOG_TRACE, "[%d] config changed.", thinkos_thread_self()); prev_state.cfg = state.cfg; } if (state.ctrl != prev_state.ctrl) { DCC_LOG1(LOG_TRACE, "[%d] control changed.", thinkos_thread_self()); prev_state.ctrl = state.ctrl; } #endif } return 0; }
int usb_ctrl_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * usb = vcom->usb; struct usb_cdc_state prev_state; struct usb_cdc_state state; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); usb_cdc_state_get(usb, &prev_state); while (1) { usb_cdc_ctrl_event_wait(usb, 0); usb_cdc_state_get(usb, &state); if (memcmp(&state.cfg, &prev_state.cfg, sizeof(struct serial_config)) != 0) { DCC_LOG1(LOG_TRACE, "[%d] config changed.", thinkos_thread_self()); prev_state.cfg = state.cfg; } if (memcmp(&state.ctrl, &prev_state.ctrl, sizeof(struct serial_control)) != 0) { DCC_LOG1(LOG_TRACE, "[%d] control changed.", thinkos_thread_self()); prev_state.ctrl = state.ctrl; } } return 0; }
void __attribute__((noreturn)) serial_recv_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * cdc = vcom->cdc; uint8_t buf[VCOM_BUF_SIZE]; int len; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); /* wait for line configuration */ usb_cdc_acm_lc_wait(cdc); /* enable serial */ serial_enable(serial); for (;;) { len = serial_read(serial, buf, VCOM_BUF_SIZE, 1000); if (len > 0) { // dbg_write(buf, len); if (vcom->mode == VCOM_MODE_CONVERTER) { led_flash(LED_AMBER, 50); usb_cdc_write(cdc, buf, len); } if (vcom->mode == VCOM_MODE_SDU_TRACE) { led_flash(LED_AMBER, 50); sdu_decode(buf, len); } #if RAW_TRACE if (len == 1) DCC_LOG1(LOG_TRACE, "RX: %02x", buf[0]); else if (len == 2) DCC_LOG2(LOG_TRACE, "RX: %02x %02x", buf[0], buf[1]); else if (len == 3) DCC_LOG3(LOG_TRACE, "RX: %02x %02x %02x", buf[0], buf[1], buf[2]); else if (len == 4) DCC_LOG4(LOG_TRACE, "RX: %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3]); else if (len == 5) DCC_LOG5(LOG_TRACE, "RX: %02x %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3], buf[4]); else if (len == 6) DCC_LOG6(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); else if (len == 7) DCC_LOG7(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x %02x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); else DCC_LOG8(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x " "%02x %02x ...", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); #endif #if SDU_TRACE RX(buf, len); #endif } } }
int event_wait_task(void * arg) { struct stm32f_tim * tim7 = STM32F_TIM7; int self = thinkos_thread_self(); uint32_t latency; uint32_t ticks; req = false; ack = false; printf(" [%d] started.\n", self); while (1) { ack = false; req = true; __thinkos_critical_enter(); while (!ack) { __thinkos_ev_wait(ev_timer); } __thinkos_critical_exit(); latency = tim7->cnt; if (meter.max.event < latency) meter.max.event = latency; meter.avg.event = (meter.avg.event * 63) / 64 + latency; ticks = meter.ticks.event; meter.ticks.event = ticks + 1; } return 0; }
int consumer_task(void * arg) { int i = 0; printf(" %s(): [%d] started...\n", __func__, thinkos_thread_self()); thinkos_sleep(100); /* set the production enable flag to start production */ do { printf(" %3d ", i); /* wait for an item to be produced */ while (thinkos_sem_timedwait(sem_full, 50) == THINKOS_ETIMEDOUT) { printf("."); } /* unload the buffer */ printf(" %016llx %llu\n", buffer, buffer); i++; /* signal the empty buffer */ thinkos_sem_post(sem_empty); } while (!prod_done); /* get the last produced item, if any */ if (thinkos_sem_timedwait(sem_full, 0) == 0) { printf(" %3d ", i); printf(" %016llx %llu\n", buffer, buffer); i++; thinkos_sem_post(sem_empty); } return i; };
int http_server_task(struct httpd * httpd) { struct httpctl httpctl; struct httpctl * ctl = &httpctl; const struct httpdobj * obj; INF("Webserver started (thread %d).", thinkos_thread_self()); for (;;) { if (http_accept(httpd, ctl) < 0) { ERR("tcp_accept() failed!\n"); thinkos_sleep(1000); continue; } if ((obj = http_obj_lookup(ctl)) != NULL) { switch (ctl->method) { case HTTP_GET: DBG("HTTP GET \"%s\"", obj->oid); http_get(ctl, obj); break; case HTTP_POST: DBG("HTTP POST \"%s\"", obj->oid); http_post(ctl, obj); break; } } http_close(ctl); } return 0; }
static int __btn_task(void) { int st; printf("%s(): thread %d started.\n", __func__, thinkos_thread_self()); stm32_gpio_clock_en(STM32_GPIOA); stm32_gpio_mode(PUSH_BTN, INPUT, 0); btn_st = stm32_gpio_stat(PUSH_BTN) ? 1 : 0; for (;;) { thinkos_sleep(50); /* process push button */ st = stm32_gpio_stat(PUSH_BTN) ? 1 : 0; if (btn_st != st) { btn_st = st; thinkos_mutex_lock(btn_mutex); btn_event = st ? BTN_PRESSED : BTN_RELEASED; thinkos_mutex_unlock(btn_mutex); } } return 0; }
int led_task(void) { DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); while (1) { DCC_LOG(LOG_MSG, "thinkos_flag_wait()..."); thinkos_flag_wait(led_flag); if (led1_flash_tail != led1_flash_head) { led1_flash_tail++; if (!led_locked) led1_on(); } if (led2_flash_tail != led2_flash_head) { led2_flash_tail++; if (!led_locked) led2_on(); } if ((led1_flash_tail == led1_flash_head) && (led2_flash_tail == led2_flash_head)) thinkos_flag_clr(led_flag); thinkos_sleep(100); if (!led_locked) { led1_off(); led2_off(); } thinkos_sleep(100); } }
static int uart_console_read(struct uart_console_dev * dev, char * buf, unsigned int len, unsigned int msec) { char * cp = (char *)buf; int n = 0; int c; DCC_LOG(LOG_INFO, "read"); __thinkos_flag_clr(dev->rx_flag); while (uart_fifo_is_empty(&dev->rx_fifo)) { DCC_LOG(LOG_INFO, "wait..."); thinkos_flag_wait(dev->rx_flag); __thinkos_flag_clr(dev->rx_flag); DCC_LOG(LOG_INFO, "wakeup."); } do { if (n == len) { break; } c = uart_fifo_get(&dev->rx_fifo); if (c == '\r') c = '\n'; cp[n++] = c; } while (!uart_fifo_is_empty(&dev->rx_fifo)); DCC_LOG2(LOG_INFO, "[%d] n=%d", thinkos_thread_self(), n); return n; }
void __attribute__((noreturn)) supervisor_task(void) { struct trace_entry trace; uint32_t clk; INF("<%d> started...", thinkos_thread_self()); trace_tail(&trace); clk = thinkos_clock(); for (;;) { struct timeval tv; char s[80]; /* 8Hz periodic task */ clk += 125; thinkos_alarm(clk); while (trace_getnext(&trace, s, sizeof(s)) >= 0) { trace_ts2timeval(&tv, trace.dt); printf("%s %2d.%06d: %s\n", trace_lvl_tab[trace.ref->lvl], (int)tv.tv_sec, (int)tv.tv_usec, s); } trace_flush(&trace); } }
static int accelerometer_task(struct acc_info * acc) { struct { int8_t x; uint8_t res1; int8_t y; uint8_t res2; int8_t z; } data; uint8_t cfg[4]; uint8_t st; int x = 0; int y = 0; int z = 0; int x_off = 0; int y_off = 0; int z_off = 0; printf("%s(): thread %d started.\n", __func__, thinkos_thread_self()); if (lis302_init() < 0) { return -1; } cfg[0] = CTRL_PD | CTRL_ZEN | CTRL_YEN | CTRL_XEN; cfg[1] = 0; cfg[3] = 0; lis302_wr(LIS302_CTRL_REG1, cfg, 3); for (; ;) { thinkos_sleep(1); /* poll the sensor */ lis302_rd(LIS302_STATUS_REG, &st, 1); if (st & STAT_ZYXDA) { /* get the forces data */ lis302_rd(LIS302_OUT_X, &data, 5); /* Filter */ x = (x * (AVG_N - 1) / AVG_N) + data.x; y = (y * (AVG_N - 1) / AVG_N) + data.y; z = (z * (AVG_N - 1) / AVG_N) + data.z; if (acc->cal_req) { x_off = -x; y_off = -y; z_off = -z; acc->cal_req = false; } acc->x = x_off + x; acc->y = y_off + y; acc->z = z_off + z; thinkos_sem_post(acc->sem); } } }
void __attribute__((noreturn)) net_recv_task(void) { void * pkt; int len; DCC_LOG1(LOG_TRACE, "thread=%d", thinkos_thread_self()); DBG("<%d> started...", thinkos_thread_self()); for (;;) { pkt = pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); DBG("pktbuf_alloc() failed!"); thinkos_sleep(1000); continue; } len = rs485_pkt_receive(&net.link, &pkt, pktbuf_len); if (len < 0) { DBG("rs485_pkt_receive() failed!"); thinkos_sleep(1000); continue; } if (len == 0) { DBG("rs485_pkt_receive() == 0!"); thinkos_sleep(1000); continue; } if (pkt != NULL) { if (net.probe_mode) net_probe_recv((char *)pkt, len); else if (net.pkt_mode) net_pkt_recv((struct net_pkt *)pkt, len); else net_recv((char *)pkt, len); pktbuf_free(pkt); } } }
void __attribute__((noreturn)) console_shell_task(void) { DCC_LOG1(LOG_TRACE, "thread=%d", thinkos_thread_self()); // tracef("%s(): <%d> started...", __func__, thinkos_thread_self()); for (;;) { stdio_shell(); } }
void __attribute__((noreturn)) usb_recv_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; usb_cdc_class_t * cdc = vcom->cdc; uint8_t buf[VCOM_BUF_SIZE]; int len; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); DCC_LOG2(LOG_TRACE, "vcom->%p, cdc->%p", vcom, cdc); for (;;) { len = usb_cdc_read(cdc, buf, VCOM_BUF_SIZE, 1000); if (vcom->mode == VCOM_MODE_CONVERTER) { if (len > 0) { led_flash(LED_RED, 50); serial_write(serial, buf, len); #if RAW_TRACE if (len == 1) DCC_LOG1(LOG_TRACE, "TX: %02x", buf[0]); else if (len == 2) DCC_LOG2(LOG_TRACE, "TX: %02x %02x", buf[0], buf[1]); else if (len == 3) DCC_LOG3(LOG_TRACE, "TX: %02x %02x %02x", buf[0], buf[1], buf[2]); else if (len == 4) DCC_LOG4(LOG_TRACE, "TX: %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3]); else if (len == 5) DCC_LOG5(LOG_TRACE, "TX: %02x %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3], buf[4]); else if (len == 6) DCC_LOG6(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); else if (len == 7) DCC_LOG7(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x %02x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); else DCC_LOG8(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x " "%02x %02x ...", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); #endif #if SDU_TRACE TX(buf, len); #endif // dbg_write(buf, len); } } else { // forward to service input vcom_service_input(vcom, buf, len); } } }
int serial_recv_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * usb = vcom->usb; char buf[VCOM_BUF_SIZE]; int len; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); for (;;) { len = serial_read(serial, buf, VCOM_BUF_SIZE, 100); if (len > 0) usb_cdc_write(usb, buf, len); } return 0; }
static int __leds_task(void) { unsigned int tmr[LED_COUNT]; unsigned int i; unsigned int rate; unsigned int tm; printf("%s(): thread %d started.\n", __func__, thinkos_thread_self()); for (i = 0; i < LED_COUNT; ++i) tmr[i] = led_rate[i]; for (;;) { thinkos_mutex_lock(leds_mutex); for (i = 0; i < LED_COUNT; ++i) { if ((rate = led_rate[i]) == 0) { continue; } tm = MIN(tmr[i], rate); if (tm == 0) { tmr[i] = rate; if (led_state[i]) { __led_off(i); } else { __led_on(i); } } else { tmr[i] = tm - 1; } } thinkos_mutex_unlock(leds_mutex); thinkos_sleep(10); } return 0; }
int main(int argc, char ** argv) { struct dmon_comm * comm; DCC_LOG_INIT(); DCC_LOG_CONNECT(); #ifndef UDELAY_FACTOR DCC_LOG(LOG_TRACE, "1. cm3_udelay_calibrate()."); cm3_udelay_calibrate(); #endif DCC_LOG(LOG_TRACE, "2. thinkos_init()."); thinkos_init(THINKOS_OPT_PRIORITY(0) | THINKOS_OPT_ID(0)); #if THINKOS_ENABLE_MPU DCC_LOG(LOG_TRACE, "3. thinkos_mpu_init()"); thinkos_mpu_init(0x0c00); #endif DCC_LOG(LOG_TRACE, "4. board_init()."); this_board.init(); DCC_LOG(LOG_TRACE, "5. thinkos_console_init()"); thinkos_console_init(); DCC_LOG(LOG_TRACE, "6. usb_comm_init()"); comm = usb_comm_init(&stm32f_otg_fs_dev); DCC_LOG(LOG_TRACE, "7. thinkos_dmon_init()"); thinkos_dmon_init(comm, monitor_task); #if THINKOS_ENABLE_MPU DCC_LOG(LOG_TRACE, "8. thinkos_userland()"); thinkos_userland(); #endif DCC_LOG(LOG_TRACE, "9. thinkos_thread_abort()"); thinkos_thread_abort(thinkos_thread_self()); return 0; }
void __attribute__((noreturn)) monitor_task(void) { int opt; tracef("%s(): <%d> started...", __func__, thinkos_thread_self()); for (;;) { thinkos_sleep(250); if (monitor_auto_flush) opt = TRACE_FLUSH; else opt = 0; if (trace_fprint(monitor_stream, opt) < 0) { /* fall back to stdout */ monitor_stream = stdout; } } }
int producer_task(void * arg) { uint64_t y; unsigned int i = 0; uint64_t x0 = 0; uint64_t x1 = 0; prod_done = false; printf(" %s(): [%d] started...\n", __func__, thinkos_thread_self()); thinkos_sleep(100); for (i = 0; i < prod_count; i++) { /* let's spend some time thinking */ thinkos_sleep(500); /* working */ if (i == 0) y = 0; else if (i == 1) y = 1; else y = x1 + x0; x0 = x1; x1 = y; /* waiting for room to insert a new item */ thinkos_sem_wait(sem_empty); /* insert the produced item in the buffer */ buffer = y; /* signal a full buffer */ thinkos_sem_post(sem_full); } prod_done = true; return i; }
void net_rcv_task(void) { sndbuf_t * buf; uint32_t ts; int n; tracef("%s(): <%d> started...", __func__, thinkos_thread_self()); for (;;) { while ((buf = sndbuf_alloc()) == NULL) { tracef("%s(): sndbuf_alloc() failed!", __func__); thinkos_sleep(1000); } #if ENABLE_G711 n = g711_alaw_recv(0, buf, &ts); #else n = audio_recv(0, buf, &ts); #endif if (n != sndbuf_len) { tracef("%s(): (n=%d != sndbuf_len)!", __func__, n); } else { if (audio_drv.stream_enabled) { #if !DISABLE_JITBUF jitbuf_enqueue(&audio_drv.jitbuf, buf, ts); #endif } } #if DISABLE_JITBUF xfr_buf = buf; #else sndbuf_free(buf); #endif } }
int timer_isr_task(void * arg) { int self = thinkos_thread_self(); struct stm32f_tim * tim6 = STM32F_TIM6; uint32_t latency; uint32_t ticks; uint32_t ev; printf(" [%d] started.\n", self); while (1) { __thinkos_irq_wait(STM32F_IRQ_TIM6); latency = tim6->cnt; ev = tim6->sr; if (ev == 0) continue; /* Clear update interrupt flag */ tim6->sr = 0; if (meter.max.tim6 < latency) meter.max.tim6 = latency; meter.avg.tim6 = (meter.avg.tim6 * 63) / 64 + latency; ticks = meter.ticks.tim6; meter.ticks.tim6 = ticks + 1; #if 0 if (ticks & 1) stm32f_gpio_set(STM32F_GPIOB, 7); else stm32f_gpio_clr(STM32F_GPIOB, 7); #endif } return 0; }
void __attribute__((noreturn)) supervisor_task(void) { struct trace_entry trace; uint32_t clk; uint32_t dump_tmo; int n; INF("<%d> started...", thinkos_thread_self()); /* set the supervisor stream to stdout */ trace_file = stdout; /* enable auto flush */ trace_auto_flush = true; trace_tail(&trace); #if 0 struct sockaddr_in sin; struct udp_pcb * udp; bool udp_enabled; if ((udp = udp_alloc()) == NULL) { abort(); } if (!inet_aton(trace_host, &sin.sin_addr)) { abort(); } sin.sin_port = htons(trace_port); if (udp_bind(udp, INADDR_ANY, htons(10)) < 0) { abort(); } // if (udp_connect(udp, sin.sin_addr.s_addr, htons(sin.sin_port)) < 0) { // abort(); // } #endif clk = thinkos_clock(); dump_tmo = clk + 15000; for (;;) { char msg[80]; /* 8Hz periodic task */ clk += 125; thinkos_alarm(clk); // udp_enabled = trace_udp_enabled; while (trace_getnext(&trace, msg, sizeof(msg)) >= 0) { struct timeval tv; char s[128]; trace_ts2timeval(&tv, trace.dt); if (trace.ref->lvl <= TRACE_LVL_WARN) n = sprintf(s, "%s %2d.%06d: %s,%d: %s\n", trace_lvl_nm[trace.ref->lvl], (int)tv.tv_sec, (int)tv.tv_usec, trace.ref->func, trace.ref->line, msg); else n = sprintf(s, "%s %2d.%06d: %s\n", trace_lvl_nm[trace.ref->lvl], (int)tv.tv_sec, (int)tv.tv_usec, msg); /* write log to local console */ fwrite(s, n, 1, trace_file); #if 0 if (udp_enabled) { /* sent log to remote station */ if (udp_sendto(udp, s, n, &sin) < 0) { udp_enabled = false; } } #endif } if (trace_auto_flush) trace_flush(&trace); if ((int32_t)(clk - dump_tmo) >= 0) { const struct thinkos_thread_inf * infbuf[33]; uint32_t cycbuf[33]; uint32_t cycsum = 0; uint32_t cycbusy; uint32_t cycidle; uint32_t cycdiv; uint32_t idle; uint32_t busy; int n; int i; thinkos_critical_enter(); thinkos_thread_inf(infbuf); n = thinkos_cyccnt(cycbuf); thinkos_critical_exit(); cycsum = 0; for (i = 0; i < n; ++i) cycsum += cycbuf[i]; cycidle = cycbuf[n - 1]; /* The last item is IDLE */ cycbusy = cycsum - cycidle; cycdiv = (cycsum + 5000) / 10000; busy = (cycbusy + (cycdiv / 2)) / cycdiv; idle = 1000 - busy; printf("CPU usage: %d.%02d%% busy, %d.%02d%% idle\n", busy / 100, busy % 100, idle / 100, idle % 100); for (i = 0; i < n; ++i) { const struct thinkos_thread_inf * inf; if (((inf = infbuf[i]) != NULL) && (cycbuf[i] != 0)) { uint32_t usage; usage = (cycbuf[i] + cycdiv / 2) / cycdiv; printf("%2d %7s %3d.%02d%%\n", i, inf->tag, usage / 100, usage % 100); } } dump_tmo = clk + 15000; } } }
void audio_io_task(void) { sndbuf_t * out_buf; sndbuf_t * in_buf; uint32_t ts = 0; int i; tracef("%s(): <%d> started...", __func__, thinkos_thread_self()); tonegen_init(&tonegen, 0, 0); spectrum_init(&audio_tx_sa, SAMPLE_RATE); spectrum_init(&audio_rx_sa, SAMPLE_RATE); for (;;) { #if DISABLE_JITBUF out_buf = xfr_buf; #else out_buf = jitbuf_dequeue(&audio_drv.jitbuf); #endif if (audio_drv.tone_mode == TONE_DAC) { if (out_buf == NULL) { if ((out_buf = sndbuf_alloc()) != NULL) tonegen_apply(&tonegen, out_buf); else out_buf = (sndbuf_t *)&sndbuf_zero; } } else { if (out_buf == NULL) { #if 0 tracef("%s(): out_buf == NULL!", __func__); #endif out_buf = (sndbuf_t *)&sndbuf_zero; } } spectrum_rec(&audio_tx_sa, out_buf); in_buf = i2s_io(out_buf); for (i = 0; i < SNDBUF_LEN; i++) in_buf->data[i] = FxaIirApply(&iir_hp_120hz, in_buf->data[i]); // in_buf->data[i] = FxaIirApply(&iir_hp_240hz, in_buf->data[i]); led_flash(LED_I2S, 100); if (in_buf != &sndbuf_null) { if (audio_drv.tone_mode == TONE_ADC) tonegen_apply(&tonegen, in_buf); spectrum_rec(&audio_rx_sa, in_buf); } if (audio_drv.stream_enabled) { #if ENABLE_G711 if (g711_alaw_send(0, in_buf, ts) < 0) { tracef("%s(): net_send() failed!", __func__); } #else if (audio_send(0, in_buf, ts) < 0) { tracef("%s(): net_send() failed!", __func__); } #endif led_flash(LED_NET, 100); } ts += SNDBUF_LEN; sndbuf_free(in_buf); sndbuf_free(out_buf); } }
int cmd_ping(FILE * f, int argc, char ** argv) { struct raw_pcb * raw; uint8_t buf[BUF_LEN]; in_addr_t ip_addr; struct sockaddr_in sin; struct iphdr * ip; struct icmphdr * icmp; uint8_t * data; int iphdrlen; int datalen; char s[16]; int len; int id; int seq; int32_t dt; uint32_t ts; uint32_t now; int i; int n; int ret = 0; if (argc < 2) { fprintf(f, msg_ping_usage); return SHELL_ERR_ARG_MISSING; } if (argc > 3) { fprintf(f, msg_ping_usage); return SHELL_ERR_EXTRA_ARGS; } if (strcmp(argv[1], "help") == 0) { fprintf(f, "ping - send ICMP ECHO_REQUEST to network host\n"); fprintf(f, msg_ping_usage); return 0; } if (inet_aton(argv[1], (struct in_addr *)&ip_addr) == 0) { fprintf(f, "ip address invalid.\n"); return SHELL_ERR_ARG_INVALID; } if (argc > 2) { n = strtol(argv[2], NULL, 0); } else { n = 5; } raw = raw_pcb_new(IPPROTO_ICMP); id = thinkos_thread_self(); datalen = DATA_LEN; fprintf(f, "PING %s: %d octets data.\n", inet_ntop(AF_INET, (void *)&ip_addr, s, 16), datalen); for (seq = 1; seq <= n; seq++) { icmp = (struct icmphdr *)(void *)buf; icmp->type = ICMP_ECHO; icmp->un.echo.id = id; icmp->un.echo.sequence = seq; data = buf + sizeof(struct icmphdr); for (i = 0; i < datalen; i++) { data[i] = i; } len = datalen + sizeof(struct icmphdr); sin.sin_addr.s_addr = ip_addr; sin.sin_family = AF_INET; ts = thinkos_clock(); // gettimeofday(&tv, NULL); memcpy(data, &ts, sizeof(uint32_t)); icmp->chksum = 0; icmp->chksum = ~in_chksum(0, icmp, len); raw_sendto(raw, buf, len, (struct sockaddr_in *)&sin); len = raw_recvfrom_tmo(raw, buf, BUF_LEN, (struct sockaddr_in *)&sin, 1000); if (len < 0) { if (len != -ETIMEDOUT) { ret = -1; break; } fprintf(f, "timed out.\n"); continue; } now = thinkos_clock(); ip = (struct iphdr *)buf; iphdrlen = ip->hlen * 4; icmp = (struct icmphdr *)(buf + iphdrlen); if ((icmp->type == ICMP_ECHOREPLY) && (icmp->un.echo.id == id)) { memcpy(&ts, buf + iphdrlen + sizeof(struct icmphdr), sizeof(uint32_t)); len -= iphdrlen + sizeof(struct icmphdr); dt = (int32_t)(now - ts); fprintf(f, "%d octets from %s: icmp_seq=%d " "ttl=%d time=%d ms\n", len, inet_ntop(AF_INET, (void *)&sin.sin_addr, s, 16), icmp->un.echo.sequence, ip->ttl, dt); } else { fprintf(f, "icmp: %d\n", icmp->type); } thinkos_sleep(250); } raw_close(raw); return ret; }
void __attribute__((noreturn)) serial_ctrl_task(struct vcom * vcom) { struct serial_dev * serial = vcom->serial; struct usb_cdc_class * cdc = vcom->cdc; struct usb_cdc_state prev_state; struct usb_cdc_state state; DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self()); usb_cdc_state_get(cdc, &prev_state); while (1) { DCC_LOG1(LOG_INFO, "[%d] usb_cdc_ctl_wait() sleep!", thinkos_thread_self()); usb_cdc_ctl_wait(cdc, 0); DCC_LOG1(LOG_INFO, "[%d] wakeup!", thinkos_thread_self()); usb_cdc_state_get(cdc, &state); if (state.flags != prev_state.flags) { if (state.suspended) { DCC_LOG1(LOG_TRACE, "[%d] suspending...", thinkos_thread_self()); } else { if (prev_state.suspended) { DCC_LOG1(LOG_TRACE, "[%d] wakeup from suspended!", thinkos_thread_self()); } } prev_state.flags = state.flags; } if (state.ctrl.dtr != prev_state.ctrl.dtr) { vcom->ser_stat.dsr = state.ctrl.dtr; usb_cdc_status_set(cdc, &vcom->ser_stat); prev_state.ctrl = state.ctrl; } if ((state.cfg.baudrate != prev_state.cfg.baudrate) || (state.cfg.databits != prev_state.cfg.databits) || (state.cfg.parity != prev_state.cfg.parity) || (state.cfg.stopbits != prev_state.cfg.stopbits)) { serial_rx_disable(serial); DCC_LOG1(LOG_TRACE, "baudrate=%d", state.cfg.baudrate); DCC_LOG1(LOG_TRACE, "databits=%d", state.cfg.databits); DCC_LOG1(LOG_TRACE, "parity=%d", state.cfg.parity); DCC_LOG1(LOG_TRACE, "stopbits=%d", state.cfg.stopbits); if (state.cfg.baudrate == 921600) { vcom->mode = VCOM_MODE_SERVICE; DCC_LOG(LOG_TRACE, "magic config!"); } else { vcom->mode = VCOM_MODE_CONVERTER; serial_config_set(serial, &state.cfg); prev_state.cfg = state.cfg; // serial_enable(serial); serial_rx_enable(serial); } } } }