/**************************************************************************//**
 * @item     CosyOS-III Kernel
 * @file     os_stack.c
 * @brief    main stack and task stack check
 * @author   迟凯峰
 * @version  v3.0.0
 * @date     2026.07.21
 ******************************************************************************/

#include "os_stack.h"

#if (SYSCFG_DEBUGGING == __ENABLED__)

#include <string.h>

#if   defined ( __C51__ )
#define STACK_TYPE  1 // 满增栈
static s_u8_t const stack_data[ 8] = {"CosyOS51"};

#elif defined ( __C251__ )
#define STACK_TYPE  1 // 满增栈
static s_u8_t const stack_data[16] = {"CosyOS for 80251"};

#else
#define STACK_TYPE  2 // 满减栈
static s_u8_t const stack_data[32] = {"CosyOS is an RTOS come on China."};
#endif

/**
 \brief      栈检查初始化
 \param[in]  addr      栈的初始安装指针
 \param[in]  size      栈的大小
 \return     无
 */
void s_stack_check_init(STACK_ADDR_T addr, STACK_SIZE_T size)
{
	STACK_SIZE_T i;
	STACK_SIZE_T c = size / sizeof(stack_data);
	
	#if   ( STACK_TYPE == 1 )
	STACK_ADDR_T p = addr + size - sizeof(stack_data);
	
	#elif ( STACK_TYPE == 2 )
	STACK_ADDR_T p = addr - size;
	#endif
	
	for(i = 0; i < c; i++){
		memcpy(p, stack_data, sizeof(stack_data));
		
		#if   ( STACK_TYPE == 1 )
		p -= sizeof(stack_data);
		
		#elif ( STACK_TYPE == 2 )
		p += sizeof(stack_data);
		#endif
	}
}

/**
 \brief      栈检查
 \param[in]  addr      栈的初始安装指针
 \param[in]  size      栈的大小
 \return     栈用量
 */
STACK_SIZE_T s_stack_check(STACK_ADDR_T addr, STACK_SIZE_T size)
{
	STACK_SIZE_T i;
	STACK_SIZE_T c = size / sizeof(stack_data);
	
	#if   ( STACK_TYPE == 1 )
	STACK_ADDR_T p = addr + size - sizeof(stack_data);
	
	#elif ( STACK_TYPE == 2 )
	STACK_ADDR_T p = addr - size;
	#endif
	
	for(i = 0; i < c; i++){
		if(!memcmp(p, stack_data, sizeof(stack_data))){
			
			#if   ( STACK_TYPE == 1 )
			p -= sizeof(stack_data);
			
			#elif ( STACK_TYPE == 2 )
			p += sizeof(stack_data);
			#endif
		}
		else{
			break;
		}
	}
	#if   ( STACK_TYPE == 1 )
	return (STACK_SIZE_T)(p - addr) + sizeof(stack_data);
	
	#elif ( STACK_TYPE == 2 )
	return (STACK_SIZE_T)(addr - p);
	#endif
}

#endif
