#include "sr_config.h"
#include "sr_stddef.h"
#include "sr_log.h"

//#ifdef SR_USE_SHELL
//#include "sr_shell.h"
//#endif

//#include "sr_osal.h"
#include <string.h>



//原厂头文件
//#include "xxx.h"



/*-----------自动初始化---------*/

static int bsp_init_start(void)
{
    return 0;
}
SR_INIT_BSP_EXPORT(bsp_init_start, "0");

static int bsp_init_end(void)
{
    return 0;
}
SR_INIT_BSP_EXPORT(bsp_init_end, "3.end");

static int component_init_start(void)
{
    return 0;
}
SR_INIT_COMPONENT_EXPORT(component_init_start, "0");

static int component_init_end(void)
{
    return 0;
}
SR_INIT_COMPONENT_EXPORT(component_init_end, "3.end");

static int app_init_start(void)
{
    return 0;
}
SR_INIT_APP_EXPORT(app_init_start, "0");

static int app_init_end(void)
{
    return 0;
}
SR_INIT_APP_EXPORT(app_init_end, "3.end");

// 遍历SR_INIT_BSP_EXPORT声明的初始化函数
static void _BspInit(void)
{
    const init_func_t *fn_ptr;

    for (fn_ptr = &_sr_init_bsp_init_start + 1; fn_ptr < &_sr_init_bsp_init_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
}

// 遍历SR_INIT_COMPONENT_EXPORT声明的初始化函数
static void _ComponentInit(void)
{
    const init_func_t *fn_ptr;

    for (fn_ptr = &_sr_init_component_init_start + 1; fn_ptr < &_sr_init_component_init_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
}

// 遍历SR_INIT_APP_EXPORT声明的初始化函数
static void _AppInit(void)
{
    const init_func_t *fn_ptr;

    for (fn_ptr = &_sr_init_app_init_start + 1; fn_ptr < &_sr_init_app_init_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
}

/*-----------周期调度---------*/
#if  0
/**
 * @brief  空处理,用于定位段入口
 */
static void _nop_process(void)
{
}

// 起始
SR_USED poll_task_t poll_task_start SR_SECTION(".sunrise.poll_task.0") = {
    _nop_process, 0, 0};
// 结束
SR_USED poll_task_t poll_task_end SR_SECTION(".sunrise.poll_task.3.end") = {
    _nop_process, 0, 0};

/**
 * @brief       周期轮询任务处理，通过遍历使用SR_POLL_TASK_EXPORT声明的任务函数，这些函数分布在poll_task_start和poll_task_end之间
 * @param       none
 * @return      none
 */
uint32_t pLastTick = 0;
uint16_t periodMs = 0;
static uint32_t gTickCnt = 0; // 每隔10ms加1

static void _poll_task(void)
{
    poll_task_t *t;
    for (t = &poll_task_start + 1; t < &poll_task_end; t++)
    {

#if 0
			if((gTickCnt - t->lastTick) >= t->periodMs) 
			{
			   pLastTick = t->lastTick;
			   periodMs = t->periodMs;
			    t->lastTick = gTickCnt;  //这句赋值不起作用，猜测由于段定义在flash上，只读
			    t->func();
			}
#else

        if (!(gTickCnt % t->periodMs)) // 对周期取余数为0
        {
            pLastTick = t->lastTick;
            periodMs = t->periodMs;
            t->func();
        }

#endif
    }
}


static void _PollThread(void *arg)
{

    SR_LOG(INFO,"_PollThread Enter...\n");

    while (1)
    {
        osDelay(10);
        gTickCnt++;

        _poll_task();
    }
}
#endif


// BSP初始化(硬件开发者编写)，预留。当平台不支持自动初始化机制时可使用该函数
// 作用和自动初始化机制的_bsp_init()一样
SR_WEAK void SR_UserBspInit(void)
{
}

// Componet初始化（弱定义，应用开发者重写）
// 作用和自动初始化机制的_component_init()一样
SR_WEAK void SR_UserComponentInit(void)
{
}

// APP初始化（弱定义，应用开发者重写）
// 作用和自动初始化机制的_app_init()一样
SR_WEAK void SR_UserAppInit(void)
{
}


// 朝阳主程序入口，弱定义，用户需要重写
SR_WEAK void SR_MainEntry(void *arg)
{
    while (1)
    {
        
    }
}

extern void Bsp_Clock_Config(void);

#include "n32l40x_rcc.h"
#include "misc.h"
// 预初始化
void _MainEntry(void *arg)
{
    //系统初始化
    Bsp_Clock_Config();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);  //优先级分组
  
  
    #ifdef  SR_USE_LOG
        SR_LogUartInit(); // 朝阳调试串口初始化
    #endif
        
    /*遍历自动初始化函数*/
    _BspInit(); // 朝阳内部使用的BSP初始化
    SR_UserBspInit();       // 开放给用户使用的BSP初始化，弱定义，用户重写

    _ComponentInit();       // 朝阳内部使用的组件初始化
    SR_UserComponentInit(); // 开放给用户使用的组件初始化，弱定义，用户重写

    _AppInit();        // 朝阳内部使用的APP初始化
    SR_UserAppInit();  // 开放给用户使用的APP初始化，弱定义，用户重写


    SR_MainEntry(arg); // 主函数入口,弱定义，用户重写
   
}


/* 原厂平台程序入口 */
int main(void)
{

  /* 朝阳SDK启动入口 */
  _MainEntry(0);

  while (1)
  {
    
  }
}


#if 0 // 自动初始化测试函数
static int bsp_init0(void)
{
 SR_LOG(INFO,"bsp_init0 Enter...\n");
 return 0;
}
SR_INIT_BSP_EXPORT(bsp_init0,SR_PRIORITY_0);

static int bsp_init1(void)
{
 SR_LOG(INFO,"bsp_init1 Enter...\n");
 return 0;
}
SR_INIT_BSP_EXPORT(bsp_init1,SR_PRIORITY_1);

static int bsp_init2(void)
{
 SR_LOG(INFO,"bsp_init2 Enter...\n");
 return 0;
}
SR_INIT_BSP_EXPORT(bsp_init2,SR_PRIORITY_2);



static int cmpt_init0(void)
{
 SR_LOG(INFO,"cmpt_init0 Enter...\n");
 return 0;
}
SR_INIT_COMPONENT_EXPORT(cmpt_init0,SR_PRIORITY_0);

static int cmpt_init1(void)
{
 SR_LOG(INFO,"cmpt_init1 Enter...\n");
 return 0;
}
SR_INIT_COMPONENT_EXPORT(cmpt_init1,SR_PRIORITY_1);

static int cmpt_init2(void)
{
 SR_LOG(INFO,"cmpt_init2 Enter...\n");
 return 0;
}
SR_INIT_COMPONENT_EXPORT(cmpt_init2,SR_PRIORITY_2);



static int app_init0(void)
{
 SR_LOG(INFO,"app_init0 Enter...\n");
 return 0;
}
SR_INIT_APP_EXPORT(app_init0,SR_PRIORITY_0);

static int app_init1(void)
{
 SR_LOG(INFO,"app_init1 Enter...\n");
 return 0;
}
SR_INIT_APP_EXPORT(app_init1,SR_PRIORITY_1);

static int app_init2(void)
{
 SR_LOG(INFO,"app_init2 Enter...\n");
 return 0;
}
SR_INIT_APP_EXPORT(app_init2,SR_PRIORITY_2);



#if  0
void poll1(void)
{
  SR_LOG(INFO,"poll1 Enter...gTickCnt(%d) pLastTick(%d) periodMs(%d)\n",gTickCnt,pLastTick,periodMs);

}
SR_POLL_TASK_EXPORT(poll1,200,SR_PRIORITY_0);


void poll2(void)
{
  SR_LOG(INFO,"poll2 Enter...\n");

}
//SR_POLL_TASK_EXPORT(poll2,10,SR_PRIORITY_1);


void poll3(void)
{
  SR_LOG(INFO,"poll3 Enter...\n");

}
//SR_POLL_TASK_EXPORT(poll3,10,SR_PRIORITY_2);
#endif

#endif
