targets/plc_debug.c
branch1.1 Korean release
changeset 968 eee7625de1f7
parent 954 ab487d32ce9a
child 969 1950fe687dde
equal deleted inserted replaced
808:6e205c1f05a0 968:eee7625de1f7
   182     BufferIterator(varp, vartype, 0);
   182     BufferIterator(varp, vartype, 0);
   183 }
   183 }
   184 
   184 
   185 extern int TryEnterDebugSection(void);
   185 extern int TryEnterDebugSection(void);
   186 extern long AtomicCompareExchange(long*, long, long);
   186 extern long AtomicCompareExchange(long*, long, long);
       
   187 extern long long AtomicCompareExchange64(long long* , long long , long long);
   187 extern void LeaveDebugSection(void);
   188 extern void LeaveDebugSection(void);
   188 extern void ValidateRetainBuffer(void);
   189 extern void ValidateRetainBuffer(void);
   189 extern void InValidateRetainBuffer(void);
   190 extern void InValidateRetainBuffer(void);
   190 
   191 
   191 void __publish_debug(void)
   192 void __publish_debug(void)
   300         *buffer = debug_buffer;
   301         *buffer = debug_buffer;
   301     }
   302     }
   302     return wait_error;
   303     return wait_error;
   303 }
   304 }
   304 
   305 
       
   306 
       
   307 /* LOGGING
       
   308 */
       
   309 
       
   310 #define LOG_LEVELS 4
       
   311 #define LOG_CRITICAL 0
       
   312 #define LOG_WARNING 1
       
   313 #define LOG_INFO 2
       
   314 #define LOG_DEBUG 3
       
   315 
       
   316 #ifndef LOG_BUFFER_SIZE
       
   317 #define LOG_BUFFER_SIZE (1<<14) /*16Ko*/
       
   318 #endif
       
   319 #define LOG_BUFFER_MASK (LOG_BUFFER_SIZE-1)
       
   320 static char LogBuff[LOG_LEVELS][LOG_BUFFER_SIZE];
       
   321 void inline copy_to_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
       
   322     if(buffpos + size < LOG_BUFFER_SIZE){
       
   323         memcpy(&LogBuff[level][buffpos], buf, size);
       
   324     }else{
       
   325         uint32_t remaining = LOG_BUFFER_SIZE - buffpos - 1; 
       
   326         memcpy(&LogBuff[level][buffpos], buf, remaining);
       
   327         memcpy(LogBuff[level], buf + remaining, size - remaining);
       
   328     }
       
   329 }
       
   330 void inline copy_from_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
       
   331     if(buffpos + size < LOG_BUFFER_SIZE){
       
   332         memcpy(buf, &LogBuff[level][buffpos], size);
       
   333     }else{
       
   334         uint32_t remaining = LOG_BUFFER_SIZE - buffpos; 
       
   335         memcpy(buf, &LogBuff[level][buffpos], remaining);
       
   336         memcpy(buf + remaining, LogBuff[level], size - remaining);
       
   337     }
       
   338 }
       
   339 
       
   340 /* Log buffer structure
       
   341 
       
   342  |<-Tail1.msgsize->|<-sizeof(mTail)->|<--Tail2.msgsize-->|<-sizeof(mTail)->|...
       
   343  |  Message1 Body  |      Tail1      |   Message2 Body   |      Tail2      |
       
   344 
       
   345 */
       
   346 typedef struct {
       
   347     uint32_t msgidx;
       
   348     uint32_t msgsize;
       
   349     unsigned long tick;
       
   350     IEC_TIME time;
       
   351 } mTail;
       
   352 
       
   353 /* Log cursor : 64b
       
   354    |63 ... 32|31 ... 0|
       
   355    | Message | Buffer |
       
   356    | counter | Index  | */
       
   357 static uint64_t LogCursor[LOG_LEVELS] = {0x0,0x0,0x0,0x0};
       
   358 
       
   359 /* Store one log message of give size */
       
   360 int LogMessage(uint8_t level, char* buf, uint32_t size){
       
   361     if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
       
   362         uint32_t buffpos;
       
   363         uint64_t new_cursor, old_cursor;
       
   364 
       
   365         mTail tail;
       
   366         tail.msgsize = size;
       
   367         tail.tick = __tick;
       
   368         PLC_GetTime(&tail.time);
       
   369 
       
   370         /* We cannot increment both msg index and string pointer 
       
   371            in a single atomic operation but we can detect having been interrupted.
       
   372            So we can try with atomic compare and swap in a loop until operation
       
   373            succeeds non interrupted */
       
   374         do{
       
   375             old_cursor = LogCursor[level];
       
   376             buffpos = (uint32_t)old_cursor;
       
   377             tail.msgidx = (old_cursor >> 32); 
       
   378             new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) 
       
   379                          | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
       
   380         }while(AtomicCompareExchange64(
       
   381             (long long*)&LogCursor[level],
       
   382             (long long)old_cursor,
       
   383             (long long)new_cursor)!=old_cursor);
       
   384 
       
   385         copy_to_log(level, buffpos, buf, size);
       
   386         copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
       
   387 
       
   388         return 1; /* Success */
       
   389     }else{
       
   390         char mstr[] = "Logging error : message too big";
       
   391         LogMessage(LOG_CRITICAL, mstr, sizeof(mstr));
       
   392     }
       
   393     return 0;
       
   394 }
       
   395 
       
   396 uint32_t GetLogCount(uint8_t level){
       
   397     return (uint64_t)LogCursor[level] >> 32;
       
   398 }
       
   399 
       
   400 /* Return message size and content */
       
   401 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){
       
   402     uint64_t cursor = LogCursor[level];
       
   403     if(cursor){
       
   404         /* seach cursor */
       
   405         uint32_t stailpos = (uint32_t)cursor; 
       
   406         uint32_t smsgidx;
       
   407         mTail tail;
       
   408         tail.msgidx = cursor >> 32;
       
   409         tail.msgsize = 0;
       
   410 
       
   411         /* Message search loop */
       
   412         do {
       
   413             smsgidx = tail.msgidx;
       
   414             stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK;
       
   415             copy_from_log(level, stailpos, &tail, sizeof(mTail));
       
   416         }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx));
       
   417 
       
   418         if(tail.msgidx == msgidx){
       
   419             uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; 
       
   420             uint32_t totalsize = tail.msgsize;
       
   421             *tick = tail.tick; 
       
   422             *tv_sec = tail.time.tv_sec; 
       
   423             *tv_nsec = tail.time.tv_nsec; 
       
   424             copy_from_log(level, sbuffpos, buf, 
       
   425                           totalsize > max_size ? max_size : totalsize);
       
   426             return totalsize;
       
   427         }
       
   428     }
       
   429     return 0;
       
   430 }