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.
Disassembler does not split events.
-
- Experienced Member
- Posts: 75
- Joined: Sat May 07, 2016 11:47 am
-
- Active Member
- Posts: 55
- Joined: Fri Mar 04, 2011 3:38 pm
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
Cheers,
Sam
-
- Experienced Member
- Posts: 75
- Joined: Sat May 07, 2016 11:47 am
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:
Disassembler is not able to show seperate events for this function:
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.
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;
}
}
}
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.