2019-09-24 16:30:38 +02:00
|
|
|
/**
|
|
|
|
* @file lv_debug.c
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* INCLUDES
|
|
|
|
*********************/
|
|
|
|
#include "lv_obj.h"
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* DEFINES
|
|
|
|
*********************/
|
2019-09-24 23:14:17 +02:00
|
|
|
#define LV_DEBUG_STR_MAX_LENGTH (1024 * 8)
|
|
|
|
#define LV_DEBUG_STR_MAX_REPEAT 8
|
2019-09-24 16:30:38 +02:00
|
|
|
|
|
|
|
/**********************
|
|
|
|
* TYPEDEFS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* STATIC PROTOTYPES
|
|
|
|
**********************/
|
2019-09-24 23:14:17 +02:00
|
|
|
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
|
2019-09-24 16:30:38 +02:00
|
|
|
|
|
|
|
/**********************
|
|
|
|
* STATIC VARIABLES
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* MACROS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* GLOBAL FUNCTIONS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
bool lv_debug_check_null(const void * p)
|
|
|
|
{
|
|
|
|
if(p) return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-09-24 23:14:17 +02:00
|
|
|
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
|
2019-09-24 16:30:38 +02:00
|
|
|
{
|
2019-09-24 23:14:17 +02:00
|
|
|
if(obj_type[0] == '\0') return true;
|
|
|
|
|
2019-09-24 16:30:38 +02:00
|
|
|
lv_obj_type_t types;
|
2019-09-25 08:58:12 +02:00
|
|
|
lv_obj_get_type((lv_obj_t *)obj, &types);
|
2019-09-24 16:30:38 +02:00
|
|
|
|
|
|
|
uint8_t i;
|
|
|
|
for(i = 0; i < LV_MAX_ANCESTOR_NUM; i++) {
|
|
|
|
if(strcmp(types.type[i], obj_type) == 0) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-09-24 23:14:17 +02:00
|
|
|
bool lv_debug_check_obj_valid(const lv_obj_t * obj)
|
2019-09-24 16:30:38 +02:00
|
|
|
{
|
|
|
|
lv_disp_t * disp = lv_disp_get_next(NULL);
|
|
|
|
while(disp) {
|
|
|
|
lv_obj_t * scr;
|
|
|
|
LV_LL_READ(disp->scr_ll, scr) {
|
|
|
|
|
|
|
|
if(scr == obj) return true;
|
|
|
|
bool found = obj_valid_child(scr, obj);
|
|
|
|
if(found) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
disp = lv_disp_get_next(disp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-09-24 23:14:17 +02:00
|
|
|
bool lv_debug_check_style(const void * str)
|
2019-09-24 16:30:38 +02:00
|
|
|
{
|
2019-09-24 23:14:17 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lv_debug_check_str(const void * str)
|
|
|
|
{
|
|
|
|
const uint8_t * s = (const uint8_t *)str;
|
|
|
|
uint8_t last_byte = 0;
|
|
|
|
uint32_t rep = 0;
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
for(i = 0; s[i] != '\0' && i < LV_DEBUG_STR_MAX_LENGTH; i++) {
|
|
|
|
if(s[i] != last_byte) {
|
|
|
|
last_byte = s[i];
|
|
|
|
rep = 1;
|
|
|
|
} else {
|
|
|
|
rep++;
|
|
|
|
if(rep > LV_DEBUG_STR_MAX_REPEAT) {
|
|
|
|
LV_LOG_WARN("lv_debug_check_str: a char has repeated more than LV_DEBUG_STR_MAX_REPEAT times)");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(s[i] < 10) {
|
|
|
|
LV_LOG_WARN("lv_debug_check_str: invalid char in the string (< 10 value)");
|
|
|
|
return false; /*Shouldn't occur in strings*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(s[i] == '\0') return true;
|
2019-09-24 16:30:38 +02:00
|
|
|
|
2019-09-24 23:14:17 +02:00
|
|
|
LV_LOG_WARN("lv_debug_check_str: string is longer than LV_DEBUG_STR_MAX_LENGTH");
|
2019-09-24 16:30:38 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lv_debug_log_error(const char * msg, unsigned long int value)
|
|
|
|
{
|
|
|
|
static const char hex[] = "0123456789ABCDEF";
|
|
|
|
|
|
|
|
uint32_t msg_len = strlen(msg);
|
|
|
|
uint32_t value_len = sizeof(unsigned long int);
|
|
|
|
|
|
|
|
if(msg_len < 230) {
|
|
|
|
char buf[255];
|
|
|
|
char * bufp = buf;
|
|
|
|
|
|
|
|
/*Add the function name*/
|
|
|
|
memcpy(bufp, msg, msg_len);
|
|
|
|
bufp += msg_len;
|
|
|
|
|
|
|
|
/*Add value in hey*/
|
|
|
|
*bufp = ' ';
|
|
|
|
bufp ++;
|
|
|
|
*bufp = '(';
|
|
|
|
bufp ++;
|
|
|
|
*bufp = '0';
|
|
|
|
bufp ++;
|
|
|
|
*bufp = 'x';
|
|
|
|
bufp ++;
|
|
|
|
|
|
|
|
int8_t i;
|
|
|
|
for(i = value_len * 2 - 1; i >= 0; i--) {
|
|
|
|
uint8_t x = (unsigned long int)((unsigned long int)value >> (i * 4)) & 0xF;
|
|
|
|
|
|
|
|
*bufp = hex[x];
|
|
|
|
bufp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*bufp = ')';
|
|
|
|
bufp ++;
|
|
|
|
|
|
|
|
*bufp = '\0';
|
|
|
|
LV_LOG_ERROR(buf);
|
|
|
|
} else {
|
|
|
|
LV_LOG_ERROR(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* STATIC FUNCTIONS
|
|
|
|
**********************/
|
|
|
|
|
2019-09-24 23:14:17 +02:00
|
|
|
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
|
2019-09-24 16:30:38 +02:00
|
|
|
{
|
|
|
|
/*Check all children of `parent`*/
|
|
|
|
lv_obj_t * child = lv_obj_get_child(parent, NULL);
|
|
|
|
while(child) {
|
|
|
|
if(child == obj_to_find) return true;
|
|
|
|
|
|
|
|
/*Check the children*/
|
|
|
|
bool found = obj_valid_child(child, obj_to_find);
|
|
|
|
if(found) return true;
|
|
|
|
|
|
|
|
child = lv_obj_get_child(parent, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|