targets/plc_debug.c
changeset 917 401e44bae7c0
parent 911 ffa24427396a
child 921 a8db48ec2c31
equal deleted inserted replaced
916:697d8b77d716 917:401e44bae7c0
   304 
   304 
   305 
   305 
   306 /* LOGGING
   306 /* LOGGING
   307 */
   307 */
   308 
   308 
       
   309 #define LOG_LEVELS 4
       
   310 #define LOG_CRITICAL 0
       
   311 #define LOG_WARNING 1
       
   312 #define LOG_INFO 2
       
   313 #define LOG_DEBUG 4
       
   314 
   309 #define LOG_BUFFER_SIZE (1<<14) /*16Ko*/
   315 #define LOG_BUFFER_SIZE (1<<14) /*16Ko*/
   310 #define LOG_BUFFER_MASK (LOG_BUFFER_SIZE-1)
   316 #define LOG_BUFFER_MASK (LOG_BUFFER_SIZE-1)
   311 static char LogBuff[LOG_BUFFER_SIZE];
   317 static char LogBuff[LOG_LEVELS][LOG_BUFFER_SIZE];
   312 void inline copy_to_log(uint32_t buffpos, void* buf, uint32_t size){
   318 void inline copy_to_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
   313     if(buffpos + size < LOG_BUFFER_SIZE){
   319     if(buffpos + size < LOG_BUFFER_SIZE){
   314         memcpy(&LogBuff[buffpos], buf, size);
   320         memcpy(&LogBuff[level][buffpos], buf, size);
   315     }else{
   321     }else{
   316         uint32_t remaining = LOG_BUFFER_SIZE - buffpos - 1; 
   322         uint32_t remaining = LOG_BUFFER_SIZE - buffpos - 1; 
   317         memcpy(&LogBuff[buffpos], buf, remaining);
   323         memcpy(&LogBuff[level][buffpos], buf, remaining);
   318         memcpy(LogBuff, buf + remaining, size - remaining);
   324         memcpy(LogBuff[level], buf + remaining, size - remaining);
   319     }
   325     }
   320 }
   326 }
   321 void inline copy_from_log(uint32_t buffpos, void* buf, uint32_t size){
   327 void inline copy_from_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
   322     if(buffpos + size < LOG_BUFFER_SIZE){
   328     if(buffpos + size < LOG_BUFFER_SIZE){
   323         memcpy(buf, &LogBuff[buffpos], size);
   329         memcpy(buf, &LogBuff[level][buffpos], size);
   324     }else{
   330     }else{
   325         uint32_t remaining = LOG_BUFFER_SIZE - buffpos; 
   331         uint32_t remaining = LOG_BUFFER_SIZE - buffpos; 
   326         memcpy(buf, &LogBuff[buffpos], remaining);
   332         memcpy(buf, &LogBuff[level][buffpos], remaining);
   327         memcpy(buf + remaining, LogBuff, size - remaining);
   333         memcpy(buf + remaining, LogBuff[level], size - remaining);
   328     }
   334     }
   329 }
   335 }
   330 
   336 
   331 /* Log buffer structure
   337 /* Log buffer structure
   332 
   338 
   343 
   349 
   344 /* Log cursor : 64b
   350 /* Log cursor : 64b
   345    |63 ... 32|31 ... 0|
   351    |63 ... 32|31 ... 0|
   346    | Message | Buffer |
   352    | Message | Buffer |
   347    | counter | Index  | */
   353    | counter | Index  | */
   348 static uint64_t LogCursor = 0x0;
   354 static uint64_t LogCursor[LOG_LEVELS] = {0x0,0x0,0x0,0x0};
   349 
   355 
   350 /* Store one log message of give size */
   356 /* Store one log message of give size */
   351 int LogMessage(char* buf, uint32_t size){
   357 int LogMessage(uint8_t level, char* buf, uint32_t size){
   352     if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
   358     if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
   353         uint32_t buffpos;
   359         uint32_t buffpos;
   354         mTail tail;
   360         mTail tail;
   355         /* We cannot increment both msg index and string pointer 
   361         /* We cannot increment both msg index and string pointer 
   356            in a single atomic operation but we can detect having been interrupted.
   362            in a single atomic operation but we can detect having been interrupted.
   357            So we can try with atomic compare and swap in a loop until operation
   363            So we can try with atomic compare and swap in a loop until operation
   358            succeeds non interrupted */
   364            succeeds non interrupted */
   359         uint64_t new_cursor, old_cursor;
   365         uint64_t new_cursor, old_cursor;
   360         do{
   366         do{
   361             old_cursor = LogCursor;
   367             old_cursor = LogCursor[level];
   362             buffpos = (uint32_t)old_cursor;
   368             buffpos = (uint32_t)old_cursor;
   363             tail.msgidx = (old_cursor >> 32); 
   369             tail.msgidx = (old_cursor >> 32); 
   364             new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) 
   370             new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) 
   365                          | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
   371                          | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
   366         }while(!__sync_bool_compare_and_swap(&LogCursor,old_cursor,new_cursor));
   372         }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor));
   367 
   373 
   368         copy_to_log(buffpos, buf, size);
   374         copy_to_log(level, buffpos, buf, size);
   369         tail.msgsize = size;
   375         tail.msgsize = size;
   370         /*XXX tick*/
   376         /*XXX tick*/
   371         /*XXX RTC*/
   377         /*XXX RTC*/
   372         copy_to_log((buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
   378         copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
   373 
   379 
   374         return 1; /* Success */
   380         return 1; /* Success */
   375     }else{
   381     }else{
   376         char mstr[] = "Logging error : message too big";
   382         char mstr[] = "Logging error : message too big";
   377         LogMessage(mstr, sizeof(mstr));
   383         LogMessage(LOG_CRITICAL, mstr, sizeof(mstr));
   378     }
   384     }
   379     return 0;
   385     return 0;
   380 }
   386 }
   381 
   387 
   382 uint32_t GetLogCount(){
   388 uint32_t GetLogCount(uint8_t level){
   383     return (uint64_t)LogCursor >> 32;
   389     return (uint64_t)LogCursor[level] >> 32;
   384 }
   390 }
   385 
   391 
   386 /* Return message size and content */
   392 /* Return message size and content */
   387 uint32_t GetLogMessage(uint32_t msgidx, char* buf, uint32_t max_size){
   393 uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size){
   388     uint64_t cursor = LogCursor;
   394     uint64_t cursor = LogCursor[level];
   389     if(cursor){
   395     if(cursor){
   390         /* seach cursor */
   396         /* seach cursor */
   391         uint32_t stailpos = (uint32_t)cursor; 
   397         uint32_t stailpos = (uint32_t)cursor; 
   392         uint32_t smsgidx;
   398         uint32_t smsgidx;
   393         mTail tail;
   399         mTail tail;
   396 
   402 
   397         /* Message search loop */
   403         /* Message search loop */
   398         do {
   404         do {
   399             smsgidx = tail.msgidx;
   405             smsgidx = tail.msgidx;
   400             stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK;
   406             stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK;
   401             copy_from_log(stailpos, &tail, sizeof(mTail));
   407             copy_from_log(level, stailpos, &tail, sizeof(mTail));
   402         }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx));
   408         }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx));
   403 
   409 
   404         if(tail.msgidx == msgidx){
   410         if(tail.msgidx == msgidx){
   405             uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; 
   411             uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; 
   406             uint32_t totalsize = tail.msgsize; /*sizeof(mTail);*/
   412             uint32_t totalsize = tail.msgsize; /*sizeof(mTail);*/
   407             copy_from_log(sbuffpos, buf, totalsize > max_size ? max_size : totalsize);
   413             copy_from_log(level, sbuffpos, buf, totalsize > max_size ? max_size : totalsize);
   408             return totalsize;
   414             return totalsize;
   409         }
   415         }
   410     }
   416     }
   411     return 0;
   417     return 0;
   412 }
   418 }