canopenethercat

Can I configure the (default) PDO layout automatically?


If I call ecrt_slave_config_reg_pdo_entry to create a domain offset, I get the message:

Failed to register PDO entry: No such file or directory

I believe that I have to call ecrt_slave_config_pdos, which I am not at the moment. However, I do not understand why I have to call it. In my case, the slave I like to talk to is already connected to the bus. If I enter ec cstruct -p [SLAVE_POS] in a terminal, I get the PDO layout.

me@here:~$ ec cstruct -p 1
/* Master 0, Slave 1, "..."
 * Vendor ID:       0x...
 * Product code:    0x...
 * Revision number: 0x...
 */

ec_pdo_entry_info_t slave_1_pdo_entries[] = {
    {0x6040, 0x00, 16},
    ...
};

ec_pdo_info_t slave_1_pdos[] = {
    {0x1600, 2, slave_1_pdo_entries + 0},
    ...
};

ec_sync_info_t slave_1_syncs[] = {
    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
    ...
    {0xff}
};

Why can I get all input arguments for ecrt_slave_config_pdos from the terminal command, but EtherCat cannot (or does not want to) configure the slave itself? Can the slave configuration be automated?


Solution

  • You can use the functions ecrt_master_get_slave(), ecrt_master_get_sync_manager(), ecrt_master_get_pdo(), and (of course) ecrt_master_get_pdo_entry() to retrieve all the necessary information. ecrt_master_get_sync_manager(), e.g., will not set the PDO information, but will return the number of PDO positions for a synchronization manager.

    So something like that works for me (error code checks left out for the sake of clarity):

    ecrt_master_get_slave(..., &slaveInformation);
    
    // For every synchronization manager...
    for (size_t syncIndex = 0; syncIndex < slaveInformation.sync_count; ++syncIndex) {
        ecrt_master_get_sync_manager(..., &syncInformation);
        ecrt_slave_config_sync_manager(...);
    
        // For every PDO field...
        for (size_t pdoIndex = 0; pdoIndex < syncInformation.n_pdos; ++pdoIndex) {
            ecrt_master_get_pdo(..., &pdoInformation);
            ecrt_slave_config_pdo_assign_add(...);
    
            // For every entry in the pdo field...
            for (size_t entryIndex = 0; entryIndex < pdoInformation.n_entries; ++entryIndex) {
                ecrt_master_get_pdo_entry(..., &entryInformation);
                ecrt_slave_config_pdo_mapping_add(...);
            }
        }
    }
    

    This, however, does not really answer the question why (or if) all this is necessary. To be specific on cleaner: It would be nice, if the Pyramid of Doom could be avoided. Especially, since I am telling the slave something it told me one line before.