/******************************************************************************
版权所有：	文件名称：	printf_e907.c
文件版本：	01.01
创建作者：	sunxi
创建日期：	2022-5-11
功能说明：	打印裸核e907的信息
其它说明：
修改记录：
*/
#include "bspconfig.h"
#include "bsp.h"
#include "shm_comm_packet.h"

#include <linux/sched.h>
#include <sys/prctl.h>


#define	P_BUF_LEN_MAX	4096 //buf总长度


//打印数据结构体
typedef struct SHM_PRINTF_T
{
	uint16_t A;
	uint16_t B;
	uint16_t w;
	uint16_t r;
	uint16_t crc;
}SHM_PRINTF_T;



static uint8_t p_buf[P_BUF_LEN_MAX];


static uint16_t	w_p = 0; //写指针
static uint16_t	r_p = 0; //读指针

#if 0
static char test_1[] = "printf_e907_func----------------------\r\n";
static char test_2[] = "printf_e907_func----------------------123\r\n";
static char test_3[] = "printf_e907_func----------------------456\r\n";
#endif

static pthread_t printf_e907_tid = 0;
static int printf_e907_func(void *arg);

static int exit_flag = 0; 

extern int main_mod_is_exit(void);

static int get_printf_wr(uint8_t *out_data)
{
	int ret = 0;
	int cnt = 0;

	if(out_data == NULL)
		return -1;
		
    while(1)
    {
		ret = shm_comm_packet_read(SHM_ADDR_U_WR, sizeof(SHM_PRINTF_T), out_data, sizeof(SHM_PRINTF_T));
		if(ret > 0)	
		{
			break;
		}

		if(++cnt > 3)
			break;

        usleep(30);
    }
    return ret;
}


/******************************************************************************
函数名称：	printf_e907_func
函数版本：	01.01
创建作者：	sunxi
创建日期：	2022-5-11
函数说明：	打印工作函数.
参数说明：		
返回值：	返回0
修改记录：	
*/
static int printf_e907_func(void *arg)
{
	SHM_PRINTF_T wr;
	int ret = 0;
	int len = 0;
	int len_1 = 0;

	memset(p_buf,0,sizeof(p_buf));
	w_p = 0;
	r_p = 0;

#if 0
	strcpy(&p_buf[w_p],test_1);
	w_p += strlen(test_1);
	strcpy(&p_buf[w_p],test_2);
	w_p += strlen(test_2);
	strcpy(&p_buf[w_p],test_3);
	w_p += strlen(test_3);

	rt_printf(p_buf);
#endif

    uint32_t wdt_id;
    int rc = watchdog_add_item("printf_e907_func", &wdt_id,120);
    if(rc != 0) {
        printf("can not add printf_e907_func task to wdt\r\n");
        return 0;
    }

	prctl(PR_SET_NAME, "printf_e907");
	while(!exit_flag)
	{

		msleep(10);

		watchdog_feed(wdt_id);

		if(main_mod_is_exit())
		{
			break;
		}
		
		w_p = 0;
		
		//获取w,r
		memset(&wr,0,sizeof(wr));
		ret = get_printf_wr((uint8_t *)&wr);
		if(ret >= 0)
		{
			w_p = wr.w;
		}

		//rt_printf("w_p = %d, r_p = %d\r\n",w_p,r_p);

		if(w_p != r_p)
		{
			memset(p_buf,0,sizeof(p_buf));
			//获取打印信息
			if(w_p > r_p)
			{
				len = w_p - r_p;
				ret = shm_read(SHM_ADDR_U_DEBUG_MSG+r_p, len, p_buf, sizeof(p_buf));
				if(ret > 0)
					r_p += ret;
			}
			else
			{
				//w_p指针翻滚，过0
				//分两段读取，再合并
				len = P_BUF_LEN_MAX-r_p;
				ret = shm_read(SHM_ADDR_U_DEBUG_MSG+r_p, len, p_buf, sizeof(p_buf));
				if(ret > 0)
					r_p += ret;

				len_1 = w_p;
				ret = shm_read(SHM_ADDR_U_DEBUG_MSG, len_1, &p_buf[len], sizeof(p_buf)-len);	
				if(ret > 0)
					r_p = ret;
			}
			
			if(r_p >= P_BUF_LEN_MAX)
				r_p = 0;

			p_buf[sizeof(p_buf)-1] = 0;//保证结束
			if(ret > 0)
			{
				rt_printf(p_buf);
				rt_printf("\r\n");
			}

		}
	
	}

	watchdog_remove_item(wdt_id);

	return 0;
}


/******************************************************************************
函数名称：	printf_e907_init
函数版本：	01.01
创建作者：	sunxi
创建日期：	2022-5-11
函数说明：	初始化.
参数说明：	
					无					
返回值：	成功返回0, 失败返回-1
修改记录：	
*/
int printf_e907_init(void)
{
	int ret;

	ret = pthread_create(&printf_e907_tid, NULL, (void *)printf_e907_func, NULL);
	if(ret)
	{
		rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
		printf_e907_tid = 0;
		return ret;
	}
	
	return 0;	
}

/******************************************************************************
函数名称：	printf_e907_exit
函数版本：	01.01
创建作者：	sunxi
创建日期：	2022-5-11
函数说明：	反初始化.
参数说明：	
					无					
返回值：	总是返回0.
修改记录：	
*/
int printf_e907_exit(void)
{
	exit_flag = 1;

	pthread_join(printf_e907_tid, NULL);
	return 0;
}




 
 
 
 
