//============================================================================ // Two-tasks implementation // Urgent task = liner // Slow task = uturn // Freshest value communication version //============================================================================= #include #include #include "code/FreeRTOS_Utils.h" #include "code/BatCar.h" #include "liner.h" #include "uturn.h" //------------------------------------------------------------- // Utils //------------------------------------------------------------- // Macros to ease debug #define PVAR(X) Serial.print(#X"="); Serial.print(X); Serial.print(' '); #define PVARLN(X) Serial.print(#X"="); Serial.println(X); //------------------------------------------------------------- // Interface with lustre code (output functions) //------------------------------------------------------------- //TODO: declare here the variables necessary for the task communication // uturn -> liner variables, // MUST BE CORRECTLY INITIALIZED bool do_turn = false; int mlt = 0; int mrt = 0; // liner -> uturn variables, // initialization not necessary (priority) bool running, ww, wb, bw, bb; //TODO: define here the output functions of liner task... //... to BatCar void uturn_O_buzzer(bool v) { BatCar.set_buzzer(!v); } //... to liner void uturn_O_do_turn(bool v) { do_turn=v; } void uturn_O_mlt(int v) { mlt=v; } void uturn_O_mrt(int v) { mrt=v; } //TODO: define here the output functions of liner task //... to BatCar void liner_O_motor_left(int s){ BatCar.set_left_speed(s); } void liner_O_motor_right(int s){ BatCar.set_right_speed(s); } void liner_O_red_light(bool v){ BatCar.set_red_light(v); } void liner_O_yellow_light(bool v){ BatCar.set_yellow_light(v); } void liner_O_green_light(bool v){ BatCar.set_green_light(v); } //... to uturn void liner_O_running(bool v){ running = v; } void liner_O_ww(bool v){ ww = v; } void liner_O_wb(bool v){ wb = v; } void liner_O_bw(bool v){ bw = v; } void liner_O_bb(bool v){ bb = v; } //------------------------------------------------------------- // FreeRTOS tasks // - Expected profile: void vATaskFunction(void *pvParameters) // pvParameters = user client-data, not used here // - this is typically a never-endind procedure. i.e. // reactive loop is implemented here // - Real-time parameters: // * OFFSET: a delay before starting // * PERIOD: the delay between 2 steps // * N.b. delays are in system tick (i.e. 15ms) //------------------------------------------------------------- #define OFFSET 5 #define FAST_PERIOD 1 void liner_task(void* _dummy){ //TODO: (REAL TIME) periodic timer initialization // Initialize xLastWakeTime with current ABSOLUTE time. TickType_t xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); //TODO: (REAL TIME) Wait offest vTaskDelayUntil(&xLastWakeTime, OFFSET); // Core of the task = infinite control loop for(;;){ //TODO: here, sample (read) necessary input from the SBC // and 'send' it the lustre program liner_I_k1(BatCar.button_pressed()); liner_I_sensor_left(BatCar.line_sensor_left()); liner_I_sensor_right(BatCar.line_sensor_right()); //TODO: here, sample (read) necessary input from uturn task // and 'send' it the lustre program liner_I_do_turn(do_turn); liner_I_ml_turn(mlt); liner_I_mr_turn(mrt); //TODO: here, call the lustre step liner_step(); //N.b. noting to do for outputs, they are sent //to the lustre program via the _O_ procedures //TODO: (REAL TIME) 'sleep' until next peiod vTaskDelayUntil( &xLastWakeTime, FAST_PERIOD); } } #define SLOW_PERIOD 1 void uturn_task(void* _dummy){ //TODO: (REAL TIME) periodic timer initialization // Initialize xLastWakeTime with current ABSOLUTE time. TickType_t xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); //TODO: (REAL TIME) Wait offest vTaskDelayUntil(&xLastWakeTime, OFFSET); // Core of the task = infinite control loop for(;;){ //TODO: here, sample (read) necessary input from the SBC // and 'send' it the lustre program uturn_I_odist(BatCar.ultrasonic_sensor_distance()); //TODO: here, sample (read) necessary input from liner task // and 'send' it the lustre program uturn_I_running(running); uturn_I_ww(ww); uturn_I_wb(wb); uturn_I_bw(bw); uturn_I_bb(bb); //TODO: here, call the lustre step uturn_step(); //N.b. noting to do for outputs, they are sent //to the lustre program via the _O_ procedures //TODO: (REAL TIME) 'sleep' until next peiod vTaskDelayUntil( &xLastWakeTime, SLOW_PERIOD); } } //------------------------------------------------------------- // Arduino setup and loop core //------------------------------------------------------------- void setup() { Serial.begin(9600); // Set Serial baud rate 9600 // INIT SmartBatCar //TODO: put here the necessary initializations (see code/BatCar.h) BatCar.init_motors(); BatCar.init_button(); BatCar.init_buzzer(); BatCar.init_lights(); BatCar.init_line_sensors(); BatCar.init_ultrasonic_sensor(); //INIT LUSTRE CODE //TODO: put here the initialization of lustre program liner_reset(); uturn_reset(); //CREATE TASK //TODO: create liner task with suitable priority xTaskCreate( *liner_task, // pointer to task code (void *f(void*)) "BatCar Liner Task", // name of the task (const char*) put what you want configMINIMAL_STACK_SIZE, // stack size, use this default value constant NULL, //Parameter to pass to control_task, not used 1, //Priority, must be the highest NULL //Where to store the created handler, not used ); //TODO: create uturn task with suitable priority xTaskCreate( *uturn_task, // pointer to task code (void *f(void*)) "BatCar Uturn Task", // name of the task (const char*) put what you want configMINIMAL_STACK_SIZE, // stack size, use this default value constant NULL, //Parameter to pass to control_task, not used 2, //Priority, must be the lowest NULL //Where to store the created handler, not used ); //TODO: start the FreeRTOS scheduler Serial.println("START TASKS"); vTaskStartScheduler(); //Dummy infinite loop => unreachable for (;;) ; } void loop() { //empty: unreachable }