diff -r 5d174cdf4d98 -r 38f7122ccbf9 svghmi/svghmi.c --- a/svghmi/svghmi.c Mon Jul 05 10:51:02 2021 +0200 +++ b/svghmi/svghmi.c Wed Jul 07 16:31:13 2021 +0200 @@ -9,6 +9,8 @@ #define HMI_BUFFER_SIZE %(buffer_size)d #define HMI_ITEM_COUNT %(item_count)d #define HMI_HASH_SIZE 8 +#define MAX_CONNECTIONS %(max_connections)d + static uint8_t hmi_hash[HMI_HASH_SIZE] = {%(hmi_hash_ints)s}; /* PLC reads from that buffer */ @@ -45,11 +47,11 @@ /* publish/write/send */ long wlock; - buf_state_t wstate; + buf_state_t wstate[MAX_CONNECTIONS]; /* zero means not subscribed */ - uint16_t refresh_period_ms; - uint16_t age_ms; + uint16_t refresh_period_ms[MAX_CONNECTIONS]; + uint16_t age_ms[MAX_CONNECTIONS]; /* retrieve/read/recv */ long rlock; @@ -81,15 +83,16 @@ static int write_iterator(uint32_t index, hmi_tree_item_t *dsc) { - if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) - { - if(dsc->wstate == buf_set){ + uint32_t session_index = 0; + if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) while(session_index < MAX_CONNECTIONS) + { + if(dsc->wstate[session_index] == buf_set){ /* if being subscribed */ - if(dsc->refresh_period_ms){ - if(dsc->age_ms + ticktime_ms < dsc->refresh_period_ms){ - dsc->age_ms += ticktime_ms; + if(dsc->refresh_period_ms[session_index]){ + if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){ + dsc->age_ms[session_index] += ticktime_ms; }else{ - dsc->wstate = buf_tosend; + dsc->wstate[session_index] = buf_tosend; global_write_dirty = 1; } } @@ -105,34 +108,36 @@ if(__Is_a_string(dsc)){ sz = ((STRING*)visible_value_p)->len + 1; } - if(dsc->wstate == buf_new /* just subscribed + if(dsc->wstate[session_index] == buf_new /* just subscribed or already subscribed having value change */ - || (dsc->refresh_period_ms > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){ + || (dsc->refresh_period_ms[session_index] > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){ /* copy and flag as set */ memcpy(dest_p, visible_value_p, sz); /* if not already marked/signaled, do it */ - if(dsc->wstate != buf_set && dsc->wstate != buf_tosend) { - if(dsc->wstate == buf_new || ticktime_ms > dsc->refresh_period_ms){ - dsc->wstate = buf_tosend; + if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) { + if(dsc->wstate[session_index] == buf_new || ticktime_ms > dsc->refresh_period_ms[session_index]){ + dsc->wstate[session_index] = buf_tosend; global_write_dirty = 1; } else { - dsc->wstate = buf_set; - } - dsc->age_ms = 0; + dsc->wstate[session_index] = buf_set; + } + dsc->age_ms[session_index] = 0; } } AtomicCompareExchange(&dsc->wlock, 1, 0); + session_index++; } // else ... : PLC can't wait, variable will be updated next turn return 0; } +static uint32_t send_session_index; static int send_iterator(uint32_t index, hmi_tree_item_t *dsc) { while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield(); - if(dsc->wstate == buf_tosend) + if(dsc->wstate[send_session_index] == buf_tosend) { uint32_t sz = __get_type_enum_size(dsc->type); if(sbufidx + sizeof(uint32_t) + sz <= sizeof(sbuf)) @@ -145,7 +150,7 @@ /* TODO : force into little endian */ memcpy(dst_p, &index, sizeof(uint32_t)); memcpy(dst_p + sizeof(uint32_t), src_p, sz); - dsc->wstate = buf_free; + dsc->wstate[send_session_index] = buf_free; sbufidx += sizeof(uint32_t) /* index */ + sz; } else @@ -179,24 +184,25 @@ return 0; } -void update_refresh_period(hmi_tree_item_t *dsc, uint16_t refresh_period_ms) +void update_refresh_period(hmi_tree_item_t *dsc, uint32_t session_index, uint16_t refresh_period_ms) { while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield(); if(refresh_period_ms) { - if(!dsc->refresh_period_ms) - { - dsc->wstate = buf_new; + if(!dsc->refresh_period_ms[session_index]) + { + dsc->wstate[session_index] = buf_new; } } else { - dsc->wstate = buf_free; - } - dsc->refresh_period_ms = refresh_period_ms; + dsc->wstate[session_index] = buf_free; + } + dsc->refresh_period_ms[session_index] = refresh_period_ms; AtomicCompareExchange(&dsc->wlock, 1, 0); } +static uint32_t reset_session_index; static int reset_iterator(uint32_t index, hmi_tree_item_t *dsc) { - update_refresh_period(dsc, 0); + update_refresh_period(dsc, reset_session_index, 0); return 0; } @@ -236,13 +242,14 @@ } /* PYTHON CALLS */ -int svghmi_send_collect(uint32_t *size, char **ptr){ +int svghmi_send_collect(uint32_t session_index, uint32_t *size, char **ptr){ SVGHMI_SuspendFromPythonThread(); if(continue_collect) { int res; sbufidx = HMI_HASH_SIZE; + send_session_index = session_index; if((res = traverse_hmi_tree(send_iterator)) == 0) { if(sbufidx > HMI_HASH_SIZE){ @@ -270,7 +277,7 @@ // Returns : // 0 is OK, <0 is error, 1 is heartbeat -int svghmi_recv_dispatch(uint32_t size, const uint8_t *ptr){ +int svghmi_recv_dispatch(uint32_t session_index, uint32_t size, const uint8_t *ptr){ const uint8_t* cursor = ptr + HMI_HASH_SIZE; const uint8_t* end = ptr + size; @@ -336,6 +343,7 @@ case reset: { progress = 0; + reset_session_index = session_index; traverse_hmi_tree(reset_iterator); } break; @@ -348,7 +356,7 @@ if(index < HMI_ITEM_COUNT) { hmi_tree_item_t *dsc = &hmi_tree_item[index]; - update_refresh_period(dsc, refresh_period_ms); + update_refresh_period(dsc, session_index, refresh_period_ms); } else {