(*exos_dataset_event_cb)()

<< 点击显示目录 >>

主页  exOS使用助手 > exOS Automation Help > Development > Programming > exOS Communication API reference (exos_api.h) >

(*exos_dataset_event_cb)()

数据集事件的回调函数

声明

类型化枚举
{
 exos_dataset_event_connection_changed、
 exos_dataset_event_updated、
 exos_dataset_event_published、
 exos_dataset_event_delivered
}exos_dataset_event_type;
typedef void (*exos_dataset_event_cb)(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info);

数据集事件发生时触发的回调。用户应使用给定的回调原型定义一个函数,例如

static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
 ...
}
...
EXOS_ASSERT_OK(exos_dataset_connect(enable, EXOS_DATASET_PUBLISH, datasetEvent));

数据集支持以下事件类型:

数据集支持以下事件类型: exos_dataset_event_type:事件类型

exos_dataset_event_connection_changed

当数据集改变了连接状态时 ,触发 EXOS_DATASET_PUBLISH 和 EXOS_DATASET_SUBSCRIBE, 而新状态可在 数据集->connection_state 成员  中找到  。  有关数据集和数据模型状态更改之间关系的更多信息, 请参阅 CONNECTION_STATE 部分。

读取新连接状态的示例

 static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
 {
 switch(event_type)
 {
 case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
 switch(dataset->connection_state)
 {
 case EXOS_STATE_DISCONNECTED:
 break;
 case EXOS_STATE_CONNECTED:
 break;
 case EXOS_STATE_OPERATIONAL:
 break;
 case EXOS_STATE_ABORTED:
 break;
 }
 break;
 case .
 }
 ...

exos_dataset_event_updated

当数据集更新/更改时 触发 EXOS_DATASET_SUBSCRIBE, 即对 站向 数据集消息路由器 发布数据集 后,服务器将新数据集转发给应用程序中订阅的数据集。该事件被称为 "更新"(UPDATED) 而非 "更改"(CHANGED, 因为对站可以触发任意次数 的EXOS_dataset_publish(),而不会 真正 改变 数据集 的

应用程序  自己发布的数据集 永远不会收到 EXOS_DATASET_EVENT_UPDATED,这 意味着在使用 EXOS_DATASET_PUBLISH + EXOS_DATASET_SUBSCRIBE 时 ,既可以发布也可以订阅该数据集、如果 在EXOS_DATASET_EVENT_UPDATED 事件 中调用 了exos_dataset_publish(),可能是为了更改并返回数据集,那么如果应用程序接收到  自己已发布数据集的EXOS_DATASET_EVENT_UPDATED 事件,就会导致无限循环  。

在这种情况下, 数据集->nettime 值会用 exos_dataset_publish() 时的 NETTIME 更新 。这样就可以确定传输的延迟时间等:

 static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
 {
 switch (event_type)
 {
 case EXOS_DATASET_EVENT_UPDATED:
 VERBOSE("dataset %s updated! latency (us):%i", dataset->name, (exos_datamodel_get_nettime(dataset->datamodel, NULL) - dataset->nettime));

exos_dataset_event_published

在 数据类型上  调用 exos_dataset_publish() 后 触发 EXOS_DATASET_PUBLISH。EXOS_DATASET_EVENT_PUBLISHED 表示数据集已 被本地 数据集消息路由器 分发 ,这意味着数据集正在发送到远程系统的途中,但尚未发送。由于传输可能受到限制, EXOS_ERROR_BUFFER_OVERFLOW 仍可能在此事件后发生,因为数据集在传输前已被缓冲(缓冲区可能已满)。  有关系统缓冲区 大小的更多信息, 请查看 预定义缓冲区

对于本地连接 ,即在exostarget 配置文件  中未 对给定的 数据模型实例名进行连接配置的连接  , EXOS_DATASET_EVENT_PUBLISHED 意味着数据正被分发到本地系统的其他部分。

与  在 EXOS_DATASET_EVENT_UPDATED时 更新 数据集->nettime变量类似 ,  在 EXOS_DATASET_EVENT_PUBLISHED 时也会更新 数据集->send_buffer 变量 。 send_buffer 结构包含 数据集消息路由器 传输缓冲区中的 空闲、 已用和 大小,它们指的是 数据集 条目 数  (而不是字节数) 。该结构有助于避免  数据集 出现EXOS_ERROR_BUFFER_OVERFLOW 错误。请注意,当发布的数据集多于可传输的数据集时, 数据集消息路由器 传输缓冲区  中每排队一个数据集 ,dataset->send_buffer.used 就会 增加 1  ,直到达到 dataset->send_buffer.size - 即触发 EXOS_ERROR_BUFFER_OVERFLOW。同样, dataset->send_buffer.free 将从 ``dataset->send_buffer.size - 1` 开始。

exos_dataset_event_delivered

在 数据类型上  调用 exos_dataset_publish() 后 触发 EXOS_DATASET_PUBLISH。EXOS_DATASET_EVENT_DELIVERED 表示数据集已 被远程 数据集消息路由器 接收 ,即数据集已被传送到对面的系统 。每次  调用 exos_dataset_publish(), 数据集首先会收到 EXOS_DATASET_EVENT_PUBLISHED 事件,然后是 EXOS_DATASET_EVENT_DELIVERED 事件。

在连接带宽有限的情况下(纯 TCP/IP 连接), EXOS_DATASET_EVENT_DELIVERED 可用于循环发布数据,而不会在  数据集上  收到 EXOS_ERROR_BUFFER_OVERFLOW 。  在 EXOS_DATASET_EVENT_DELIVERED 事件中  调用另一个 exos_dataset_publish(), 意味着数据集正在 "尽可能快地 "发布,通常是指每隔一次扫描 TCP/IP 连接。示例

 static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
 {
 switch (event_type)
 {
 case EXOS_DATASET_EVENT_DELIVERED:
 VERBOSE("dataset %s delivered to remote server for distribution!发送下一个!已释放发送缓冲区:%i", dataset->name, dataset->send_buffer.free);
 exos_dataset_publish(dataset);

就像 EXOS_DATASET_EVENT_PUBLISHED一样, EXOS_DATASET_EVENT_DELIVERED 也会  更新 数据集->send_buffer 变量。现在,如果按照上面的示例进行发布, dataset->send_buffer.used 将始终为 0,而 dataset->send_buffer.free 将  始终  等于 dataset->send_buffer.size。


Callback function for dataset events

Declaration

typedef enum
{
    EXOS_DATASET_EVENT_CONNECTION_CHANGED,
    EXOS_DATASET_EVENT_UPDATED,
    EXOS_DATASET_EVENT_PUBLISHED,
    EXOS_DATASET_EVENT_DELIVERED
} EXOS_DATASET_EVENT_TYPE;
typedef void (*exos_dataset_event_cb)(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info);

Callback that is triggered in case of a dataset event. The user should define a function with the given callback prototype, for example:

static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
{
    ...
}
...
EXOS_ASSERT_OK(exos_dataset_connect(enable, EXOS_DATASET_PUBLISH, datasetEvent));

A dataset supports the following event types:

EXOS_DATASET_EVENT_TYPE: Event Types

EXOS_DATASET_EVENT_CONNECTION_CHANGED:

Triggered for EXOS_DATASET_PUBLISH and EXOS_DATASET_SUBSCRIBE when this dataset has changed the connection state, whereas the new state is found in the dataset->connection_state member. Please see the CONNECTION_STATE section for more on the relation between the dataset and the datamodel state changes.

Example for reading the new connection state:

  static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
  {
      switch(event_type)
      {
      case EXOS_DATASET_EVENT_CONNECTION_CHANGED:
          switch(dataset->connection_state)
          {
          case EXOS_STATE_DISCONNECTED:
              break;
          case EXOS_STATE_CONNECTED:
              break;
          case EXOS_STATE_OPERATIONAL:
              break;
          case EXOS_STATE_ABORTED:
              break;
          }
          break;
      case ..
      }
      ...

EXOS_DATASET_EVENT_UPDATED:

Triggered for EXOS_DATASET_SUBSCRIBE when this dataset is updated / changed - that is, after an opposite station has published a dataset to the Dataset Message Router, and the server has forwarded the the new dataset to the subscribed dataset in the application. The event is called UPDATED rather than CHANGED as the opposite station could trigger any number of exos_dataset_publish() without actually changing the value of the dataset.

An application will never receive EXOS_DATASET_EVENT_UPDATED for its own published datasets, meaning when using EXOS_DATASET_PUBLISH + EXOS_DATASET_SUBSCRIBE, it is possible to both publish and subscribe to this dataset, and in case an exos_dataset_publish() would be called inside the EXOS_DATASET_EVENT_UPDATED, maybe to change and return the dataset, it would cause an infinite loop if the application was to receive an EXOS_DATASET_EVENT_UPDATED event for its own published datasets.

In case of this event, the dataset->nettime value is updated with the NETTIME at the time of exos_dataset_publish(). With this it is possible to determine the latency of the transmission, for example:

  static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
  {
      switch (event_type)
      {
      case EXOS_DATASET_EVENT_UPDATED:
          VERBOSE("dataset %s updated! latency (us):%i", dataset->name, (exos_datamodel_get_nettime(dataset->datamodel, NULL) - dataset->nettime));

EXOS_DATASET_EVENT_PUBLISHED:

Triggered for EXOS_DATASET_PUBLISH after calling exos_dataset_publish() on the datatype. The EXOS_DATASET_EVENT_PUBLISHED means that the dataset has been distributed by the local Dataset Message Router, meaning that the dataset is on its way to the remote system, but not yet sent. As transmission can be limitied, the EXOS_ERROR_BUFFER_OVERFLOW can still occur after this event, since the dataset is buffered prior to being transmitted (and this buffer might be full). Check the Predefined buffers for more on the Buffer sizes of the system.

For Local connections, i.e. where not connection configuration of the given datamodel_instance_name has been made in the exostarget configuration file, the EXOS_DATASET_EVENT_PUBLISHED means that the data is being distributed to the rest of the local system.

Similar to the dataset->nettime variable being updated at EXOS_DATASET_EVENT_UPDATED, the dataset->send_buffer variable is updated at the EXOS_DATASET_EVENT_PUBLISHED. The send_buffer structure contains free, used, and size referring to the number of dataset items (not Bytes) in the transmission buffer of the Dataset Message Router. This structure is useful for avoiding EXOS_ERROR_BUFFER_OVERFLOW errors on the dataset. Note that when publishing more datasets than can be transmitted, the dataset->send_buffer.used will increase with 1 for every dataset queued in the Dataset Message Router transmission buffer, until it reaches dataset->send_buffer.size - which triggers an EXOS_ERROR_BUFFER_OVERFLOW. Likewise, the dataset->send_buffer.free will start with being ``dataset->send_buffer.size - 1`.

EXOS_DATASET_EVENT_DELIVERED:

Triggered for EXOS_DATASET_PUBLISH after calling exos_dataset_publish() on the datatype. The EXOS_DATASET_EVENT_DELIVERED means that the dataset has been recevied by the remote Dataset Message Router, that is that the dataset has been transferred to the opposite system. Every time exos_dataset_publish() is being called, the dataset first receives an EXOS_DATASET_EVENT_PUBLISHED event, then an EXOS_DATASET_EVENT_DELIVERED event.

In cases where the connection has a limited bandwidth (pure TCP/IP connections), the EXOS_DATASET_EVENT_DELIVERED can be used to cyclically publish data without receiving an EXOS_ERROR_BUFFER_OVERFLOW on the dataset. Calling another exos_dataset_publish() in the event of EXOS_DATASET_EVENT_DELIVERED would mean that the dataset is being published "as-fast-as-possible", normally meaning every other scan for TCP/IP connections. Example:

  static void datasetEvent(exos_dataset_handle_t *dataset, EXOS_DATASET_EVENT_TYPE event_type, void *info)
  {
      switch (event_type)
      {
      case EXOS_DATASET_EVENT_DELIVERED:
          VERBOSE("dataset %s delivered to remote server for distribution! Sending the next! send buffer free:%i", dataset->name, dataset->send_buffer.free);
          exos_dataset_publish(dataset);

Just like the EXOS_DATASET_EVENT_PUBLISHED, the EXOS_DATASET_EVENT_DELIVERED updates the dataset->send_buffer variable. Now, if publishing like the example above, the dataset->send_buffer.used will always be 0, and dataset->send_buffer.free will remain equal to dataset->send_buffer.size.