In the unit Embedded and Real Time System, I had had the chance to worked with the TI-Robotics-System-Learning-Kit, where I learnt much more about embedded real time system
Polling Vs Interrupts
The task was to develop a program that allows the robot that has two modes of operations using both polling and interrupts techniques:
(Operation 1: Autonomous mode) upon pressing switch SW1, the robot operates
using predefined route and immediately stop when any of bump switches are
touched.
(Operation 2: Free-motion mode) upon pressing switch SW2, the robot freely move
forward but will change direction of movement according to the interrupted bump
switches.
Measure and compare interrupt latency and polling latency
Example of using bitwise operations to program the motor to move:
// Function: dcMotor_Left // Description: Drives the left motor forward and the right motor backward voiddcMotor_Left(uint16_t duty, uint32_t period){ P1->OUT &= ~0xC0; P2->OUT &= ~0xC0;
uint32_t i;
// Motor Turn Left P1->DIR |= 0x80; P1->OUT |= 0x80;
for(i=0; i<period; i++){ P2->OUT |= 0xC0; // on vTaskDelay( 1 ); P2->OUT &= ~0xC0; // off vTaskDelay( 1 ); }
P1->OUT &= ~0xC0; P2->OUT &= ~0xC0; }
Real-Time Operating System (RTOS) with Round Robin Algorithm
Use Real-time operating system (RTOS) to achieve Autonomous mode and Free-motion mode while having music playing simultaneously
Use of Round Robin algorithm as scheduling mechanism in RTOS.
Scheduling CPU usage and managing shared resources
staticvoidtaskInterrupt(void *pvParamters){ //Initialise the interrupt EnableInterrupts(); // Clear the I bit
for ( ;; ){ xSemaphoreTake(xBSemaphore, portMAX_DELAY); dcMotor_Stop(1); vTaskSuspend(taskHandle_Main); vTaskSuspend(taskHandle_PlaySong); //Make sure the motor is stopped
//change colours - value stored in the global variable outputLED_response_ISR(bumpSwitch_status);
//look at which mode we are on if (mode == 1){ dcMotor_Stop(1); stop = 1; } elseif (mode == 2){ dcMotor_response_interrupt(bumpSwitch_status); vTaskResume(taskHandle_PlaySong); }
} } //--------------------------Interrupt functions ----------------------- // // // // // //--------------------------Polling functions ----------------------- // a static void function for taskReadInputSwitch staticvoidtaskReadInputSwitch( void *pvParameters ){ // This function act as a switch press once to stop playing, // press second time to resume
char i_SW1=0; int i;
for( ;; ) { if (SW1IN == 1) { // 1 means being pressed mode=1; flag=0; i_SW1 ^= 1; // toggle the variable i_SW1 for (i=0; i<1000000; i++); // this waiting loop is used // to prevent the switch bounce. }
elseif (SW2IN == 1){ mode=2; flag=0; for (i=0; i<1000000; i++); // this waiting loop is used // to prevent the switch bounce. }
} }
// TODO: create a static void function for taskBumpSwitch staticvoidtaskBumpSwitch(void *pvParameters){ // TODO: initialise bump switches BumpSwitch_Init(); // TODO: Read the input of bump switches forever: // Continuously read the 6 bump switches in a loop, // and return it to the "bumpSwitch_status" variable. // Note that the bumpSwitch_status is a global variable, // so do not declare it again here locally. for( ;; ){ // TODO: use bumpSwitch_status as the variable and // use Bump_Read_Input to read the input bumpSwitch_status = Bump_Read_Input(); } }
// TODO: create a static void function for taskDisplayOutputLED staticvoidtaskDisplayOutputLED(void *pvParameters){ for( ;; ){ // TODO: use outputLED_response as the function and // use bumpSwitch_status as the parameter outputLED_response(bumpSwitch_status); } }
// TODO: create a static void function for taskdcMotor staticvoidtaskdcMotor(void *pvParameters){
// TODO: initialise the DC Motor dcMotor_Init();
// TODO: use a polling that continuously read from the bumpSwitch_status, // and run this forever in a while loop. // use dcMotor_response and bumpSwitch_status for the parameter for ( ;; ){ if (mode==1){
flag=dcMotor_stop_flag(bumpSwitch_status);
while (flag==1){ dcMotor_Stop(500); } vTaskSuspend(taskHandle_PlaySong);