tools/Master.cpp
changeset 1079 ef1266652c4d
parent 1073 f3c50aa42b6c
child 1082 ff06c58e269c
equal deleted inserted replaced
1078:fce58ba8a912 1079:ef1266652c4d
   126         int slavePosition,
   126         int slavePosition,
   127         bool force,
   127         bool force,
   128         const vector<string> &commandArgs
   128         const vector<string> &commandArgs
   129         )
   129         )
   130 {
   130 {
   131     ec_ioctl_sii_t data;
   131     ec_ioctl_slave_sii_t data;
   132     ec_ioctl_slave_t slave;
   132     ec_ioctl_slave_t slave;
   133     unsigned int i;
   133     unsigned int i;
   134     uint16_t alias;
   134     uint16_t alias;
   135     stringstream err, strAlias;
   135     stringstream err, strAlias;
   136     int number;
   136     int number;
   228         throw MasterException(err.str());
   228         throw MasterException(err.str());
   229     }
   229     }
   230 
   230 
   231     open(ReadWrite);
   231     open(ReadWrite);
   232 
   232 
   233     if (ioctl(fd, EC_IOCTL_SET_DEBUG, debugLevel) < 0) {
   233     if (ioctl(fd, EC_IOCTL_MASTER_DEBUG, debugLevel) < 0) {
   234         stringstream err;
   234         stringstream err;
   235         err << "Failed to set debug level: " << strerror(errno);
   235         err << "Failed to set debug level: " << strerror(errno);
   236         throw MasterException(err.str());
   236         throw MasterException(err.str());
   237     }
   237     }
   238 }
   238 }
   351         const string &dataTypeStr,
   351         const string &dataTypeStr,
   352         const vector<string> &commandArgs
   352         const vector<string> &commandArgs
   353         )
   353         )
   354 {
   354 {
   355     stringstream strIndex, strSubIndex, strValue, err;
   355     stringstream strIndex, strSubIndex, strValue, err;
   356     ec_ioctl_sdo_download_t data;
   356     ec_ioctl_slave_sdo_download_t data;
   357     unsigned int i, number;
   357     unsigned int i, number;
   358     const CoEDataType *dataType = NULL;
   358     const CoEDataType *dataType = NULL;
   359 
   359 
   360     if (slavePosition < 0) {
   360     if (slavePosition < 0) {
   361         err << "'sdo_download' requires a slave! Please specify --slave.";
   361         err << "'sdo_download' requires a slave! Please specify --slave.";
   391         if (!(dataType = findDataType(dataTypeStr))) {
   391         if (!(dataType = findDataType(dataTypeStr))) {
   392             err << "Invalid data type '" << dataTypeStr << "'!";
   392             err << "Invalid data type '" << dataTypeStr << "'!";
   393             throw MasterException(err.str());
   393             throw MasterException(err.str());
   394         }
   394         }
   395     } else { // no data type specified: fetch from dictionary
   395     } else { // no data type specified: fetch from dictionary
   396         ec_ioctl_sdo_entry_t entry;
   396         ec_ioctl_slave_sdo_entry_t entry;
   397         unsigned int entryByteSize;
   397         unsigned int entryByteSize;
   398 
   398 
   399         open(ReadWrite);
   399         open(ReadWrite);
   400 
   400 
   401         try {
   401         try {
   495         throw MasterException(err.str());
   495         throw MasterException(err.str());
   496     }
   496     }
   497 
   497 
   498     open(ReadWrite);
   498     open(ReadWrite);
   499 
   499 
   500     if (ioctl(fd, EC_IOCTL_SDO_DOWNLOAD, &data) < 0) {
   500     if (ioctl(fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &data) < 0) {
   501         stringstream err;
   501         stringstream err;
   502         err << "Failed to download Sdo: ";
   502         err << "Failed to download Sdo: ";
   503         if (errno == EIO && data.abort_code) {
   503         if (errno == EIO && data.abort_code) {
   504             err << "Abort code 0x" << hex << setfill('0')
   504             err << "Abort code 0x" << hex << setfill('0')
   505                 << setw(8) << data.abort_code;
   505                 << setw(8) << data.abort_code;
   521         const vector<string> &commandArgs
   521         const vector<string> &commandArgs
   522         )
   522         )
   523 {
   523 {
   524     stringstream strIndex, strSubIndex;
   524     stringstream strIndex, strSubIndex;
   525     int sval;
   525     int sval;
   526     ec_ioctl_sdo_upload_t data;
   526     ec_ioctl_slave_sdo_upload_t data;
   527     unsigned int i, uval;
   527     unsigned int i, uval;
   528     const CoEDataType *dataType = NULL;
   528     const CoEDataType *dataType = NULL;
   529 
   529 
   530     if (slavePosition < 0) {
   530     if (slavePosition < 0) {
   531         stringstream err;
   531         stringstream err;
   566             stringstream err;
   566             stringstream err;
   567             err << "Invalid data type '" << dataTypeStr << "'!";
   567             err << "Invalid data type '" << dataTypeStr << "'!";
   568             throw MasterException(err.str());
   568             throw MasterException(err.str());
   569         }
   569         }
   570     } else { // no data type specified: fetch from dictionary
   570     } else { // no data type specified: fetch from dictionary
   571         ec_ioctl_sdo_entry_t entry;
   571         ec_ioctl_slave_sdo_entry_t entry;
   572         unsigned int entryByteSize;
   572         unsigned int entryByteSize;
   573 
   573 
   574         open(Read);
   574         open(Read);
   575 
   575 
   576         try {
   576         try {
   599 
   599 
   600     data.target = new uint8_t[data.target_size + 1];
   600     data.target = new uint8_t[data.target_size + 1];
   601 
   601 
   602     open(Read);
   602     open(Read);
   603 
   603 
   604     if (ioctl(fd, EC_IOCTL_SDO_UPLOAD, &data) < 0) {
   604     if (ioctl(fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &data) < 0) {
   605         stringstream err;
   605         stringstream err;
   606         err << "Failed to upload Sdo: ";
   606         err << "Failed to upload Sdo: ";
   607         if (errno == EIO && data.abort_code) {
   607         if (errno == EIO && data.abort_code) {
   608             err << "Abort code 0x" << hex << setfill('0')
   608             err << "Abort code 0x" << hex << setfill('0')
   609                 << setw(8) << data.abort_code;
   609                 << setw(8) << data.abort_code;
   686 
   686 
   687 /****************************************************************************/
   687 /****************************************************************************/
   688 
   688 
   689 void Master::siiRead(int slavePosition)
   689 void Master::siiRead(int slavePosition)
   690 {
   690 {
   691     ec_ioctl_sii_t data;
   691     ec_ioctl_slave_sii_t data;
   692     ec_ioctl_slave_t slave;
   692     ec_ioctl_slave_t slave;
   693     unsigned int i;
   693     unsigned int i;
   694 
   694 
   695     if (slavePosition < 0) {
   695     if (slavePosition < 0) {
   696         stringstream err;
   696         stringstream err;
   708 
   708 
   709     data.offset = 0;
   709     data.offset = 0;
   710     data.nwords = slave.sii_nwords;
   710     data.nwords = slave.sii_nwords;
   711     data.words = new uint16_t[data.nwords];
   711     data.words = new uint16_t[data.nwords];
   712 
   712 
   713     if (ioctl(fd, EC_IOCTL_SII_READ, &data) < 0) {
   713     if (ioctl(fd, EC_IOCTL_SLAVE_SII_READ, &data) < 0) {
   714         stringstream err;
   714         stringstream err;
   715         delete [] data.words;
   715         delete [] data.words;
   716         err << "Failed to read SII: " << strerror(errno);
   716         err << "Failed to read SII: " << strerror(errno);
   717         throw MasterException(err.str());
   717         throw MasterException(err.str());
   718     }
   718     }
   732         bool force,
   732         bool force,
   733         const vector<string> &commandArgs
   733         const vector<string> &commandArgs
   734         )
   734         )
   735 {
   735 {
   736     stringstream err;
   736     stringstream err;
   737     ec_ioctl_sii_t data;
   737     ec_ioctl_slave_sii_t data;
   738     ifstream file;
   738     ifstream file;
   739     unsigned int byte_size;
   739     unsigned int byte_size;
   740     const uint16_t *categoryHeader;
   740     const uint16_t *categoryHeader;
   741     uint16_t categoryType, categorySize;
   741     uint16_t categoryType, categorySize;
   742     uint8_t crc;
   742     uint8_t crc;
   812     }
   812     }
   813 
   813 
   814     // send data to master
   814     // send data to master
   815     open(ReadWrite);
   815     open(ReadWrite);
   816     data.offset = 0;
   816     data.offset = 0;
   817     if (ioctl(fd, EC_IOCTL_SII_WRITE, &data) < 0) {
   817     if (ioctl(fd, EC_IOCTL_SLAVE_SII_WRITE, &data) < 0) {
   818         stringstream err;
   818         stringstream err;
   819         err << "Failed to write SII: " << strerror(errno);
   819         err << "Failed to write SII: " << strerror(errno);
   820         throw MasterException(err.str());
   820         throw MasterException(err.str());
   821     }
   821     }
   822 }
   822 }
   923 void Master::writeSlaveAlias(
   923 void Master::writeSlaveAlias(
   924         uint16_t slavePosition,
   924         uint16_t slavePosition,
   925         uint16_t alias
   925         uint16_t alias
   926         )
   926         )
   927 {
   927 {
   928     ec_ioctl_sii_t data;
   928     ec_ioctl_slave_sii_t data;
   929     ec_ioctl_slave_t slave;
   929     ec_ioctl_slave_t slave;
   930     stringstream err;
   930     stringstream err;
   931     uint8_t crc;
   931     uint8_t crc;
   932 
   932 
   933     open(ReadWrite);
   933     open(ReadWrite);
   944     data.offset = 0;
   944     data.offset = 0;
   945     data.nwords = 8;
   945     data.nwords = 8;
   946     data.words = new uint16_t[data.nwords];
   946     data.words = new uint16_t[data.nwords];
   947 
   947 
   948     // read first 8 SII words
   948     // read first 8 SII words
   949     if (ioctl(fd, EC_IOCTL_SII_READ, &data) < 0) {
   949     if (ioctl(fd, EC_IOCTL_SLAVE_SII_READ, &data) < 0) {
   950         delete [] data.words;
   950         delete [] data.words;
   951         err << "Failed to read SII: " << strerror(errno);
   951         err << "Failed to read SII: " << strerror(errno);
   952         throw MasterException(err.str());
   952         throw MasterException(err.str());
   953     }
   953     }
   954 
   954 
   960 
   960 
   961     // write new checksum into first byte of word 7
   961     // write new checksum into first byte of word 7
   962     *(uint8_t *) (data.words + 7) = crc;
   962     *(uint8_t *) (data.words + 7) = crc;
   963 
   963 
   964     // write first 8 words with new alias and checksum
   964     // write first 8 words with new alias and checksum
   965     if (ioctl(fd, EC_IOCTL_SII_WRITE, &data) < 0) {
   965     if (ioctl(fd, EC_IOCTL_SLAVE_SII_WRITE, &data) < 0) {
   966         delete [] data.words;
   966         delete [] data.words;
   967         err << "Failed to write SII: " << strerror(errno);
   967         err << "Failed to write SII: " << strerror(errno);
   968         throw MasterException(err.str());
   968         throw MasterException(err.str());
   969     }
   969     }
   970 
   970 
  1149 /****************************************************************************/
  1149 /****************************************************************************/
  1150 
  1150 
  1151 void Master::outputDomainData(unsigned int domainIndex)
  1151 void Master::outputDomainData(unsigned int domainIndex)
  1152 {
  1152 {
  1153     ec_ioctl_domain_t domain;
  1153     ec_ioctl_domain_t domain;
  1154     ec_ioctl_data_t data;
  1154     ec_ioctl_domain_data_t data;
  1155     unsigned char *processData;
  1155     unsigned char *processData;
  1156     unsigned int i;
  1156     unsigned int i;
  1157     
  1157     
  1158     getDomain(&domain, domainIndex);
  1158     getDomain(&domain, domainIndex);
  1159 
  1159 
  1180 
  1180 
  1181 void Master::showDomain(unsigned int domainIndex)
  1181 void Master::showDomain(unsigned int domainIndex)
  1182 {
  1182 {
  1183     ec_ioctl_domain_t domain;
  1183     ec_ioctl_domain_t domain;
  1184     unsigned char *processData;
  1184     unsigned char *processData;
  1185     ec_ioctl_data_t data;
  1185     ec_ioctl_domain_data_t data;
  1186     unsigned int i, j;
  1186     unsigned int i, j;
  1187     ec_ioctl_domain_fmmu_t fmmu;
  1187     ec_ioctl_domain_fmmu_t fmmu;
  1188     unsigned int dataOffset;
  1188     unsigned int dataOffset;
  1189     
  1189     
  1190     getDomain(&domain, domainIndex);
  1190     getDomain(&domain, domainIndex);
  1251         bool quiet,
  1251         bool quiet,
  1252         bool withHeader
  1252         bool withHeader
  1253         )
  1253         )
  1254 {
  1254 {
  1255     ec_ioctl_slave_t slave;
  1255     ec_ioctl_slave_t slave;
  1256     ec_ioctl_sync_t sync;
  1256     ec_ioctl_slave_sync_t sync;
  1257     ec_ioctl_pdo_t pdo;
  1257     ec_ioctl_slave_sync_pdo_t pdo;
  1258     ec_ioctl_pdo_entry_t entry;
  1258     ec_ioctl_slave_sync_pdo_entry_t entry;
  1259     unsigned int i, j, k;
  1259     unsigned int i, j, k;
  1260     
  1260     
  1261     getSlave(&slave, slavePosition);
  1261     getSlave(&slave, slavePosition);
  1262 
  1262 
  1263     if (withHeader)
  1263     if (withHeader)
  1311         bool quiet,
  1311         bool quiet,
  1312         bool withHeader
  1312         bool withHeader
  1313         )
  1313         )
  1314 {
  1314 {
  1315     ec_ioctl_slave_t slave;
  1315     ec_ioctl_slave_t slave;
  1316     ec_ioctl_sdo_t sdo;
  1316     ec_ioctl_slave_sdo_t sdo;
  1317     ec_ioctl_sdo_entry_t entry;
  1317     ec_ioctl_slave_sdo_entry_t entry;
  1318     unsigned int i, j, k;
  1318     unsigned int i, j, k;
  1319     const CoEDataType *d;
  1319     const CoEDataType *d;
  1320     
  1320     
  1321     getSlave(&slave, slavePosition);
  1321     getSlave(&slave, slavePosition);
  1322 
  1322 
  1551 /****************************************************************************/
  1551 /****************************************************************************/
  1552 
  1552 
  1553 void Master::generateSlaveXml(uint16_t slavePosition)
  1553 void Master::generateSlaveXml(uint16_t slavePosition)
  1554 {
  1554 {
  1555     ec_ioctl_slave_t slave;
  1555     ec_ioctl_slave_t slave;
  1556     ec_ioctl_sync_t sync;
  1556     ec_ioctl_slave_sync_t sync;
  1557     ec_ioctl_pdo_t pdo;
  1557     ec_ioctl_slave_sync_pdo_t pdo;
  1558     string pdoType;
  1558     string pdoType;
  1559     ec_ioctl_pdo_entry_t entry;
  1559     ec_ioctl_slave_sync_pdo_entry_t entry;
  1560     unsigned int i, j, k;
  1560     unsigned int i, j, k;
  1561     
  1561     
  1562     getSlave(&slave, slavePosition);
  1562     getSlave(&slave, slavePosition);
  1563 
  1563 
  1564     cout
  1564     cout
  1779     }
  1779     }
  1780 }
  1780 }
  1781 
  1781 
  1782 /****************************************************************************/
  1782 /****************************************************************************/
  1783 
  1783 
  1784 void Master::getData(ec_ioctl_data_t *data, unsigned int domainIndex,
  1784 void Master::getData(ec_ioctl_domain_data_t *data, unsigned int domainIndex,
  1785         unsigned int dataSize, unsigned char *mem)
  1785         unsigned int dataSize, unsigned char *mem)
  1786 {
  1786 {
  1787     data->domain_index = domainIndex;
  1787     data->domain_index = domainIndex;
  1788     data->data_size = dataSize;
  1788     data->data_size = dataSize;
  1789     data->target = mem;
  1789     data->target = mem;
  1790 
  1790 
  1791     if (ioctl(fd, EC_IOCTL_DATA, data) < 0) {
  1791     if (ioctl(fd, EC_IOCTL_DOMAIN_DATA, data) < 0) {
  1792         stringstream err;
  1792         stringstream err;
  1793         err << "Failed to get domain data: " << strerror(errno);
  1793         err << "Failed to get domain data: " << strerror(errno);
  1794         throw MasterException(err.str());
  1794         throw MasterException(err.str());
  1795     }
  1795     }
  1796 }
  1796 }
  1837 }
  1837 }
  1838 
  1838 
  1839 /****************************************************************************/
  1839 /****************************************************************************/
  1840 
  1840 
  1841 void Master::getSync(
  1841 void Master::getSync(
  1842         ec_ioctl_sync_t *sync,
  1842         ec_ioctl_slave_sync_t *sync,
  1843         uint16_t slaveIndex,
  1843         uint16_t slaveIndex,
  1844         uint8_t syncIndex
  1844         uint8_t syncIndex
  1845         )
  1845         )
  1846 {
  1846 {
  1847     sync->slave_position = slaveIndex;
  1847     sync->slave_position = slaveIndex;
  1848     sync->sync_index = syncIndex;
  1848     sync->sync_index = syncIndex;
  1849 
  1849 
  1850     if (ioctl(fd, EC_IOCTL_SYNC, sync)) {
  1850     if (ioctl(fd, EC_IOCTL_SLAVE_SYNC, sync)) {
  1851         stringstream err;
  1851         stringstream err;
  1852         err << "Failed to get sync manager: ";
  1852         err << "Failed to get sync manager: ";
  1853         if (errno == EINVAL)
  1853         if (errno == EINVAL)
  1854             err << "Either slave " << slaveIndex << " does not exist, "
  1854             err << "Either slave " << slaveIndex << " does not exist, "
  1855                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1855                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1861 }
  1861 }
  1862 
  1862 
  1863 /****************************************************************************/
  1863 /****************************************************************************/
  1864 
  1864 
  1865 void Master::getPdo(
  1865 void Master::getPdo(
  1866         ec_ioctl_pdo_t *pdo,
  1866         ec_ioctl_slave_sync_pdo_t *pdo,
  1867         uint16_t slaveIndex,
  1867         uint16_t slaveIndex,
  1868         uint8_t syncIndex,
  1868         uint8_t syncIndex,
  1869         uint8_t pdoPos
  1869         uint8_t pdoPos
  1870         )
  1870         )
  1871 {
  1871 {
  1872     pdo->slave_position = slaveIndex;
  1872     pdo->slave_position = slaveIndex;
  1873     pdo->sync_index = syncIndex;
  1873     pdo->sync_index = syncIndex;
  1874     pdo->pdo_pos = pdoPos;
  1874     pdo->pdo_pos = pdoPos;
  1875 
  1875 
  1876     if (ioctl(fd, EC_IOCTL_PDO, pdo)) {
  1876     if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO, pdo)) {
  1877         stringstream err;
  1877         stringstream err;
  1878         err << "Failed to get Pdo: ";
  1878         err << "Failed to get Pdo: ";
  1879         if (errno == EINVAL)
  1879         if (errno == EINVAL)
  1880             err << "Either slave " << slaveIndex << " does not exist, "
  1880             err << "Either slave " << slaveIndex << " does not exist, "
  1881                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1881                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1889 }
  1889 }
  1890 
  1890 
  1891 /****************************************************************************/
  1891 /****************************************************************************/
  1892 
  1892 
  1893 void Master::getPdoEntry(
  1893 void Master::getPdoEntry(
  1894         ec_ioctl_pdo_entry_t *entry,
  1894         ec_ioctl_slave_sync_pdo_entry_t *entry,
  1895         uint16_t slaveIndex,
  1895         uint16_t slaveIndex,
  1896         uint8_t syncIndex,
  1896         uint8_t syncIndex,
  1897         uint8_t pdoPos,
  1897         uint8_t pdoPos,
  1898         uint8_t entryPos
  1898         uint8_t entryPos
  1899         )
  1899         )
  1901     entry->slave_position = slaveIndex;
  1901     entry->slave_position = slaveIndex;
  1902     entry->sync_index = syncIndex;
  1902     entry->sync_index = syncIndex;
  1903     entry->pdo_pos = pdoPos;
  1903     entry->pdo_pos = pdoPos;
  1904     entry->entry_pos = entryPos;
  1904     entry->entry_pos = entryPos;
  1905 
  1905 
  1906     if (ioctl(fd, EC_IOCTL_PDO_ENTRY, entry)) {
  1906     if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, entry)) {
  1907         stringstream err;
  1907         stringstream err;
  1908         err << "Failed to get Pdo entry: ";
  1908         err << "Failed to get Pdo entry: ";
  1909         if (errno == EINVAL)
  1909         if (errno == EINVAL)
  1910             err << "Either slave " << slaveIndex << " does not exist, "
  1910             err << "Either slave " << slaveIndex << " does not exist, "
  1911                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1911                 << "or it contains less than " << (unsigned int) syncIndex + 1
  1921 }
  1921 }
  1922 
  1922 
  1923 /****************************************************************************/
  1923 /****************************************************************************/
  1924 
  1924 
  1925 void Master::getSdo(
  1925 void Master::getSdo(
  1926         ec_ioctl_sdo_t *sdo,
  1926         ec_ioctl_slave_sdo_t *sdo,
  1927         uint16_t slaveIndex,
  1927         uint16_t slaveIndex,
  1928         uint16_t sdoPosition
  1928         uint16_t sdoPosition
  1929         )
  1929         )
  1930 {
  1930 {
  1931     sdo->slave_position = slaveIndex;
  1931     sdo->slave_position = slaveIndex;
  1932     sdo->sdo_position = sdoPosition;
  1932     sdo->sdo_position = sdoPosition;
  1933 
  1933 
  1934     if (ioctl(fd, EC_IOCTL_SDO, sdo)) {
  1934     if (ioctl(fd, EC_IOCTL_SLAVE_SDO, sdo)) {
  1935         stringstream err;
  1935         stringstream err;
  1936         err << "Failed to get Sdo: ";
  1936         err << "Failed to get Sdo: ";
  1937         if (errno == EINVAL)
  1937         if (errno == EINVAL)
  1938             err << "Either slave " << slaveIndex << " does not exist, "
  1938             err << "Either slave " << slaveIndex << " does not exist, "
  1939                 << "or it contains less than " << sdoPosition + 1 << " Sdos!"
  1939                 << "or it contains less than " << sdoPosition + 1 << " Sdos!"
  1945 }
  1945 }
  1946 
  1946 
  1947 /****************************************************************************/
  1947 /****************************************************************************/
  1948 
  1948 
  1949 void Master::getSdoEntry(
  1949 void Master::getSdoEntry(
  1950         ec_ioctl_sdo_entry_t *entry,
  1950         ec_ioctl_slave_sdo_entry_t *entry,
  1951         uint16_t slaveIndex,
  1951         uint16_t slaveIndex,
  1952         int sdoSpec,
  1952         int sdoSpec,
  1953         uint8_t entrySubindex
  1953         uint8_t entrySubindex
  1954         )
  1954         )
  1955 {
  1955 {
  1956     entry->slave_position = slaveIndex;
  1956     entry->slave_position = slaveIndex;
  1957     entry->sdo_spec = sdoSpec;
  1957     entry->sdo_spec = sdoSpec;
  1958     entry->sdo_entry_subindex = entrySubindex;
  1958     entry->sdo_entry_subindex = entrySubindex;
  1959 
  1959 
  1960     if (ioctl(fd, EC_IOCTL_SDO_ENTRY, entry)) {
  1960     if (ioctl(fd, EC_IOCTL_SLAVE_SDO_ENTRY, entry)) {
  1961         stringstream err;
  1961         stringstream err;
  1962         err << "Failed to get Sdo entry: ";
  1962         err << "Failed to get Sdo entry: ";
  1963         err << strerror(errno);
  1963         err << strerror(errno);
  1964         throw MasterException(err.str());
  1964         throw MasterException(err.str());
  1965     }
  1965     }