master/device.c
changeset 73 9f4ea66d89a3
parent 70 6693d7e25d5e
child 78 3d74183d6c6b
equal deleted inserted replaced
72:7c986b717411 73:9f4ea66d89a3
    27    @param ecd Zu initialisierendes EtherCAT-Gerät
    27    @param ecd Zu initialisierendes EtherCAT-Gerät
    28 */
    28 */
    29 
    29 
    30 int ec_device_init(ec_device_t *ecd)
    30 int ec_device_init(ec_device_t *ecd)
    31 {
    31 {
    32   ecd->dev = NULL;
    32     ecd->dev = NULL;
    33   ecd->open = 0;
    33     ecd->open = 0;
    34   ecd->tx_time = 0;
    34     ecd->tx_time = 0;
    35   ecd->rx_time = 0;
    35     ecd->rx_time = 0;
    36   ecd->tx_intr_cnt = 0;
    36     ecd->state = EC_DEVICE_STATE_READY;
    37   ecd->rx_intr_cnt = 0;
    37     ecd->rx_data_length = 0;
    38   ecd->intr_cnt = 0;
    38     ecd->isr = NULL;
    39   ecd->state = EC_DEVICE_STATE_READY;
    39     ecd->module = NULL;
    40   ecd->rx_data_length = 0;
    40     ecd->error_reported = 0;
    41   ecd->isr = NULL;
    41 
    42   ecd->module = NULL;
    42     if ((ecd->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
    43   ecd->error_reported = 0;
    43         printk(KERN_ERR "EtherCAT: Error allocating device socket buffer!\n");
    44 
    44         return -1;
    45   if ((ecd->tx_skb = dev_alloc_skb(EC_FRAME_SIZE)) == NULL) {
    45     }
    46     printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n");
    46 
    47     return -1;
    47     return 0;
    48   }
       
    49 
       
    50   if ((ecd->rx_skb = dev_alloc_skb(EC_FRAME_SIZE)) == NULL) {
       
    51     dev_kfree_skb(ecd->tx_skb);
       
    52     ecd->tx_skb = NULL;
       
    53     printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n");
       
    54     return -1;
       
    55   }
       
    56 
       
    57   return 0;
       
    58 }
    48 }
    59 
    49 
    60 /*****************************************************************************/
    50 /*****************************************************************************/
    61 
    51 
    62 /**
    52 /**
    68    @param ecd EtherCAT-Gerät
    58    @param ecd EtherCAT-Gerät
    69 */
    59 */
    70 
    60 
    71 void ec_device_clear(ec_device_t *ecd)
    61 void ec_device_clear(ec_device_t *ecd)
    72 {
    62 {
    73   if (ecd->open) ec_device_close(ecd);
    63     if (ecd->open) ec_device_close(ecd);
    74 
    64 
    75   ecd->dev = NULL;
    65     ecd->dev = NULL;
    76 
    66 
    77   if (ecd->tx_skb) {
    67     if (ecd->tx_skb) {
    78     dev_kfree_skb(ecd->tx_skb);
    68         dev_kfree_skb(ecd->tx_skb);
    79     ecd->tx_skb = NULL;
    69         ecd->tx_skb = NULL;
    80   }
    70     }
    81 
       
    82   if (ecd->rx_skb) {
       
    83     dev_kfree_skb(ecd->rx_skb);
       
    84     ecd->rx_skb = NULL;
       
    85   }
       
    86 }
    71 }
    87 
    72 
    88 /*****************************************************************************/
    73 /*****************************************************************************/
    89 
    74 
    90 /**
    75 /**
   100    fehlgeschlagen
    85    fehlgeschlagen
   101 */
    86 */
   102 
    87 
   103 int ec_device_open(ec_device_t *ecd)
    88 int ec_device_open(ec_device_t *ecd)
   104 {
    89 {
   105   unsigned int i;
    90     unsigned int i;
   106 
    91 
   107   if (!ecd) {
    92     if (!ecd) {
   108     printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
    93         printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
   109     return -1;
    94         return -1;
   110   }
    95     }
   111 
    96 
   112   if (!ecd->dev) {
    97     if (!ecd->dev) {
   113     printk(KERN_ERR "EtherCAT: No net_device to open!\n");
    98         printk(KERN_ERR "EtherCAT: No net_device to open!\n");
   114     return -1;
    99         return -1;
   115   }
   100     }
   116 
   101 
   117   if (ecd->open) {
   102     if (ecd->open) {
   118     printk(KERN_WARNING "EtherCAT: Device already opened!\n");
   103         printk(KERN_WARNING "EtherCAT: Device already opened!\n");
   119   }
   104     }
   120   else {
   105     else {
   121     // Device could have received frames before
   106         // Device could have received frames before
   122     for (i = 0; i < 4; i++) ec_device_call_isr(ecd);
   107         for (i = 0; i < 4; i++) ec_device_call_isr(ecd);
   123 
   108 
   124     // Reset old device state
   109         // Reset old device state
   125     ecd->state = EC_DEVICE_STATE_READY;
   110         ecd->state = EC_DEVICE_STATE_READY;
   126     ecd->tx_intr_cnt = 0;
   111 
   127     ecd->rx_intr_cnt = 0;
   112         if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1;
   128 
   113     }
   129     if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1;
   114 
   130   }
   115     return ecd->open ? 0 : -1;
   131 
       
   132   return ecd->open ? 0 : -1;
       
   133 }
   116 }
   134 
   117 
   135 /*****************************************************************************/
   118 /*****************************************************************************/
   136 
   119 
   137 /**
   120 /**
   138    Führt die stop()-Funktion des net_devices aus.
   121    Führt die stop()-Funktion des net_devices aus.
   139 
   122 
   140    @param ecd EtherCAT-Gerät
   123    @param ecd EtherCAT-Gerät
   141 
   124 
   142    @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
   125    @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
   143            Schliessen fehlgeschlagen.
   126    Schliessen fehlgeschlagen.
   144 */
   127 */
   145 
   128 
   146 int ec_device_close(ec_device_t *ecd)
   129 int ec_device_close(ec_device_t *ecd)
   147 {
   130 {
   148   if (!ecd->dev) {
   131     if (!ecd->dev) {
   149     printk(KERN_ERR "EtherCAT: No device to close!\n");
   132         printk(KERN_ERR "EtherCAT: No device to close!\n");
   150     return -1;
   133         return -1;
   151   }
   134     }
   152 
   135 
   153   if (!ecd->open) {
   136     if (!ecd->open) {
   154     printk(KERN_WARNING "EtherCAT: Device already closed!\n");
   137         printk(KERN_WARNING "EtherCAT: Device already closed!\n");
   155   }
   138     }
   156   else {
   139     else {
   157     printk(KERN_INFO "EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
   140         if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0;
   158            (unsigned int) ecd->tx_intr_cnt, (unsigned int) ecd->rx_intr_cnt);
   141     }
   159 
   142 
   160     if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0;
   143     return !ecd->open ? 0 : -1;
   161   }
   144 }
   162 
   145 
   163   return !ecd->open ? 0 : -1;
   146 /*****************************************************************************/
       
   147 
       
   148 /**
       
   149    Bereitet den geräteinternen Socket-Buffer auf den Versand vor.
       
   150 
       
   151    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
       
   152 */
       
   153 
       
   154 uint8_t *ec_device_prepare(ec_device_t *ecd /**< EtherCAT-Gerät */)
       
   155 {
       
   156     // Clear transmit socket buffer and reserve space for Ethernet-II header
       
   157     skb_trim(ecd->tx_skb, 0);
       
   158     skb_reserve(ecd->tx_skb, ETH_HLEN);
       
   159 
       
   160     // Erstmal Speicher für maximal langen Frame reservieren
       
   161     return skb_put(ecd->tx_skb, EC_MAX_FRAME_SIZE);
   164 }
   162 }
   165 
   163 
   166 /*****************************************************************************/
   164 /*****************************************************************************/
   167 
   165 
   168 /**
   166 /**
   170 
   168 
   171    Kopiert die zu sendenden Daten in den statischen Socket-
   169    Kopiert die zu sendenden Daten in den statischen Socket-
   172    Buffer, fügt den Ethernat-II-Header hinzu und ruft die
   170    Buffer, fügt den Ethernat-II-Header hinzu und ruft die
   173    start_xmit()-Funktion der Netzwerkkarte auf.
   171    start_xmit()-Funktion der Netzwerkkarte auf.
   174 
   172 
   175    @param ecd EtherCAT-Gerät
   173    \return 0 bei Erfolg, < 0: Vorheriger Rahmen noch
   176    @param data Zeiger auf die zu sendenden Daten
       
   177    @param length Länge der zu sendenden Daten
       
   178 
       
   179    @return 0 bei Erfolg, < 0: Vorheriger Rahmen noch
       
   180    nicht empfangen, oder kein Speicher mehr vorhanden
   174    nicht empfangen, oder kein Speicher mehr vorhanden
   181 */
   175 */
   182 
   176 
   183 int ec_device_send(ec_device_t *ecd, unsigned char *data, unsigned int length)
   177 void ec_device_send(ec_device_t *ecd, /**< EtherCAT-Gerät */
   184 {
   178                     unsigned int length /**< Länge der zu sendenden Daten */
   185   unsigned char *frame_data;
   179                     )
   186   struct ethhdr *eth;
   180 {
   187 
   181     struct ethhdr *eth;
   188   if (unlikely(ecd->state == EC_DEVICE_STATE_SENT)) {
   182 
   189     printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame while last "
   183     // Framegroesse auf (jetzt bekannte) Laenge abschneiden
   190            " was not received!\n");
   184     skb_trim(ecd->tx_skb, length);
   191   }
   185 
   192 
   186     // Ethernet-II-Header hinzufuegen
   193   // Clear transmit socket buffer and reserve
   187     eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN);
   194   // space for Ethernet-II header
   188     eth->h_proto = htons(0x88A4);
   195   skb_trim(ecd->tx_skb, 0);
   189     memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len);
   196   skb_reserve(ecd->tx_skb, ETH_HLEN);
   190     memset(eth->h_dest, 0xFF, ecd->dev->addr_len);
   197 
   191 
   198   // Copy data to socket buffer
   192     ecd->state = EC_DEVICE_STATE_SENT;
   199   frame_data = skb_put(ecd->tx_skb, length);
   193     ecd->rx_data_length = 0;
   200   memcpy(frame_data, data, length);
   194 
   201 
   195     // Senden einleiten
   202   // Add Ethernet-II-Header
   196     rdtscl(ecd->tx_time); // Get CPU cycles
   203   if (unlikely((eth = (struct ethhdr *)
   197     ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
   204                 skb_push(ecd->tx_skb, ETH_HLEN)) == NULL)) {
   198 }
   205     printk(KERN_ERR "EtherCAT: device_send -"
   199 
   206            " Could not allocate Ethernet-II header!\n");
   200 /*****************************************************************************/
   207     return -1;
   201 
   208   }
   202 /**
   209 
   203    Gibt die Anzahl der empfangenen Bytes zurück.
   210   // Protocol type
   204 
   211   eth->h_proto = htons(0x88A4);
   205    \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde.
   212   // Hardware address
   206 */
   213   memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len);
   207 
   214   // Broadcast address
   208 unsigned int ec_device_received(const ec_device_t *ecd)
   215   memset(eth->h_dest, 0xFF, ecd->dev->addr_len);
   209 {
   216 
   210     return ecd->rx_data_length;
   217   rdtscl(ecd->tx_time); // Get CPU cycles
   211 }
   218 
   212 
   219   // Start sending of frame
   213 /*****************************************************************************/
   220   ecd->state = EC_DEVICE_STATE_SENT;
   214 
   221   ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
   215 /**
   222 
   216    Gibt die empfangenen Daten zurück.
   223   return 0;
   217 
   224 }
   218    \return Adresse auf empfangene Daten.
   225 
   219 */
   226 /*****************************************************************************/
   220 
   227 
   221 uint8_t *ec_device_data(ec_device_t *ecd)
   228 /**
   222 {
   229    Holt einen empfangenen Rahmen von der Netzwerkkarte.
   223     return ecd->rx_data;
   230 
   224 }
   231    Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen
   225 
   232    wurde. Wenn ja, wird dieser in den angegebenen
   226 /*****************************************************************************/
   233    Speicherbereich kopiert.
   227 
   234 
   228 /**
   235    @param ecd EtherCAT-Gerät
   229    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   236    @param data Zeiger auf den Speicherbereich, in den die
   230 
   237                empfangenen Daten kopiert werden sollen
   231    @param ecd EtherCAT-Gerät
   238 
   232 
   239    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
   233    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
   240 */
   234 */
   241 
   235 
   242 int ec_device_receive(ec_device_t *ecd, unsigned char *data)
       
   243 {
       
   244   if (unlikely(ecd->state != EC_DEVICE_STATE_RECEIVED)) {
       
   245     if (likely(ecd->error_reported)) {
       
   246       printk(KERN_ERR "EtherCAT: receive - Nothing received!\n");
       
   247       ecd->error_reported = 1;
       
   248     }
       
   249     return -1;
       
   250   }
       
   251 
       
   252   if (unlikely(ecd->rx_data_length > EC_FRAME_SIZE)) {
       
   253     if (likely(ecd->error_reported)) {
       
   254       printk(KERN_ERR "EtherCAT: receive - "
       
   255              " Reveived frame is too long (%i Bytes)!\n",
       
   256              ecd->rx_data_length);
       
   257       ecd->error_reported = 1;
       
   258     }
       
   259     return -1;
       
   260   }
       
   261 
       
   262   if (unlikely(ecd->error_reported)) {
       
   263     ecd->error_reported = 0;
       
   264   }
       
   265 
       
   266   memcpy(data, ecd->rx_data, ecd->rx_data_length);
       
   267 
       
   268   return ecd->rx_data_length;
       
   269 }
       
   270 
       
   271 /*****************************************************************************/
       
   272 
       
   273 /**
       
   274    Ruft die Interrupt-Routine der Netzwerkkarte auf.
       
   275 
       
   276    @param ecd EtherCAT-Gerät
       
   277 
       
   278    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
       
   279 */
       
   280 
       
   281 void ec_device_call_isr(ec_device_t *ecd)
   236 void ec_device_call_isr(ec_device_t *ecd)
   282 {
   237 {
   283   if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
   238     if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
   284 }
   239 }
   285 
   240 
   286 /*****************************************************************************/
   241 /*****************************************************************************/
   287 
   242 
   288 /**
   243 /**
   289    Gibt alle Informationen über das Device-Objekt aus.
   244    Gibt alle Informationen über das Device-Objekt aus.
   290 
   245 
   291    @param ecd EtherCAT-Gerät
   246    @param ecd EtherCAT-Gerät
   292 */
   247 */
   293 
   248 
   294 void ec_device_debug(ec_device_t *ecd)
   249 void ec_device_print(ec_device_t *ecd)
   295 {
   250 {
   296   printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   251     printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   297 
   252 
   298   if (ecd)
   253     if (ecd)
   299   {
   254     {
   300     printk(KERN_DEBUG "Assigned net_device: %X\n",
   255         printk(KERN_DEBUG "Assigned net_device: %X\n",
   301            (unsigned) ecd->dev);
   256                (unsigned) ecd->dev);
   302     printk(KERN_DEBUG "Transmit socket buffer: %X\n",
   257         printk(KERN_DEBUG "Transmit socket buffer: %X\n",
   303            (unsigned) ecd->tx_skb);
   258                (unsigned) ecd->tx_skb);
   304     printk(KERN_DEBUG "Receive socket buffer: %X\n",
   259         printk(KERN_DEBUG "Time of last transmission: %u\n",
   305            (unsigned) ecd->rx_skb);
   260                (unsigned) ecd->tx_time);
   306     printk(KERN_DEBUG "Time of last transmission: %u\n",
   261         printk(KERN_DEBUG "Time of last receive: %u\n",
   307            (unsigned) ecd->tx_time);
   262                (unsigned) ecd->rx_time);
   308     printk(KERN_DEBUG "Time of last receive: %u\n",
   263         printk(KERN_DEBUG "Actual device state: %i\n",
   309            (unsigned) ecd->rx_time);
   264                (int) ecd->state);
   310     printk(KERN_DEBUG "Number of transmit interrupts: %u\n",
   265         printk(KERN_DEBUG "Receive buffer: %X\n",
   311            (unsigned) ecd->tx_intr_cnt);
   266                (unsigned) ecd->rx_data);
   312     printk(KERN_DEBUG "Number of receive interrupts: %u\n",
   267         printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   313            (unsigned) ecd->rx_intr_cnt);
   268                (unsigned) ecd->rx_data_length, EC_MAX_FRAME_SIZE);
   314     printk(KERN_DEBUG "Total Number of interrupts: %u\n",
   269     }
   315            (unsigned) ecd->intr_cnt);
   270     else
   316     printk(KERN_DEBUG "Actual device state: %i\n",
   271     {
   317            (int) ecd->state);
   272         printk(KERN_DEBUG "Device is NULL!\n");
   318     printk(KERN_DEBUG "Receive buffer: %X\n",
   273     }
   319            (unsigned) ecd->rx_data);
   274 
   320     printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   275     printk(KERN_DEBUG "---EtherCAT device information end---\n");
   321            (unsigned) ecd->rx_data_length, EC_FRAME_SIZE);
       
   322   }
       
   323   else
       
   324   {
       
   325     printk(KERN_DEBUG "Device is NULL!\n");
       
   326   }
       
   327 
       
   328   printk(KERN_DEBUG "---EtherCAT device information end---\n");
       
   329 }
   276 }
   330 
   277 
   331 /******************************************************************************
   278 /******************************************************************************
   332  *
   279  *
   333  * Treiberschnittstelle
   280  * Treiberschnittstelle
   334  *
   281  *
   335  *****************************************************************************/
   282  *****************************************************************************/
   336 
   283 
   337 void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state)
   284 void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state)
   338 {
   285 {
   339   if (state == EC_DEVICE_STATE_TIMEOUT && ecd->state != EC_DEVICE_STATE_SENT) {
   286     ecd->state = state;
   340     printk(KERN_WARNING "EtherCAT: Wrong status at timeout: %i\n", ecd->state);
       
   341   }
       
   342 
       
   343   ecd->state = state;
       
   344 }
   287 }
   345 
   288 
   346 /*****************************************************************************/
   289 /*****************************************************************************/
   347 
   290 
   348 int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev)
   291 int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev)
   349 {
   292 {
   350   return ecd && ecd->dev == dev;
   293     return ecd && ecd->dev == dev;
   351 }
   294 }
   352 
   295 
   353 /*****************************************************************************/
   296 /*****************************************************************************/
   354 
   297 
   355 int EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size)
   298 void EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size)
   356 {
   299 {
   357   if (ecd->state != EC_DEVICE_STATE_SENT)
   300     // Copy received data to ethercat-device buffer
   358   {
   301     memcpy(ecd->rx_data, data, size);
   359     printk(KERN_WARNING "EtherCAT: Received frame while not in SENT state!\n");
   302     ecd->rx_data_length = size;
   360     return -1;
   303     ecd->state = EC_DEVICE_STATE_RECEIVED;
   361   }
       
   362 
       
   363   // Copy received data to ethercat-device buffer, skip Ethernet-II header
       
   364   memcpy(ecd->rx_data, data, size);
       
   365   ecd->rx_data_length = size;
       
   366   ecd->state = EC_DEVICE_STATE_RECEIVED;
       
   367 
       
   368   return 0;
       
   369 }
   304 }
   370 
   305 
   371 /*****************************************************************************/
   306 /*****************************************************************************/
   372 
   307 
   373 EXPORT_SYMBOL(EtherCAT_dev_is_ec);
   308 EXPORT_SYMBOL(EtherCAT_dev_is_ec);
   376 
   311 
   377 /*****************************************************************************/
   312 /*****************************************************************************/
   378 
   313 
   379 /* Emacs-Konfiguration
   314 /* Emacs-Konfiguration
   380 ;;; Local Variables: ***
   315 ;;; Local Variables: ***
   381 ;;; c-basic-offset:2 ***
   316 ;;; c-basic-offset:4 ***
   382 ;;; End: ***
   317 ;;; End: ***
   383 */
   318 */