Disassembler does not split events.

Technical questions regarding the XTC tools and programming with XMOS.
mozcelikors
Experienced Member
Posts: 75
Joined: Sat May 07, 2016 11:47 am

Disassembler does not split events.

Post by mozcelikors »

Hello everyone,
I am trying to count the instruction count that seperate events require.
I have decided to do it via Disassembly window as XTA caused issues with some branches, memset, memcpy etc.
The problem I'm having with Disassembly is that,
Sometimes it splits select-case events which is what I want.
But for some functions it does not do that, even though I have many case blocks.
Does anyone know why? If so, I'd appreciate an explanation.

Image


User avatar
xsamc
Active Member
Posts: 55
Joined: Fri Mar 04, 2011 3:38 pm

Post by xsamc »

Could it be that the tasks are run differently, perhaps one is distributed, and one is combined for example? I believe that the complier will only generate the additional init and enable functions when they are required (e.g. the specific usage in this application requires them as they are called across multiple cores).

Cheers,
Sam
mozcelikors
Experienced Member
Posts: 75
Joined: Sat May 07, 2016 11:47 am

Post by mozcelikors »

Hmm, but both functions have select-case events that I want to analyze.
Let me show you with the code.

Disassembler is able to show the events of this function:

Code: Select all

[[combinable]]
void Task_SteeringServo_MotorController (out port p, server steering_if steering_interface)
{
    uint32_t overall_pwm_period = STEERINGSERVO_PWM_PERIOD;
    uint32_t on_period;
    uint32_t off_period;

    uint32_t time;
    int port_state = 0;
    timer tmr;

    int steering;

    //PrintCoreAndTileInformation("Task_SteeringServo_MotorController");

    // Timing measurement/debugging related definitions
    timer debug_timer;
    uint32_t start_time, end_time;

    while (1)
    {
        select
        {
            //Wait for the steering value
            case steering_interface.ShareSteeringValue (int steering_val):
                steering = steering_val;
                break;

            //Calculate PWM periods and apply period within the timer
            case tmr when timerafter(time) :> void :
                //Measure start time
                ////debug_timer :> start_time;

                tmr :> time;

                if  (steering == 0)
                {
                    on_period = STEERINGSERVO_PWM_MAXRIGHT_PULSE_WIDTH;
                }
                else if (steering > 100)
                {
                    on_period = STEERINGSERVO_PWM_MAXLEFT_PULSE_WIDTH;
                }
                else
                {
                    on_period = (STEERINGSERVO_PWM_MAXRIGHT_PULSE_WIDTH - ((STEERINGSERVO_PWM_MAXRIGHT_PULSE_WIDTH - STEERINGSERVO_PWM_MAXLEFT_PULSE_WIDTH) * (steering/100.0)));
                }

                off_period = overall_pwm_period - on_period;

                //PWM Port Toggling
                if(port_state == 0)
                {
                    p <: 1;
                    port_state = 1;
                    time += on_period; //Extend timer deadline
                }
                else if(port_state == 1)
                {
                    p <: 0;
                    port_state = 0;
                    time += off_period; //Extend timer deadline
                }

                //Measure end time
                ////debug_timer :> end_time;
                ////printf("SERVO t: %u", end_time - start_time);

                break;

        }
    }
}

Disassembler is not able to show seperate events for this function:

Code: Select all

[[combinable]]
void Task_GetRemoteCommandsViaBluetooth(client uart_tx_if uart_tx,
                                        client uart_rx_if uart_rx,
                                        client control_if control_interface,
                                        client steering_if steering_interface,
                                        server ethernet_to_cmdparser_if cmd_from_ethernet_to_override,
                                        client lightstate_if lightstate_interface)
{
    //Debugging related definitions
    timer tmr2;
#define RCCAR_STATUS_UPDATE_RATE    (50 * MILLISECOND)
    unsigned int time2, delay2 = RCCAR_STATUS_UPDATE_RATE; //.05sec
    int set_val = 0;
    int direction_val = REVERSE;
    int speed_val = 0;
    tmr2 :> time2;

    char CommandLine_Buffer[COMMANDLINE_BUFSIZE];
    int char_index = 0;
    char command[COMMANDLINE_BUFSIZE];
    int command_line_ready = 0;
    int speed = 0;
    int steering = 50;
    int direction = FORWARD;
    int previous_direction = FORWARD;

    int ctr = 0;

    char data, data1;

    //PrintCoreAndTileInformation("Task_GetRemoteCommandsViaBluetooth");

    // Timing measurement/debugging related definitions
    timer debug_timer;
    uint32_t start_time, end_time;

    char buffer2[]= "SA,0\r";                // set to open mode (no authentication)
    WriteData(uart_tx, buffer2);
    delay_microseconds(300000); //0.03sec //Wait for the response

    //Light system state
    short int lightstate = 2;
    short int previous_lightstate = 2;

#ifdef RN42_INITIAL_CONFIG
    // Send initialization commands to RN42
    // Do for only first time. Change RN42_INITIAL CONFIG section in rn42_driver.h to do so.
    InitializeRN42asSlave(uart_tx);
#endif

    while (1) {
        select
        {
            case uart_rx.data_ready(): //Read when data is available
    # pragma xta endpoint "start_uart_rx"
                //Measure start time
                //debug_timer :> start_time;

                data = uart_rx.read();
                //printf("%c",data);
                //Using so many printf's to debug causes malfunction..
                //printf("Data received: %c\n", data);
                //printf("CommandLine buffer= ");
                //for(int x = 0; x < 7; x++)
                //    printf("%c", command[x]);
                //printf("\n");
                // This section is basically dedicated to use the bytes and when the end of line reached,
                // construct the command line.
                if(data != 'E')
                {
                        CommandLine_Buffer[char_index] = data;
                        if(char_index >= COMMANDLINE_BUFSIZE-1) char_index = 0;
                        else char_index++;
                }
                else // data == E
                {
                    char_index = 0;
                    ctr = 0;
                    //Copy the string to construct the command
                    for(int x = 0; x < COMMANDLINE_BUFSIZE; x++)
                        command[x] = CommandLine_Buffer[x];

                    //Raise the command line ready flag
                    command_line_ready = 1;
                }

                //Measure end time
                ////debug_timer :> end_time;
                ////printf("RN42 t: %u", end_time - start_time);
    # pragma xta endpoint "stop_uart_rx"
                break;

            //Whenever a command comes over ethernet to override our bluetooth commands,
            //we need to process it.
            case cmd_from_ethernet_to_override.SendCmd(char* override_command, int cmd_length):
                //printf("override command=%s\n", override_command);
    # pragma xta endpoint "start_eth_override"
                command_line_ready = 1;
                for(int k=0; k<cmd_length; k++)
                {
                    command[k] = override_command[k];
                }
    # pragma xta endpoint "stop_eth_override"
                break;
            //Process the commands received above in a timer event
            case tmr2 when timerafter(time2) :> void : // Timer event
    # pragma xta endpoint "start_timer_event_command"
                time2 += delay2;
                if ( command_line_ready )
                {
                    // Check if incoming data is as expected..
                    if ( CheckIfCommandFormatIsValid(command) == 1 )
                    {
                            {speed, steering, direction} = ParseRCCommandString (command);

                            /*lightstate = GetLightStateFromCommands (speed, steering, direction);
                            if (lightstate != previous_lightstate)
                            {
                                    lightstate_interface.ShareLightSystemState  (lightstate);
                            }*/

                            if (previous_direction == FORWARD && direction == REVERSE)
                            {
                                    //Commands to cheat into REVERSE mode, so that motor driver is ready for REVERSE movement
                                    steering_interface.ShareSteeringValue(50);
                                    control_interface.ShareDirectionValue(REVERSE);
                                    control_interface.ShareSpeedValue(11);
                                    delay_milliseconds(20);
                                    steering_interface.ShareSteeringValue(50);
                                    control_interface.ShareDirectionValue(REVERSE);
                                    control_interface.ShareSpeedValue(53);
                                    delay_milliseconds(150);
                                    steering_interface.ShareSteeringValue(50);
                                    control_interface.ShareDirectionValue(REVERSE);
                                    control_interface.ShareSpeedValue(6);
                                    delay_milliseconds(50);
                            }

                            steering_interface.ShareSteeringValue(steering);
                            control_interface.ShareDirectionValue(direction);
                            control_interface.ShareSpeedValue(speed);
                            command_line_ready = 0;
                            previous_direction = direction;
                            previous_lightstate = lightstate;

                            /*printf("speed=%i\n",speed);
                            printf("steering=%i\n",steering);
                            printf("direction=%i\n",direction);*/
                    }
                }
    # pragma xta endpoint "stop_timer_event_command"
                break;

        }
    }
}
What might be the problem?
Interestingly, the timing analyzer works perfectly on the function that Disassembler successfully divides events, but the other function the timing analyzer is not able to resolve timing for some branches.