#include "sr_sunrise.h"

// 自定义数据结构
typedef struct Person
{
	char *name;
	int age;
	float num;
} Person_T;

Person_T person = {"piter", 18, 3.1415926};

#ifdef SR_USE_OS
/*************OS环境写法*******************/
// 线程1
static SR_THD_RET Thread1Func(void *args)
{
	osThreadId_t thdId = osThreadGetId();
	const char *name = osThreadGetName(thdId);
	Person_T *person = (Person_T *)args;

	// 打印线程id、name
	SR_LOG(INFO, "thd1 enter,name: %s   id: %d\r\n", name, (uint32_t)thdId);

	// 打印用户参数
	SR_LOG(INFO, "Person: name(%s)  age(%d) num(%f)\r\n", person->name, person->age, person->num);

	while (gShellThreadRun)
	{

		SR_LOG(INFO, "thread1 loop\r\n");
		osDelay(1000);
	}

	SR_LOG(INFO, "thread1 exit\r\n");
	osThreadExit(); // 退出线程（不加这个，线程返回会出错）
}

// 线程
static SR_THD_RET ThreadFunc(void *args)
{
	osThreadId_t thdId = osThreadGetId();
	const char *name = osThreadGetName(thdId);

	SR_LOG(INFO, "%s enter, id: %d\r\n", name, (uint32_t)thdId);
	while (gShellThreadRun)
	{

		SR_LOG(INFO, "%s loop\r\n", name);
		osDelay(3000);
	}

	SR_LOG(INFO, "%s exit\r\n", name);
	osThreadExit(); // 退出线程（不加这个，线程返回会出错）
}
#else
/*************裸机环境写法*******************/
// 线程1
static SR_THD_RET Thread1Func(void *args)
{
	osThreadId_t thdId = osThreadGetId();
	const char *name = osThreadGetName(thdId);
	Person_T *person = (Person_T *)args;

	SR_GET_CT(); // 获取当前上下文
	SR_CT_BEGIN();			   // 上下文环境起始

	// 打印线程id、name
	SR_LOG(INFO, "thd1 enter,name: %s   id: %d\r\n", name, (uint32_t)thdId);
	// 打印用户参数
	SR_LOG(INFO, "Person: name(%s)  age(%d) num(%f)\r\n", person->name, person->age, person->num);

	while (gShellThreadRun)
	{

		SR_LOG(INFO, "thread1 loop\r\n");
		osDelay(1000);
	}

	SR_LOG(INFO, "thread1 exit\r\n");
	osThreadExit(); // 退出线程（不加这个，线程返回会出错）

	SR_CT_END(); // 上下文环境结束
}

// 线程
static SR_THD_RET ThreadFunc(void *args)
{
	osThreadId_t thdId = osThreadGetId();
	const char *name = osThreadGetName(thdId);

	SR_GET_CT(); // 获取当前上下文
	SR_CT_BEGIN();			   // 上下文环境起始

	SR_LOG(INFO, "%s enter, id: %d\r\n", name, (uint32_t)thdId);

	while (gShellThreadRun)
	{

		SR_LOG(INFO, "%s loop\r\n", name);
		osDelay(3000);
	}

	SR_LOG(INFO, "%s exit\r\n", name);
	osThreadExit(); // 退出线程（不加这个，线程返回会出错）

	SR_CT_END(); // 上下文环境结束
}

#endif

static uint8_t th1Cb[SR_THD_CB_SIZE] = {0}; // 用户自定义静态线程控制块CB
static uint8_t th1Stack[128] = {0};			// 用户自定义静态栈
static int ThreadExample(int argc, char *argv[])
{
	osThreadId_t th1Id, th2Id, th3Id;

	gShellThreadRun = 1; // 内部测试使用，ctrl+c（将该变量清0）可以停止线程，结束示例

	// 创建线程1，静态方式，使用静态分配的栈和线程控制块CB的空间,传入用户参数
	osThreadAttr_t th1Attr = {0};
	th1Attr.name = "thread1";			  // 线程名称
	th1Attr.stack_size = 128;		  // 线程栈大小
	th1Attr.stack_mem = th1Stack;	  // 静态线程栈空间
	th1Attr.cb_mem = th1Cb;				  // 静态线程控制块CB空间
	th1Attr.cb_size = SR_THD_CB_SIZE;	  // 控制块CB空间大小
	th1Attr.priority = osPriorityNormal1, // 线程优先级

	th1Id = osThreadNew(Thread1Func, &person, &th1Attr);
	SR_LOG(INFO, "th1Id: %ud", (uint32_t)th1Id); // 打印线程Id

	// 创建线程2，动态方式，使用动分配态栈空间，指定栈大小、优先级
	osThreadAttr_t th2Attr = {0};
	th2Attr.name = "thread2";				  // 线程名称
	th2Attr.stack_size = 128;			  // 线程栈大小
	th2Attr.priority = osPriorityNormal1, // 线程优先级

	th2Id = osThreadNew(ThreadFunc, SR_NULL, &th2Attr);
	SR_LOG(INFO, "th2Id: %ud", (uint32_t)th2Id); // 打印线程Id

	// 创建线程3，动态方式，全部使用默认参数
	th3Id = osThreadNew(ThreadFunc, SR_NULL, SR_NULL);
	SR_LOG(INFO, "th3Id: %ud", (uint32_t)th3Id); // 打印线程Id

	return 0;
}
SR_SHELL_CMD_EXPORT(thdExmp, ThreadExample);
