master/datagram.c
changeset 809 ec4ef8911824
parent 758 8fa6f825eb7d
child 815 002fe9ec778f
equal deleted inserted replaced
808:1feddbd65608 809:ec4ef8911824
    61 
    61 
    62 /** \endcond */
    62 /** \endcond */
    63 
    63 
    64 /*****************************************************************************/
    64 /*****************************************************************************/
    65 
    65 
    66 /**
    66 /** Constructor.
    67    Datagram constructor.
    67  */
    68 */
       
    69 
       
    70 void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */)
    68 void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */)
    71 {
    69 {
    72     INIT_LIST_HEAD(&datagram->queue); // mark as unqueued
    70     INIT_LIST_HEAD(&datagram->queue); // mark as unqueued
    73     datagram->type = EC_DATAGRAM_NONE;
    71     datagram->type = EC_DATAGRAM_NONE;
    74     memset(datagram->address, 0x00, EC_ADDR_LEN);
    72     memset(datagram->address, 0x00, EC_ADDR_LEN);
    75     datagram->data = NULL;
    73     datagram->data = NULL;
       
    74     datagram->data_origin = EC_ORIG_INTERNAL;
    76     datagram->mem_size = 0;
    75     datagram->mem_size = 0;
    77     datagram->data_size = 0;
    76     datagram->data_size = 0;
    78     datagram->index = 0x00;
    77     datagram->index = 0x00;
    79     datagram->working_counter = 0x00;
    78     datagram->working_counter = 0x0000;
    80     datagram->state = EC_DATAGRAM_INIT;
    79     datagram->state = EC_DATAGRAM_INIT;
    81     datagram->cycles_sent = 0;
    80     datagram->cycles_sent = 0;
    82     datagram->jiffies_sent = 0;
    81     datagram->jiffies_sent = 0;
    83     datagram->cycles_received = 0;
    82     datagram->cycles_received = 0;
    84     datagram->jiffies_received = 0;
    83     datagram->jiffies_received = 0;
    85     datagram->skip_count = 0;
    84     datagram->skip_count = 0;
    86     datagram->stats_output_jiffies = 0;
    85     datagram->stats_output_jiffies = 0;
    87     datagram->name[0] = 0x00;
    86     memset(datagram->name, 0x00, EC_DATAGRAM_NAME_SIZE);
    88 }
    87 }
    89 
    88 
    90 /*****************************************************************************/
    89 /*****************************************************************************/
    91 
    90 
    92 /**
    91 /** Destructor.
    93    Datagram destructor.
    92  */
    94 */
       
    95 
       
    96 void ec_datagram_clear(ec_datagram_t *datagram /**< EtherCAT datagram */)
    93 void ec_datagram_clear(ec_datagram_t *datagram /**< EtherCAT datagram */)
    97 {
    94 {
    98     if (datagram->data) kfree(datagram->data);
    95     if (datagram->data_origin == EC_ORIG_INTERNAL && datagram->data)
    99 }
    96         kfree(datagram->data);
   100 
    97 }
   101 /*****************************************************************************/
    98 
   102 
    99 /*****************************************************************************/
   103 /**
   100 
   104    Allocates datagram data memory.
   101 /** Allocates internal payload memory.
   105    If the allocated memory is already larger than requested, nothing ist done.
   102  *
   106    \return 0 in case of success, else < 0
   103  * If the allocated memory is already larger than requested, nothing ist done.
   107 */
   104  *
   108 
   105  * \attention If external payload memory has been provided, no range checking
       
   106  *            is done!
       
   107  *
       
   108  * \return 0 in case of success, else < 0
       
   109  */
   109 int ec_datagram_prealloc(ec_datagram_t *datagram, /**< EtherCAT datagram */
   110 int ec_datagram_prealloc(ec_datagram_t *datagram, /**< EtherCAT datagram */
   110                          size_t size /**< New size in bytes */
   111         size_t size /**< New size in bytes */
   111                          )
   112         )
   112 {
   113 {
   113     if (size <= datagram->mem_size) return 0;
   114     if (datagram->data_origin == EC_ORIG_EXTERNAL
       
   115             || size <= datagram->mem_size)
       
   116         return 0;
   114 
   117 
   115     if (datagram->data) {
   118     if (datagram->data) {
   116         kfree(datagram->data);
   119         kfree(datagram->data);
   117         datagram->data = NULL;
   120         datagram->data = NULL;
   118         datagram->mem_size = 0;
   121         datagram->mem_size = 0;
   127     return 0;
   130     return 0;
   128 }
   131 }
   129 
   132 
   130 /*****************************************************************************/
   133 /*****************************************************************************/
   131 
   134 
   132 /**
   135 /** Initializes an EtherCAT NPRD datagram.
   133    Initializes an EtherCAT NPRD datagram.
   136  *
   134    Node-adressed physical read.
   137  * Node-adressed physical read.
   135    \return 0 in case of success, else < 0
   138  *
   136 */
   139  * \return 0 in case of success, else < 0
   137 
   140  */
   138 int ec_datagram_nprd(ec_datagram_t *datagram,
   141 int ec_datagram_nprd(ec_datagram_t *datagram,
   139                      /**< EtherCAT datagram */
   142                      /**< EtherCAT datagram */
   140                      uint16_t node_address,
   143                      uint16_t node_address,
   141                      /**< configured station address */
   144                      /**< configured station address */
   142                      uint16_t offset,
   145                      uint16_t offset,
   155     EC_FUNC_FOOTER;
   158     EC_FUNC_FOOTER;
   156 }
   159 }
   157 
   160 
   158 /*****************************************************************************/
   161 /*****************************************************************************/
   159 
   162 
   160 /**
   163 /** Initializes an EtherCAT NPWR datagram.
   161    Initializes an EtherCAT NPWR datagram.
   164  *
   162    Node-adressed physical write.
   165  * Node-adressed physical write.
   163    \return 0 in case of success, else < 0
   166  *
   164 */
   167  * \return 0 in case of success, else < 0
   165 
   168  */
   166 int ec_datagram_npwr(ec_datagram_t *datagram,
   169 int ec_datagram_npwr(ec_datagram_t *datagram,
   167                      /**< EtherCAT datagram */
   170                      /**< EtherCAT datagram */
   168                      uint16_t node_address,
   171                      uint16_t node_address,
   169                      /**< configured station address */
   172                      /**< configured station address */
   170                      uint16_t offset,
   173                      uint16_t offset,
   183     EC_FUNC_FOOTER;
   186     EC_FUNC_FOOTER;
   184 }
   187 }
   185 
   188 
   186 /*****************************************************************************/
   189 /*****************************************************************************/
   187 
   190 
   188 /**
   191 /** Initializes an EtherCAT APRD datagram.
   189    Initializes an EtherCAT APRD datagram.
   192  *
   190    Autoincrement physical read.
   193  * Autoincrement physical read.
   191    \return 0 in case of success, else < 0
   194  *
   192 */
   195  * \return 0 in case of success, else < 0
   193 
   196  */
   194 int ec_datagram_aprd(ec_datagram_t *datagram,
   197 int ec_datagram_aprd(ec_datagram_t *datagram,
   195                      /**< EtherCAT datagram */
   198                      /**< EtherCAT datagram */
   196                      uint16_t ring_position,
   199                      uint16_t ring_position,
   197                      /**< auto-increment position */
   200                      /**< auto-increment position */
   198                      uint16_t offset,
   201                      uint16_t offset,
   208     EC_FUNC_FOOTER;
   211     EC_FUNC_FOOTER;
   209 }
   212 }
   210 
   213 
   211 /*****************************************************************************/
   214 /*****************************************************************************/
   212 
   215 
   213 /**
   216 /** Initializes an EtherCAT APWR datagram.
   214    Initializes an EtherCAT APWR datagram.
   217  *
   215    Autoincrement physical write.
   218  * Autoincrement physical write.
   216    \return 0 in case of success, else < 0
   219  *
   217 */
   220  * \return 0 in case of success, else < 0
   218 
   221  */
   219 int ec_datagram_apwr(ec_datagram_t *datagram,
   222 int ec_datagram_apwr(ec_datagram_t *datagram,
   220                      /**< EtherCAT datagram */
   223                      /**< EtherCAT datagram */
   221                      uint16_t ring_position,
   224                      uint16_t ring_position,
   222                      /**< auto-increment position */
   225                      /**< auto-increment position */
   223                      uint16_t offset,
   226                      uint16_t offset,
   233     EC_FUNC_FOOTER;
   236     EC_FUNC_FOOTER;
   234 }
   237 }
   235 
   238 
   236 /*****************************************************************************/
   239 /*****************************************************************************/
   237 
   240 
   238 /**
   241 /** Initializes an EtherCAT BRD datagram.
   239    Initializes an EtherCAT BRD datagram.
   242  *
   240    Broadcast read.
   243  * Broadcast read.
   241    \return 0 in case of success, else < 0
   244  *
   242 */
   245  * \return 0 in case of success, else < 0
   243 
   246  */
   244 int ec_datagram_brd(ec_datagram_t *datagram,
   247 int ec_datagram_brd(ec_datagram_t *datagram,
   245                     /**< EtherCAT datagram */
   248                     /**< EtherCAT datagram */
   246                     uint16_t offset,
   249                     uint16_t offset,
   247                     /**< physical memory address */
   250                     /**< physical memory address */
   248                     size_t data_size
   251                     size_t data_size
   256     EC_FUNC_FOOTER;
   259     EC_FUNC_FOOTER;
   257 }
   260 }
   258 
   261 
   259 /*****************************************************************************/
   262 /*****************************************************************************/
   260 
   263 
   261 /**
   264 /** Initializes an EtherCAT BWR datagram.
   262    Initializes an EtherCAT BWR datagram.
   265  *
   263    Broadcast write.
   266  * Broadcast write.
   264    \return 0 in case of success, else < 0
   267  *
   265 */
   268  * \return 0 in case of success, else < 0
   266 
   269  */
   267 int ec_datagram_bwr(ec_datagram_t *datagram,
   270 int ec_datagram_bwr(ec_datagram_t *datagram,
   268                     /**< EtherCAT datagram */
   271                     /**< EtherCAT datagram */
   269                     uint16_t offset,
   272                     uint16_t offset,
   270                     /**< physical memory address */
   273                     /**< physical memory address */
   271                     size_t data_size
   274                     size_t data_size
   279     EC_FUNC_FOOTER;
   282     EC_FUNC_FOOTER;
   280 }
   283 }
   281 
   284 
   282 /*****************************************************************************/
   285 /*****************************************************************************/
   283 
   286 
   284 /**
   287 /** Initializes an EtherCAT LRW datagram.
   285    Initializes an EtherCAT LRW datagram.
   288  *
   286    Logical read write.
   289  * Logical read write.
   287    \return 0 in case of success, else < 0
   290  *
   288 */
   291  * \attention It is assumed, that the external memory is at least \a data_size
   289 
   292  *            bytes large.
   290 int ec_datagram_lrw(ec_datagram_t *datagram,
   293  *
   291                     /**< EtherCAT datagram */
   294  * \return 0 in case of success, else < 0
   292                     uint32_t offset,
   295  */
   293                     /**< logical address */
   296 int ec_datagram_lrw(
   294                     size_t data_size
   297         ec_datagram_t *datagram, /**< EtherCAT datagram */
   295                     /**< number of bytes to read/write */
   298         uint32_t offset, /**< Logical address. */
   296                     )
   299         size_t data_size, /**< Number of bytes to read/write. */
   297 {
   300         uint8_t *external_memory /**< Pointer to the memory to use. */
       
   301         )
       
   302 {
       
   303     datagram->data = external_memory;
       
   304     datagram->data_origin = EC_ORIG_EXTERNAL;
   298     EC_FUNC_HEADER;
   305     EC_FUNC_HEADER;
   299     datagram->type = EC_DATAGRAM_LRW;
   306     datagram->type = EC_DATAGRAM_LRW;
   300     EC_WRITE_U32(datagram->address, offset);
   307     EC_WRITE_U32(datagram->address, offset);
   301     EC_FUNC_FOOTER;
   308     EC_FUNC_FOOTER;
   302 }
   309 }
   303 
   310 
   304 /*****************************************************************************/
   311 /*****************************************************************************/
   305 
   312 
   306 /**
   313 /** Evaluates the working counter of a single-cast datagram.
   307  * Evaluates the working counter of a single-cast datagram.
   314  *
   308  * Outputs an error message.
   315  * Outputs an error message.
   309  */
   316  */
   310 
       
   311 void ec_datagram_print_wc_error(
   317 void ec_datagram_print_wc_error(
   312         const ec_datagram_t *datagram /**< EtherCAT datagram */
   318         const ec_datagram_t *datagram /**< EtherCAT datagram */
   313         )
   319         )
   314 {
   320 {
   315     if (datagram->working_counter == 0)
   321     if (datagram->working_counter == 0)
   321     printk("\n");
   327     printk("\n");
   322 }
   328 }
   323 
   329 
   324 /*****************************************************************************/
   330 /*****************************************************************************/
   325 
   331 
   326 /**
   332 /** Outputs datagram statistics at most every second.
   327  * Outputs datagram statistics at most every second.
   333  */
   328  */
       
   329 
       
   330 void ec_datagram_output_stats(
   334 void ec_datagram_output_stats(
   331         ec_datagram_t *datagram
   335         ec_datagram_t *datagram
   332         )
   336         )
   333 {
   337 {
   334     if (jiffies - datagram->stats_output_jiffies < HZ) {
   338     if (jiffies - datagram->stats_output_jiffies < HZ) {