void nx_assert_error(const char *file, const int line, const char *expr, const char *msg) { const char *basename = strrchr(file, '/'); basename = basename ? basename+1 : file; /* Try to halt as many moving parts of the system as possible. */ nx_systick_install_scheduler(NULL); nx__avr_set_motor(0, 0, TRUE); nx__avr_set_motor(1, 0, TRUE); nx__avr_set_motor(2, 0, TRUE); nx_display_clear(); nx_sound_freq_async(440, 1000); nx_display_string("** Assertion **\n"); nx_display_string(basename); nx_display_string(":"); nx_display_uint(line); nx_display_end_line(); nx_display_string(expr); nx_display_end_line(); nx_display_string(msg); nx_display_end_line(); while (nx_avr_get_button() != BUTTON_CANCEL); nx_core_halt(); }
//Arrete les moteurs et le robot avec CANCEL static void watchdog(void) { S8 data[MSG_SIZE]; switch (nx_avr_get_button()) { case BUTTON_CANCEL: nx_motors_stop(RIGHT_MOTOR, TRUE); nx_motors_stop(LEFT_MOTOR, TRUE); nx_core_halt(); case BUTTON_OK: nx_systick_wait_ms(1000); nx_motors_rotate(LEFT_MOTOR,MEDIUM_SPEED); nx_motors_rotate(RIGHT_MOTOR, MEDIUM_SPEED); break; case BUTTON_LEFT: data[0]=98; data[1]=98; nx_bt_stream_write((U8 *)data, 2); nx_systick_wait_ms(1000); break; case BUTTON_RIGHT: data[0]=99; data[1]=99; nx_bt_stream_write((U8 *)data, 2); nx_systick_wait_ms(1000); break; case BUTTON_NONE: break; } }
bool nx_cmd_interpret(U8 *buffer, size_t len, bool *req_ack) { U8 cmd; bool (*call) (U8, U8 *) = NULL; if (len < 6) return FALSE; cmd = buffer[0]; *req_ack = FALSE; buffer++; switch (MSK_ACTION(cmd)) { case HALT: nx_core_halt(); break; case ROTATE: call = wheel_rotate; break; case STOP: call = wheel_stop; break; case MOVE: call = robot_move; break; case GET: *req_ack = TRUE; call = get_info; break; default: return FALSE; } return call(cmd, buffer); }
/* This is where most of the magic happens. This function gets called * every millisecond to handle scheduling decisions. */ static void scheduler_cb(void) { U32 time = nx_systick_get_ms(); bool need_reschedule = FALSE; /* Security mechanism: in case the system crashes, as long as the * scheduler is still running, the brick can be powered off. */ if (nx_avr_get_button() == BUTTON_CANCEL) nx_core_halt(); /* If the scheduler state is locked, nothing can be done. */ if (sched_lock > 0) return; sched_lock = 1; /* Process pending commands, if any */ if (task_command != CMD_NONE) { switch (task_command) { case CMD_YIELD: need_reschedule = TRUE; break; case CMD_DIE: destroy_running_task(); need_reschedule = TRUE; break; default: break; } task_command = CMD_NONE; nx_systick_unmask_scheduler(); } else { /* Check if the task quantum for the running task has expired. */ if (time - sched_state.last_context_switch >= TASK_EXECUTION_QUANTUM) need_reschedule = TRUE; } /* Wake up tasks that have scheduled alarms. */ while (!mv_list_is_empty(sched_state.alarms_pending) && sched_state.alarms_pending->wakeup_time <= time) { struct mv_alarm_entry *a = sched_state.alarms_pending; mv_list_remove(sched_state.alarms_pending, sched_state.alarms_pending); mv__scheduler_task_unblock(a->task); nx_free(a); } /* Task switching time? */ if (need_reschedule) { if (sched_state.task_current != NULL) sched_state.task_current->stack_current = mv__task_get_stack(); reschedule(); mv__task_set_stack(sched_state.task_current->stack_current); sched_state.last_context_switch = nx_systick_get_ms(); } sched_lock = 0; }
/** * Arret du robot */ void die(void) { nx_display_string("dying...\n"); nx_motors_stop(LEFT_MOTOR, TRUE); nx_motors_stop(RIGHT_MOTOR, TRUE); nx_radar_close(RADAR_SENSOR); bt_die(); nx_systick_wait_ms(2000); nx_core_halt(); }
/* The security hook lets the tester shut down the brick despite the * main thread of execution being locked up due to a bug. As long as * the system timer and AVR link are working, pressing the Cancel * button should power off the brick. */ static void security_hook(void) { if (nx_avr_get_button() == BUTTON_CANCEL) nx_core_halt(); }
void main() { /* We want to draw a moving ellipse, two arcs and two lines */ /* Declaring center point of the ellipse / arcs and points representing the lines */ point ellipse_c, q, r, s, t, u, v, w; /* Initialize ellipse center position */ ellipse_c.x = 1; ellipse_c.y = 1; /* Initialize the first line position*/ q.x = 3; q.y = 63; s.x = 28; s.y = 63; /* Initialize the second line position */ r.x = 102; r.y = 63; t.x = 76; t.y = 63; /* initialize the triangle position */ u.x = 48; u.y = 33; v.x = 48; v.y = 45; w.x = 61; w.y = 39; /* Superior radius of the ellipse */ U8 sradius = 85; /* Difference between the superior and inferior radius of the ellipse */ U8 delta = 73; /* Offset angle for arcs rotation */ U32 offset_angle = 60; /* Disable auto refresh of the screen, we want to control each frame */ nx_display_auto_refresh(FALSE); /* Loop until the cancel button is pushed Each loop iteration represent a frame composed of three steps*/ while (nx_avr_get_button() != BUTTON_CANCEL) { /* Clear the screen */ nx_display_clear(); /* First step of the frame : calculate positions and parameters of shapes */ /* If the ellipse is in the first half of the screen, make it follow a pseudo sinusoidal path */ if(ellipse_c.x < 53) { ellipse_c.x ++; delta--; ellipse_c.y = (30 * sinf( ((float) ellipse_c.x) / 25) + 4); } /* If the ellipse have past the first third of the screen, then start to move lines and rotate arcs */ if(ellipse_c.x > 34) { if(ellipse_c.x < 49) { q.x = (q.x) + 2; s.x = (s.x) + 2; r.x = (r.x) - 2; t.x = (t.x) - 2; offset_angle += ellipse_c.x; } else if(offset_angle > 5) offset_angle -= 5; } /* Second step of the frame : draw shapes on the screen buffer*/ /* If the ellipse have past the first third of the screen, draw moving arcs around and lines at the bottom of the screen */ if(ellipse_c.x > (34)) { nx_display_arc(ellipse_c, 27, 45, offset_angle); nx_display_arc(ellipse_c, 27, 45, (180 + offset_angle)); nx_display_line(q, s); nx_display_line(r, t); } /* If the ellipse is at the middle of the screen, write "NxOS on the screen */ if(ellipse_c.x > 52) { nx_display_cursor_set_pos(7, 3); nx_display_string("NxOS"); } /* Just draw the ellipse, every frame */ nx_display_ellipse(ellipse_c, (sradius / 4), ((sradius - delta) / 3), (ellipse_c.x * 20) ); nx_display_triangle(u, v, w); /* Last step of the frame : refresh the screen */ nx_display_refresh(); /* Wait a bit before next frame */ nx_systick_wait_ms(85); } /* Shutdown the brick */ nx_core_halt(); }
void nx__kernel_main(void) { core_init(); check_boot_errors(); main(); nx_core_halt(); }
/* A simple shutdown hook that lets you power down the brick if * something goes wrong. See the scheduler example kernel for details * on this. */ static void shutdown_hook(void) { if (nx_avr_get_button() == BUTTON_CANCEL) nx_core_halt(); }