svghmi/svghmi.c
branchsvghmi
changeset 2771 361366b891ca
parent 2768 31785529a657
child 2775 3b93409ba22c
equal deleted inserted replaced
2770:41fc23fd21c4 2771:361366b891ca
    13 /* PLC writes to that buffer */
    13 /* PLC writes to that buffer */
    14 static char wbuf[HMI_BUFFER_SIZE];
    14 static char wbuf[HMI_BUFFER_SIZE];
    15 
    15 
    16 %(extern_variables_declarations)s
    16 %(extern_variables_declarations)s
    17 
    17 
    18 #define ticktime_ns %(PLC_ticktime)d;
    18 #define ticktime_ns %(PLC_ticktime)d
    19 uint16_t ticktime_ms (ticktime_ns>1000000)?
    19 uint16_t ticktime_ms = (ticktime_ns>1000000)?
    20                      ticktime_ns/1000000:
    20                      ticktime_ns/1000000:
    21                      1;
    21                      1;
    22 
    22 
    23 typedef enum {
    23 typedef enum {
    24     buf_free = 0,
    24     buf_free = 0,
    26     buf_tosend
    26     buf_tosend
    27 } buf_state_t;
    27 } buf_state_t;
    28 
    28 
    29 int global_write_dirty = 0;
    29 int global_write_dirty = 0;
    30 
    30 
    31 typedef const struct {
    31 typedef struct {
    32     void *ptr;
    32     void *ptr;
    33     __IEC_types_enum type;
    33     __IEC_types_enum type;
    34     uint32_t buf_index;
    34     uint32_t buf_index;
    35 
    35 
    36     /* publish/write/send */
    36     /* publish/write/send */
    37     int wlock;
    37     long wlock;
    38     /* zero means not subscribed */
    38     /* zero means not subscribed */
    39     uint16_t refresh_period_ms;
    39     uint16_t refresh_period_ms;
    40     uint16_t age_ms;
    40     uint16_t age_ms;
    41 
    41 
    42     buf_state_t wstate;
    42     buf_state_t wstate;
    43 
    43 
    44     /* retrieve/read/recv */
    44     /* retrieve/read/recv */
    45     int rlock;
    45     long rlock;
    46     buf_state_t rstate;
    46     buf_state_t rstate;
    47 
    47 
    48 } hmi_tree_item_t;
    48 } hmi_tree_item_t;
    49 
    49 
    50 static hmi_tree_item_t hmi_tree_item[] = {
    50 static hmi_tree_item_t hmi_tree_item[] = {
    80     if(was_locked) {
    80     if(was_locked) {
    81         /* was locked. give up*/
    81         /* was locked. give up*/
    82         return;
    82         return;
    83     }
    83     }
    84 
    84 
    85     if(dsc->wstate == buf_set)
    85     if(dsc->wstate == buf_set){
    86         /* if being subscribed */
    86         /* if being subscribed */
    87         if(dsc->refresh_period_ms){
    87         if(dsc->refresh_period_ms){
    88             if(dsc->age_ms + ticktime_ms < dsc->refresh_period_ms){
    88             if(dsc->age_ms + ticktime_ms < dsc->refresh_period_ms){
    89                 dsc->age_ms += ticktime_ms;
    89                 dsc->age_ms += ticktime_ms;
    90             }else{
    90             }else{
   113 void send_iterator(hmi_tree_item_t *dsc)
   113 void send_iterator(hmi_tree_item_t *dsc)
   114 {
   114 {
   115     while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
   115     while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
   116 
   116 
   117     // check for variable being modified
   117     // check for variable being modified
   118     if(dsc->wstat == buf_tosend){
   118     if(dsc->wstate == buf_tosend){
   119         // send 
   119         // send 
   120 
   120 
   121         // TODO write to some socket
   121         // TODO call the python callback 
   122 
   122 
   123         dsc->wstate = buf_free; 
   123         dsc->wstate = buf_free; 
   124     }
   124     }
   125 
   125 
   126     AtomicCompareExchange(&dsc->wlock, 1, 0);
   126     AtomicCompareExchange(&dsc->wlock, 1, 0);
   141 int __init_svghmi()
   141 int __init_svghmi()
   142 {
   142 {
   143     bzero(rbuf,sizeof(rbuf));
   143     bzero(rbuf,sizeof(rbuf));
   144     bzero(wbuf,sizeof(wbuf));
   144     bzero(wbuf,sizeof(wbuf));
   145     
   145     
   146     // create - connection endpoint
   146     // TODO - sending pthread condition variable
   147     //        - sending thread
       
   148     //        - sending semaphore
       
   149     //        - recv thread
       
   150 
   147 
   151     return 0;
   148     return 0;
   152 }
   149 }
   153 
   150 
   154 void __cleanup_svghmi()
   151 void __cleanup_svghmi()
   163 void __publish_svghmi()
   160 void __publish_svghmi()
   164 {
   161 {
   165     global_write_dirty = 0;
   162     global_write_dirty = 0;
   166     traverse_hmi_tree(write_iterator);
   163     traverse_hmi_tree(write_iterator);
   167     if(global_write_dirty) {
   164     if(global_write_dirty) {
   168         // TODO : set emaphore to wakeup sending thread
   165         // TODO : set condition variable to wakeup sending collector
   169     }
   166     }
   170 
   167 
   171 }
   168 }
   172 
   169 
   173 void sending_thread_proc(void* args){
   170 void* collect_updates_to_send(void* args){
       
   171 
       
   172     // TODO : get callback from args
       
   173 
   174 
   174 
   175     // TODO : wait for 
   175     // TODO : wait for 
   176     //        - semaphore
   176     //        - condition variable
   177     //        - next autonomous send thread wakeup. (impl as wait timeout ?) 
   177 
       
   178     // TODO add arg to traverse_hmi_tree to pass callback
   178 
   179 
   179     traverse_hmi_tree(send_iterator);
   180     traverse_hmi_tree(send_iterator);
       
   181 
   180 }
   182 }