/****************************************************************************** 版权所有: 文件名称: main_mod.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2025-06-09 功能说明: 实时微系统。 其它说明: 修改记录: */ #include #include #include #include "bsp.h" #include "rt.h" #include "app.h" #include "head.h" #include "tmp/bsp_share/bsp_ustimer.h" #include #include #include #include #include #include #include "lvgl_app.h" #include // #define __USE_GNU #define _GNU_SOURCE #include #include // #include #include "bsp_boardcheck.h" int g_l_shm_init = 0xff; static int m_reset; // 看门狗复位变量 struct completion *g_exit_completion_gprs_net_IEC_proc; static int g_exit_flag; bool SystemInit_finish_flag __attribute__((aligned(8))) = false; static int sync_cnt = 0; static pthread_t sync_tid = 0; enum { PTHREAD_MQ = 0, // 消息队列 PTHREAD_C0NSOLE, // 控制台 PTHREAD_PRINTF, // 打印信息 PTHREAD_MAIN_LOOP, // 主循环 PTHREAD_MAIN_APP, PTHREAD_MAIN_DIDO_ADC, PTHREAD_RCD, // 录波 PTHREAD_CAL_SAMPLE, PTHREAD_MAX_NUM }; pthread_t AW_DTU_PTHREAD_TAB[PTHREAD_MAX_NUM]; // 线程表 struct rt_stat g_stat_periodus_5ms; int app_main(void *arg); int di_do_adc(void *arg); #ifdef ENCRYPT_SM2 int gh_sm2_dev_init(void); void gh_sm2_dev_exit(void); #endif int console_init(void); void console_exit(void); int encrypt_test(void); int snprintf_test(void); extern void uart_putchar(int channel, char ch); extern int net_if_test(void); extern int clk_test(void); extern int ac_e2prom_test(void); void watchdog_m_reset(int flag) {} extern int printf_e907_exit(void); int kernel_callback(void); static void main_mod_exit(int signo); // static DECLARE_WAIT_QUEUE_HEAD(wq); static int g_soft_irq_flag = 0; static struct proc_dir_entry *corp_info_proc_entry; int corp_info_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *data) { sprintf(buf, "XXXXXX XXXXXX XXXXXXX XXXXX XXXXXXX Co.,Ltd(XXXXXXXXXX) 2025\r\n"); len = strlen(buf); return len; } pid_t gettid() { return syscall(SYS_gettid); } int mainloop_soft_isr(int irq, void *dev_id) { // int offset=0,tmp,count=1,count2=1,count3=0; // struct timespec ts; // struct rtc_time_t rtcs; struct sched_param sch_par; sch_par.sched_priority = 6; pthread_setschedparam(pthread_self(), SCHED_RR, &sch_par); // 设置当前线程优先级 prctl(PR_SET_NAME, "mainloop_soft_isr_thread"); #ifdef RT_THREAD_DEBUG rt_printf("Thread created successfully: %s,PID: %d LWP: %d\r\n", "mainloop_soft_isr_thread", (int)getpid(), (int)syscall(SYS_gettid)); #endif while (1) { msleep(100); // 延时100ms kernel_callback(); #if 0 if(count++>=40) { //gps_get_time(&ts); //timespec_to_rtc(ts, &rtcs, 0); //tmp=GetUsCounterValue(); //offset=tmp-offset; //rt_printf("%d---%d-%d-%d,%d:%d:%d mainloop=%d,offset=%d\r\n",ts.tv_sec,rtcs.year,rtcs.month,rtcs.day,rtcs.hour,rtcs.min,rtcs.ms,tmp,offset); //offset=tmp; //rt_printf("di=0x%08X\r\n",gpio_get_di()); if(count3==0) gpio_kout_do(0,DO_OUT7); else { if((count3-1)!=DO_OUT4) gpio_kout_do(0,count3-1); } gpio_kout_do(1,count3); rt_printf("count=%d\r\n",count3); ++count3; if(count3>=DO_NUM) count3=0; gpio_kout_do(1,DO_PWM0); count=1; } #endif } } void mainloop_wakeup(void) { // rt_sirq_force(11); } int kernel_callback(void) { static unsigned char init_end_flag = 0; // sunxi 20190416 added // 延时100ms // wait_event_interruptible_timeout(wq,g_soft_irq_flag,HZ/10); g_soft_irq_flag = 0; // sunxi 20190416 added start if (!init_end_flag) { // corp_info_proc_entry = create_proc_entry("corp_info", 0400, NULL); if (corp_info_proc_entry) { // corp_info_proc_entry->read_proc = corp_info_read_proc; // corp_info_proc_entry->write_proc = NULL; } init_end_flag = 1; } // sunxi 20190416 added end // 检查是否需要退出。 if (g_exit_flag) { hzk_exit(); led_exit(); net_debug_exit(); net_debug_s_exit(); if (g_exit_completion_gprs_net_IEC_proc) { ; // wait_for_completion(g_exit_completion_gprs_net_IEC_proc); } printf_e907_exit(); // complete_and_exit(&exit_completion, 1); } return 0; } int cal_thread(void *arg) { uint32_t us0; int ms; struct sched_param sch_par; sch_par.sched_priority = 8; pthread_setschedparam(pthread_self(), SCHED_RR, &sch_par); // 设置当前线程优先级暂定 20200910 while (SystemInit_finish_flag == false) { msleep(10); } uint32_t wdt_id; int rc = watchdog_add_item("cal_thread", &wdt_id, 120); if (rc != 0) { printf("can not add cal_thread task to wdt\r\n"); return -1; } ms = 50; us0 = ustimer_get_origin(); prctl(PR_SET_NAME, "cal_thread"); #ifdef RT_THREAD_DEBUG rt_printf("Thread created successfully: %s, PID: %d LWP: %d\r\n", "cal_thread", (int)getpid(), (int)syscall(SYS_gettid)); #endif while (1) { watchdog_feed(wdt_id); // 100ms执行一次 ms = 50 - (ustimer_get_duration(us0) / USTIMER_US + 500) / 1000; if (ms < 0) { ms = 0; } msleep(ms); us0 = ustimer_get_origin(); // 检查是否需要退出。 if (g_exit_flag) { // complete_and_exit(&exit_completion2, 1); break; } sw_cal_app(); hisory_file_app(); // pw_quality_app(); rec_chnl_zero_drift_handle(); } watchdog_remove_item(wdt_id); return 0; } int main_mod_is_exit(void) { return g_exit_flag; } // sunxi 20190417 added start /* * 该接口在模块装载时调用,防止我们的模块在之前的内核版本中能被轻易使用。函数名称不要定义跟功能一样。 */ int mod_init(void) { char buf[256] = {0x00}; int fd = rt_file_open("/proc/version", O_RDONLY, 0); if (fd < 0) return -1; rt_file_read(fd, buf, 256, NULL); rt_file_close(fd, 0); if (strstr(buf, "root@Ubuntu") && strstr(buf, "-LYQ")) return 0; return -3; } extern void gps_isr(void); int di_do_adc(void *unused) { pid_t tid; cpu_set_t set; struct sched_param sch_par; sch_par.sched_priority = 90; // Set CPU affinity [T536-CPU-3] tid = gettid(); CPU_ZERO(&set); CPU_SET(3, &set); sched_setaffinity(tid, sizeof(cpu_set_t), &set); while (SystemInit_finish_flag == false) { msleep(10); } uint32_t wdt_id; int rc = watchdog_add_item("di_do_adc", &wdt_id, 120); if (rc != 0) { printf("can not add di_do_adc task to wdt\r\n"); return -1; } rt_stat_init(&g_stat_periodus_5ms, "pit_5ms_priod(1us)"); pthread_setschedparam(pthread_self(), SCHED_FIFO, &sch_par); // 设置当前线程优先级 prctl(PR_SET_NAME, "di_do_adc"); #ifdef RT_THREAD_DEBUG rt_printf("Thread created successfully: %s, PID: %d LWP: %d\r\n", "di_do_adc", (int)getpid(), (int)syscall(SYS_gettid)); #endif #ifdef CPU_FUXI // zhl add struct shmem_fd shmem_fd; if (share_mem_init_v2(&shmem_fd) < 0) { dp_err_n_c("--->shmem_init fail !!!"); g_l_shm_init = -1; return -1; } else { g_l_shm_init = 0; dp_info_n_c("--->shmem_init success !!!"); } // 写入毫秒时间戳 struct t_shmdata_timestamp t_rv_msts; #if (0) /* 统一使用gps接口 */ struct timeval tv; gettimeofday(&tv, NULL); uint64_t milliseconds = (uint64_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); #else struct timespec ts_gps; gps_get_time(&ts_gps); uint64_t milliseconds = (uint64_t)((ts_gps.tv_sec + 28800) * 1000 + ts_gps.tv_nsec / 1000000); #endif t_rv_msts.ull_timestamp = milliseconds; shm_packet_write_v2(SHM_ADDR_R_TIMESTAMP, (uint8_t *)&t_rv_msts, sizeof(struct t_shmdata_timestamp)); check_shmdata_change(); // 装置类型us_machine_type (分布式:1,集中式:2) struct t_shmdata_machine_type t_rv_mt = {0}; t_rv_mt.us_machine_type = 1; shm_packet_write_v2(SHM_ADDR_R_MACHINETYPE, (uint8_t *)&t_rv_mt, sizeof(struct t_shmdata_machine_type)); // printf("write SHM_ADDR_R_MACHINETYPE::0x%X -> us_updata: %d, us_op: %d, us_op_bk: %d, us_machine_type: %d, us_crc: 0x%04x\n\n", // SHM_ADDR_R_MACHINETYPE, t_rv_mt.us_updata, t_rv_mt.us_op, t_rv_mt.us_op_bk, t_rv_mt.us_machine_type, t_rv_mt.us_crc); sleep(5); // 注:下发装置类型后,需要等待大于5s,才能读取到R核的ADC初始化标志信息 // ADC初始化标志信息 struct t_shmdata_flag t_rv_adc = {0}; int ret_flag = shm_packet_read_v2(SHM_ADDR_W_FLAG, sizeof(t_rv_adc), (uint8_t *)&t_rv_adc, sizeof(t_rv_adc)); if (t_rv_adc.us_cfg_adc_err == 1 || ret_flag < 0) { dp_err_a_c("adc init err!"); rt_err_set(ERR_CODE_INIT_ADC, 0); } else { dp_info_nt("adc init ok!"); } // printf("ret_flag: %d, read SHM_ADDR_W_FLAG:0x%X -> us_updata: %u, us_op: %u, us_op_bk: %u, us_cfg_adc_err: %u, us_crc: 0x%04x\n\n", // ret_flag, SHM_ADDR_W_FLAG, t_rv_adc.us_updata, t_rv_adc.us_op, t_rv_adc.us_op_bk, t_rv_adc.us_cfg_adc_err, t_rv_adc.us_crc); int l_retrv_di = equ_init_rv_di(); if (0 > l_retrv_di) { rt_err_set(ERR_CODE_INIT_SOFTWARE, 0); } else { l_retrv_di = 0; dp_info_nt("rvdi init ok!"); } // dp_info_nt("l_retrv_di = %d", l_retrv_di); #endif while (1) { static u8 flags = 0; static unsigned long us1 = 0; unsigned long origin_ext = 0; usleep(1000); // bsp_ustimer_delay(1000); // 1ms // 检查是否需要退出。 if (g_exit_flag) { // complete_and_exit(&exit_completion2, 1); break; } origin_ext = bsp_ustimer_get_origin(); if (flags) { rt_stat_in(&g_stat_periodus_5ms, (origin_ext - us1)); } watchdog_feed(wdt_id); // adc_isr(0); if (t_rv_adc.us_cfg_adc_err == 0 && ret_flag > 0) { adc_isr_new(0); freq_get_shm_data(); } // 保护计算 if (prt_flag) { pit_5ms_main(0); prt_flag = false; } #ifdef CPU_FUXI if (0 == l_retrv_di) { if (pRunSet->lb_dint) { get_shm_dintdata(); } get_shm_didata(); } #endif // gps_isr(); // zhl upadte 放在另一个线程跑 us1 = origin_ext; flags = 1; } watchdog_remove_item(wdt_id); return 0; } // 当装置修改app文件夹里面的文件时,需要调用该函数,以sync_cnt数减为0时,调用sync,写入flash,保存数文件。 void start_sync(void) { sync_cnt = 50; // 500ms } static int sync_func(void *arg) { // int ret = 0; uint32_t wdt_id; int rc = watchdog_add_item("sync_func", &wdt_id, 60); if (rc != 0) { printf("can not add sync_func task to wdt\r\n"); return 0; } sync_cnt = 0; prctl(PR_SET_NAME, "sync_func"); #ifdef RT_THREAD_DEBUG rt_printf("Thread created successfully: %s, PID: %d LWP: %d\r\n", "sync_func", (int)getpid(), (int)syscall(SYS_gettid)); #endif while (1) { msleep(10); watchdog_feed(wdt_id); if (main_mod_is_exit()) { break; } if (sync_cnt > 0) { if (--sync_cnt <= 0) { system("sync"); // rt_printf_time("--- sync.\r\n"); } } } watchdog_remove_item(wdt_id); return 0; } int main(void) { // pid_t pid; char *argv[] = {"/sbin/ifconfig", "eth1", "192.168.2.100", NULL}; char *envp[] = {NULL}; // struct task_struct * ts; // struct sched_param sp; int ret; SystemInit_finish_flag = false; // 停止喂狗,让程序复位 m_reset=1 if (m_reset == 1) { rt_printf("watchdog_m_reset(1)...\n"); watchdog_m_reset(1); return 0; } call_usermodehelper("/sbin/ifconfig", argv, envp, UMH_WAIT_PROC); rt_printf("\r\n"); dp_info_nt("%s %s", __DATE__, __TIME__); float f_version = ((VER_NUM >> 12) & 0xff) + ((VER_NUM & 0xfff) * 0.001f); dp_info_nt("版本信息: SV%06.03f %s", f_version, DEVICE_VERSION_INFORMATION); // if(mod_init() < 0) //jack.liu 20200904 认证信息先不使用 // return -1; bsp_init(); // bsp必须先初始化 rt_init(); // 实时系统后初始化 app_init(); // 应用初始化最后初始化 adc_init(); bsp_board_init(); // 建立主函数入口线程 ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_LOOP], NULL, (void *)mainloop_soft_isr, NULL); if (ret) { rt_printf("mainloop_soft_isr thread create failed!\r\n"); rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret)); memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB)); return ret; } // 创建主循环线程 ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP], NULL, (void *)app_main, NULL); if (ret) { rt_printf("app_main thread create failed!\r\n"); rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret)); AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP] = 0; memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB)); return ret; } #if 1 // 创建三遥线程 ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC], NULL, (void *)di_do_adc, NULL); if (ret) { rt_printf("di_do_adc thread create failed!\r\n"); rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret)); AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC] = 0; memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB)); return ret; } // 创建采样数据计算线程 ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_CAL_SAMPLE], NULL, (void *)cal_thread, NULL); if (ret) { rt_printf("cal_thread thread create failed!\r\n"); rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret)); AW_DTU_PTHREAD_TAB[PTHREAD_CAL_SAMPLE] = 0; memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB)); return ret; } ret = pthread_create(&sync_tid, NULL, (void *)sync_func, NULL); if (ret) { rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret)); sync_tid = 0; return ret; } printf("LVGL application start...\n"); // 启动 LVGL 线程(函数声明在gui/lvgl_app.h中) start_lvgl_thread(); // 设置进程名字 prctl(PR_SET_NAME, "AW_DTU_CALL", 0, 0, 0); signal(SIGINT, main_mod_exit); #endif #ifdef RT_THREAD_DEBUG rt_printf("thread create success!\r\n"); #endif scaio_init_data(); // 主线程阻塞 while (1) { bsp_board_check(); rsio_get_runtime(); scaio_save_data(); usleep(1000 * 100); } return 0; } int net_debug_exit(void); int net_maintain_exit(void); int net_104_exit(void); static void main_mod_exit(int signo) { if (corp_info_proc_entry) { ; // remove_proc_entry("corp_info", NULL); } // if (m_reset == 1) { watchdog_m_reset(0); rt_printf("watchdog_m_reset(0)...\n"); return; } // gh_sm2_dev_exit(); // console_exit(); // watchdog_unregister_all(); // rt_sirq_unregister(RT_SOFT_IRQ_MAINLOOP); net_maintain_exit(); net_104_exit(); net_104link_exit(); g_exit_flag = 1; // wait_for_completion(&exit_completion); // wait_for_completion(&exit_completion2); app_exit(); rt_exit(); bsp_exit(); // sunxi 20190418 goose_app_exit(); open_inet_port(); rt_printf("main_mod_exit\n"); }