#include "app_config.h" #include "asm/includes.h" #include "system/init.h" #include "system/task.h" #include "app_core.h" #include "irq.h" #include "version.h" #include "jiffies.h" #include "system/timer.h" #include long sysconf(int name) { if (name == _SC_NPROCESSORS_CONF) { return CPU_CORE_NUM; } else { printf("[%s, %d][%d]is not supported yet\n", __FUNCTION__, __LINE__, name); } return -1; } int errno; __attribute__((used)) int *__errno(void) { return &errno; } volatile unsigned long jiffies = 10; #if 0 volatile unsigned long hi_jiffies = 10; /* * 测试cpu0,cpu1 stack用多少空间 * 使用list_for_stack_info查看stack使用空间前,先在main函数最先调用init_for_stack_info初始化stack */ extern unsigned int stack_info_begin[]; extern unsigned int _stack_cpu0[]; extern unsigned int _stack1_cpu0[]; extern unsigned int _stack_cpu1[]; extern unsigned int _stack1_cpu1[]; extern unsigned int stack_info_end[]; #define STACK_MAG 0x87654321 void init_for_stack_info(void) { unsigned int *buf; for (buf = stack_info_begin; buf < stack_info_end; buf++) { *buf = STACK_MAG; } } void list_for_stack_info(void) { unsigned int *buf; unsigned int all_size; unsigned int use_size; printf("\r\n\r\n----------------------------------------------------------------------\r\n\r\n"); for (buf = stack_info_begin; buf < _stack_cpu0; buf++) { if (*buf != STACK_MAG) { all_size = (unsigned int)(_stack_cpu0 - stack_info_begin) * 4; use_size = (unsigned int)(_stack_cpu0 - buf) * 4; printf("stack_cpu0 addr : 0x%08x , all size : %08d, used : %08d \r\n", (u32)stack_info_begin, all_size, use_size); break; } } for (buf = _stack_cpu0; buf < _stack1_cpu0; buf++) { if (*buf != STACK_MAG) { all_size = (unsigned int)(_stack1_cpu0 - _stack_cpu0) * 4; use_size = (unsigned int)(_stack1_cpu0 - buf) * 4; printf("stack1_cpu0 addr : 0x%08x , all size : %08d, used : %08d \r\n", (u32)_stack_cpu0, all_size, use_size); break; } } for (buf = _stack1_cpu0; buf < _stack_cpu1; buf++) { if (*buf != STACK_MAG) { all_size = (unsigned int)(_stack_cpu1 - _stack1_cpu0) * 4; use_size = (unsigned int)(_stack_cpu1 - buf) * 4; printf("stack_cpu1 addr : 0x%08x , all size : %08d, used : %08d \r\n", (u32)_stack1_cpu0, all_size, use_size); break; } } for (buf = _stack_cpu1; buf < stack_info_end; buf++) { if (*buf != STACK_MAG) { all_size = (unsigned int)(stack_info_end - _stack_cpu1) * 4; use_size = (unsigned int)(stack_info_end - buf) * 4; printf("stack1_cpu1 addr : 0x%08x , all size : %08d, used : %08d \r\n", (u32)_stack_cpu1, all_size, use_size); break; } } printf("----------------------------------------------------------------------\r\n\r\n"); } #endif extern volatile char cpu1_run_flag; #if CPU_CORE_NUM == 1 SEC_USED(.volatile_ram_code) #endif void cpu1_main(void) { cpu1_run_flag = 1;//标记CPU1启动 __local_irq_disable(); interrupt_init(); debug_init(); #if CPU_CORE_NUM > 1 os_start(); #else puts("\r\n\n cpu1_run... \r\n\n"); #endif __local_irq_enable(); #if defined CONFIG_UCOS_ENABLE || (CPU_CORE_NUM == 1) //在这句话之后 不可用操作系统接口,printf/puts等打印接口,并且需要替换单核专用的system库, while (1) { __asm__ volatile("idle"); } #endif } void cpu_assert_debug() { #ifdef CONFIG_DEBUG_ENABLE log_flush(); local_irq_disable(); #endif /*while (1);*/ cpu_reset(); } #ifdef RTOS_STACK_CHECK_ENABLE static void rtos_stack_check_func(void *p) { #if 0 char *pWriteBuffer = malloc(2048); if (!pWriteBuffer) { return; } extern void vTaskList(char *pcWriteBuffer); vTaskList(pWriteBuffer); printf(" \n\ntask_name task_state priority stack task_num\n%s\n", pWriteBuffer); free(pWriteBuffer); #else extern void get_task_state(void *parm); get_task_state(NULL); //1分钟以内调用一次才准确 #endif dump_cpu_irq_usage(); /* dump_os_sw_cnt(); */ malloc_stats(); #if configCPU_USAGE_CALCULATE extern unsigned char ucGetCpuUsage(unsigned char cpuid); printf("cpu0 use: %d%%, cpu1 use: %d%%\n", ucGetCpuUsage(0), ucGetCpuUsage(1)); #endif /*cpu_effic_calc();*/ } #endif #ifdef MEM_LEAK_CHECK_ENABLE #include "mem_leak_test.h" static void malloc_debug_dump(void *p) { malloc_stats(); malloc_debug_show(); malloc_dump(); } #endif extern void setup_arch(void); extern int sys_timer_init(void); extern void app_main(void); extern void sdfile_ext_mount_init(void); void __attribute__((weak)) board_init() {} void __attribute__((weak)) board_early_init() {} static void app_task_handler(void *p) { sys_timer_init(); sys_timer_task_init(); #ifdef RTOS_STACK_CHECK_ENABLE sys_timer_add(NULL, rtos_stack_check_func, 60 * 1000); #endif #ifdef MEM_LEAK_CHECK_ENABLE malloc_debug_start(); sys_timer_add(NULL, malloc_debug_dump, 60 * 1000); #endif board_early_init(); __do_initcall(early_initcall); #ifdef CONFIG_SDFILE_EXT_ENABLE sdfile_ext_mount_init(); #endif __do_initcall(platform_initcall); board_init(); #ifdef RF_FCC_TEST_ENABLE u8 rf_fcc_test_init(void); if (rf_fcc_test_init()) { #ifndef RF_FCC_IN_NORNAL_WORK while (1) { os_time_dly(10); } #endif } #endif __do_initcall(initcall); __do_initcall(module_initcall); app_core_init(); __do_initcall(late_initcall); app_main(); #ifdef CONFIG_FINSH_ENABLE extern int finsh_system_init(void); finsh_system_init(); #endif int res; int msg[32]; while (1) { res = os_task_pend("taskq", msg, ARRAY_SIZE(msg)); if (res != OS_TASKQ) { continue; } app_core_msg_handler(msg); } } #if 0 /*__attribute__((always_inline))*/ //SEC_USED(.volatile_ram_code) void early_putchar(char a) { if (a == '\n') { JL_UART2->CON0 |= BIT(13); JL_UART2->BUF = '\r'; __asm_csync(); while ((JL_UART2->CON0 & BIT(15)) == 0); } JL_UART2->CON0 |= BIT(13); JL_UART2->BUF = a; __asm_csync(); while ((JL_UART2->CON0 & BIT(15)) == 0); } void early_puts(char *s) { do { early_putchar(*s); } while (*(++s)); } #endif int main() { //init_for_stack_info(); /* early_puts("WL8X SDK RUN !!!\r\n"); */ __local_irq_disable(); setup_arch(); #if CPU_CORE_NUM == 1 EnableOtherCpu(); //cpu1_run_flag = 0; //如果运行在SFC模式下,不希望写FLASH的时候会挂起CPU1,则打开这句话,但是需要保证cpu1_main调用到的所有函数全部放到内部ram或者sdram,防止写flash过程中引起死机 #endif os_init(); task_create(app_task_handler, NULL, "app_core"); #if CPU_CORE_NUM == 1 //本来改 prvIdleTask __local_irq_enable(); #endif os_start(); #if CPU_CORE_NUM > 1 __local_irq_enable(); #endif #if defined CONFIG_UCOS_ENABLE while (1) { __asm__ volatile("idle"); } #endif return 0; } int eSystemConfirmStopStatus(void) { /* 系统进入在未来时间里,无任务超时唤醒,可根据用户选择系统停止,或者系统定时唤醒(100ms) */ //1:Endless Sleep //0:100 ms wakeup return 0; } #define CONFIG_BT_ENABLE_SPINLOCK 1 #if CONFIG_BT_ENABLE_SPINLOCK && CPU_CORE_NUM > 1 static volatile u32 bt_lock_cnt[CPU_CORE_NUM] SEC_USED(.volatile_ram) = {0}; static spinlock_t bt_lock SEC_USED(.volatile_ram) = {0}; __attribute__((always_inline)) void local_irq_disable(void) { __local_irq_disable(); if (bt_lock_cnt[current_cpu_id()]++ == 0) { arch_spin_lock(&bt_lock); } } __attribute__((always_inline)) void local_irq_enable(void) { if (--bt_lock_cnt[current_cpu_id()] == 0) { arch_spin_unlock(&bt_lock); } __local_irq_enable(); } #else __attribute__((always_inline)) void local_irq_disable(void) { sys_local_irq_disable(); } __attribute__((always_inline)) void local_irq_enable(void) { sys_local_irq_enable(); } #endif #ifdef CONFIG_IPMASK_ENABLE //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) void __local_irq_disable(void) { __builtin_pi32v2_cli(); q32DSP(current_cpu_id())->IPMASK = 7;//把中断优先级大于等于7的中断设定为不可屏蔽中断 irq_lock_cnt[current_cpu_id()]++; __asm_csync(); __builtin_pi32v2_sti(); } //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) void __local_irq_enable(void) { if (--irq_lock_cnt[current_cpu_id()] == 0) { __builtin_pi32v2_cli(); q32DSP(current_cpu_id())->IPMASK = 0; __asm_csync(); __builtin_pi32v2_sti(); } } //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) int cpu_irq_disabled(void) { int flag, flag2; __asm__ volatile("%0 = icfg" : "=r"(flag)); int first = ((flag & 0x300) != 0x300) || (q32DSP(current_cpu_id())->IPMASK == 7);//不可屏蔽中断 //只读一遍有可能出现实际上没关中断但又条件成立的情况,需要再读一次确保正确,读取前使用ssync也没效果,原因未知 __asm__ volatile("%0 = icfg" : "=r"(flag2)); int second = ((flag2 & 0x300) != 0x300) || (q32DSP(current_cpu_id())->IPMASK == 7);//不可屏蔽中断 return (first && second); } #else //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) void __local_irq_disable(void) { __builtin_pi32v2_cli(); irq_lock_cnt[current_cpu_id()]++; __asm_csync(); } //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) void __local_irq_enable(void) { if (--irq_lock_cnt[current_cpu_id()] == 0) { __asm_csync(); __builtin_pi32v2_sti(); } } //外部用到宏控制的函数, 库里面不能够内联 SEC_USED(.volatile_ram_code) __attribute__((noinline)) int cpu_irq_disabled(void) { int flag, flag2; __asm__ volatile("%0 = icfg" : "=r"(flag)); int first = ((flag & 0x300) != 0x300); //只读一遍有可能出现实际上没关中断但又条件成立的情况,需要再读一次确保正确,读取前使用ssync也没效果,原因未知 __asm__ volatile("%0 = icfg" : "=r"(flag2)); int second = ((flag2 & 0x300) != 0x300); return (first && second); } #endif __attribute__((always_inline)) int __local_irq_lock_cnt(void) { __asm_csync(); return irq_lock_cnt[current_cpu_id()]; } __attribute__((always_inline)) int cpu_in_irq(void) { int flag; __asm__ volatile("%0 = icfg" : "=r"(flag)); return flag & 0xff; } __attribute__((always_inline)) void sys_local_irq_disable(void) { __local_irq_disable(); if (cpu_lock_cnt[current_cpu_id()]++ == 0) { asm volatile("lockset;"); } __asm_csync(); } __attribute__((always_inline)) void sys_local_irq_enable(void) { __asm_csync(); if (--cpu_lock_cnt[current_cpu_id()] == 0) { asm volatile("lockclr;"); } __local_irq_enable(); } // just fix build&link #if !defined CONFIG_NET_ENABLE && !defined CONFIG_BT_ENABLE __attribute__((weak)) void wf_set_phcom_cnt(u32 phcom_cnt) { } #endif