error: service called in non multi-tile function Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
aclassifier
Respected Member
Posts: 507
Joined: Wed Apr 25, 2012 8:52 pm

error: service called in non multi-tile function

Post by aclassifier »

I am trying out a combination of [[combinable]], placed with on and [[combine]]. The goal is to end up with fewer chanends (I will also replace c_buttons with interface once I get the below to work). Below is the top level code where I get the error: service called in non multi-tile function message, else all seems fine:

Code: Select all

int main() {
    chan c_buttons[BUTTONS_NUM_CLIENTS]; // Individual
    chan c_analogue;

    i2c_external_commands_if       i_i2c_external_commands[I2C_EXTERNAL_NUM_CLIENTS];
    i2c_internal_commands_if       i_i2c_internal_commands[I2C_INTERNAL_NUM_CLIENTS];
    startkit_adc_acquire_if        i_startkit_adc_acquire;
    lib_startkit_adc_commands_if   i_lib_startkit_adc_commands[ADC_STARTKIT_NUM_CLIENTS];
    port_heat_light_commands_if    i_port_heat_light_commands[PORT_HEAT_LIGHT_SERVER_NUM_CLIENTS];
    temperature_heater_commands_if i_temperature_heater_commands[HEATER_CONTROLLER_NUM_CLIENTS];
    temperature_water_commands_if  i_temperature_water_commands;

    #define MAP_CHANENDS_27_A // If MAP_PAR_COMBINE == 0

    #if (MAP_PAR_COMBINE == 1)
    par {

        Port_Pins_Heat_Light_Task (i_port_heat_light_commands);
        installExceptionHandler();
        My_startKIT_ADC_Task      (i_startkit_adc_acquire, i_lib_startkit_adc_commands, NUM_STARTKIT_ADC_NEEDED_DATA_SETS);
        startkit_adc              (c_analogue); // Declare the ADC service (this is the ADC hardware, not a task)
        // ^~~~~~~~~~~~ error: service called in non multi-tile function
        [[combine]]
        par {
            I2C_Internal_Task         (i_i2c_internal_commands);
            I2C_External_Task         (i_i2c_external_commands);
            System_Task               (i_i2c_internal_commands[0], i_i2c_external_commands[0], i_lib_startkit_adc_commands[0],
                                       i_port_heat_light_commands[0], i_temperature_heater_commands[0], i_temperature_water_commands,
                                       c_buttons);
            Temperature_Heater_Task   (i_temperature_heater_commands, i_i2c_external_commands[1], i_port_heat_light_commands[1]);
            Temperature_Water_Task    (i_temperature_water_commands, i_temperature_heater_commands[1]);
            Button_Task               (IOF_BUTTON_LEFT,   inP_button_left,   c_buttons[IOF_BUTTON_LEFT]);
            Button_Task               (IOF_BUTTON_CENTER, inP_button_center, c_buttons[IOF_BUTTON_CENTER]);
            Button_Task               (IOF_BUTTON_RIGHT,  inP_button_right,  c_buttons[IOF_BUTTON_RIGHT]);
            adc_task                  (i_startkit_adc_acquire, c_analogue, ADC_PERIOD_TIME_USEC_ZERO_IS_ONY_QUERY_BASED);
        }
    }
    #elif defined MAP_CHANENDS_27_A
    // WORKS and LIGHT STABLE
    /* Constraint check for tile[0]:
      Cores available:            8,   used:          7 .  OKAY
      Timers available:          10,   used:          8 .  OKAY
      Chanends available:        32,   used:         27 .  OKAY
      Memory available:       65536,   used:      52772 .  OKAY
        (Stack: 8212, Code: 38342, Data: 6218)
    Constraints checks PASSED.
    Build Complete */
    par {
        on tile[0]: installExceptionHandler();

        on tile[0].core[0]: I2C_Internal_Task         (i_i2c_internal_commands);
        on tile[0].core[4]: I2C_External_Task         (i_i2c_external_commands);
        on tile[0]:         System_Task               (i_i2c_internal_commands[0], i_i2c_external_commands[0], i_lib_startkit_adc_commands[0],
                                                       i_port_heat_light_commands[0], i_temperature_heater_commands[0], i_temperature_water_commands,
                                                       c_buttons);
        on tile[0].core[0]: Temperature_Heater_Task   (i_temperature_heater_commands, i_i2c_external_commands[1], i_port_heat_light_commands[1]);
        on tile[0].core[5]: Temperature_Water_Task    (i_temperature_water_commands, i_temperature_heater_commands[1]);
        on tile[0].core[1]: Button_Task               (IOF_BUTTON_LEFT,   inP_button_left,   c_buttons[IOF_BUTTON_LEFT]);
        on tile[0].core[1]: Button_Task               (IOF_BUTTON_CENTER, inP_button_center, c_buttons[IOF_BUTTON_CENTER]);
        on tile[0].core[1]: Button_Task               (IOF_BUTTON_RIGHT,  inP_button_right,  c_buttons[IOF_BUTTON_RIGHT]);
        on tile[0]:         My_startKIT_ADC_Task      (i_startkit_adc_acquire, i_lib_startkit_adc_commands, NUM_STARTKIT_ADC_NEEDED_DATA_SETS);
        on tile[0].core[5]: Port_Pins_Heat_Light_Task (i_port_heat_light_commands);
        on tile[0].core[4]: adc_task                  (i_startkit_adc_acquire, c_analogue, ADC_PERIOD_TIME_USEC_ZERO_IS_ONY_QUERY_BASED);
                            startkit_adc              (c_analogue); // Declare the ADC service (this is the ADC hardware, not a task)
    }
    #endif
    return 0;
}
I also use MAP_PAR_COMBINE==1 to remove [[combinable]] in Port_Pins_Heat_Light_Task.

However, I am uncertain about the "service" term and how this may be solved above.

I have tried several, but it's difficult when I don't understand the underlying basics. (MAP_CHANENDS_27_A works fine)
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
View Solution
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

The term 'service' refers to the ADC task that is actually hardware, rather than software running on a logical core.
This hardware can be connected to via a channel, as long as the other end of the channel is on the same tile.

The compiler is unhappy picking 'startkit_adc' without being given a tile.
This seems a little unhelpful as if it worked a bit harder it could probably work it out for itself and decide if everything is fine or not.
For now you need to specify the tile (hence it becomes a multi-tile main function of 1 tile!), as you do so in the second working block.

As you have found, you can explicitly combine 'combinable' tasks by placing them on the same tile-core id (the unique core id can be what ever you want it to be).
Alternatively you can place nested pars on a tile viz:

Code: Select all

  on tile [0] : [[combine]] par {...}
I hope that helps
Robert
User avatar
aclassifier
Respected Member
Posts: 507
Joined: Wed Apr 25, 2012 8:52 pm

Post by aclassifier »

Off Topic
Everything helps! The fun thing about XC and XCORE is that there always seem to be a next question. Never boring!
The compiler is unhappy picking 'startkit_adc' without being given a tile.
If I go

Code: Select all

par {
    on tile[0]: startkit_adc (c_analogue); // Declare the ADC service (this is the ADC hardware, not a task)
                ^ error: call to service prefixed with `on'
or

Code: Select all

on tile[0]: {
    par {
        startkit_adc (c_analogue); // Declare the ADC service (this is the ADC hardware, not a task)
        ^ error: call to service prefixed with `on'
The compiler looks rather unhappy also if I tile it!? I have always had to let startkit_adc be non-placed!?
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
aclassifier
Respected Member
Posts: 507
Joined: Wed Apr 25, 2012 8:52 pm

Post by aclassifier »

By the way, I don't think there is a service reserved word?
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

Quite right, my mistake.
It seems it needs to be around other tasks that are placed, but itself is not placed.
It may be possible to make this a little less confusing in the future!
robert
User avatar
aclassifier
Respected Member
Posts: 507
Joined: Wed Apr 25, 2012 8:52 pm

Post by aclassifier »

robertxmos wrote: It may be possible to make this a little less confusing in the future!
;-)
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/