targets/plc_debug.c
changeset 921 a8db48ec2c31
parent 917 401e44bae7c0
child 923 6ef6e0b3a908
equal deleted inserted replaced
920:1499a4d225db 921:a8db48ec2c31
   341 
   341 
   342 */
   342 */
   343 typedef struct {
   343 typedef struct {
   344     uint32_t msgidx;
   344     uint32_t msgidx;
   345     uint32_t msgsize;
   345     uint32_t msgsize;
   346     /*XXX tick*/
   346     unsigned long tick;
   347     /*XXX RTC*/
   347     IEC_TIME time;
   348 } mTail;
   348 } mTail;
   349 
   349 
   350 /* Log cursor : 64b
   350 /* Log cursor : 64b
   351    |63 ... 32|31 ... 0|
   351    |63 ... 32|31 ... 0|
   352    | Message | Buffer |
   352    | Message | Buffer |
   355 
   355 
   356 /* Store one log message of give size */
   356 /* Store one log message of give size */
   357 int LogMessage(uint8_t level, char* buf, uint32_t size){
   357 int LogMessage(uint8_t level, char* buf, uint32_t size){
   358     if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
   358     if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
   359         uint32_t buffpos;
   359         uint32_t buffpos;
       
   360         uint64_t new_cursor, old_cursor;
       
   361 
   360         mTail tail;
   362         mTail tail;
       
   363         tail.msgsize = size;
       
   364         tail.tick = __tick;
       
   365         PLC_GetTime(&tail.time);
       
   366 
   361         /* We cannot increment both msg index and string pointer 
   367         /* We cannot increment both msg index and string pointer 
   362            in a single atomic operation but we can detect having been interrupted.
   368            in a single atomic operation but we can detect having been interrupted.
   363            So we can try with atomic compare and swap in a loop until operation
   369            So we can try with atomic compare and swap in a loop until operation
   364            succeeds non interrupted */
   370            succeeds non interrupted */
   365         uint64_t new_cursor, old_cursor;
       
   366         do{
   371         do{
   367             old_cursor = LogCursor[level];
   372             old_cursor = LogCursor[level];
   368             buffpos = (uint32_t)old_cursor;
   373             buffpos = (uint32_t)old_cursor;
   369             tail.msgidx = (old_cursor >> 32); 
   374             tail.msgidx = (old_cursor >> 32); 
   370             new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) 
   375             new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) 
   371                          | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
   376                          | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
   372         }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor));
   377         }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor));
   373 
   378 
   374         copy_to_log(level, buffpos, buf, size);
   379         copy_to_log(level, buffpos, buf, size);
   375         tail.msgsize = size;
       
   376         /*XXX tick*/
       
   377         /*XXX RTC*/
       
   378         copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
   380         copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
   379 
   381 
   380         return 1; /* Success */
   382         return 1; /* Success */
   381     }else{
   383     }else{
   382         char mstr[] = "Logging error : message too big";
   384         char mstr[] = "Logging error : message too big";
   388 uint32_t GetLogCount(uint8_t level){
   390 uint32_t GetLogCount(uint8_t level){
   389     return (uint64_t)LogCursor[level] >> 32;
   391     return (uint64_t)LogCursor[level] >> 32;
   390 }
   392 }
   391 
   393 
   392 /* Return message size and content */
   394 /* Return message size and content */
   393 uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size){
   395 uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size, uint32_t* tick, uint32_t* tv_sec, uint32_t* tv_nsec){
   394     uint64_t cursor = LogCursor[level];
   396     uint64_t cursor = LogCursor[level];
   395     if(cursor){
   397     if(cursor){
   396         /* seach cursor */
   398         /* seach cursor */
   397         uint32_t stailpos = (uint32_t)cursor; 
   399         uint32_t stailpos = (uint32_t)cursor; 
   398         uint32_t smsgidx;
   400         uint32_t smsgidx;
   407             copy_from_log(level, stailpos, &tail, sizeof(mTail));
   409             copy_from_log(level, stailpos, &tail, sizeof(mTail));
   408         }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx));
   410         }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx));
   409 
   411 
   410         if(tail.msgidx == msgidx){
   412         if(tail.msgidx == msgidx){
   411             uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; 
   413             uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; 
   412             uint32_t totalsize = tail.msgsize; /*sizeof(mTail);*/
   414             uint32_t totalsize = tail.msgsize;
   413             copy_from_log(level, sbuffpos, buf, totalsize > max_size ? max_size : totalsize);
   415             *tick = tail.tick; 
       
   416             *tv_sec = tail.time.tv_sec; 
       
   417             *tv_nsec = tail.time.tv_nsec; 
       
   418             copy_from_log(level, sbuffpos, buf, 
       
   419                           totalsize > max_size ? max_size : totalsize);
   414             return totalsize;
   420             return totalsize;
   415         }
   421         }
   416     }
   422     }
   417     return 0;
   423     return 0;
   418 }
   424 }