/***************************************************************************** 函 数 名 : hi6559_om_log_save 功能描述 : 记录hi6559的异常信息 输入参数 : @hi6559_om_log_flag Log类型 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_om_log_save(pmu_om_log_e hi6559_om_log_flag) { switch(hi6559_om_log_flag) { case PMU_OM_LOG_START: print2file(PMU_OM_LOG, "system start....\n"); break; case PMU_OM_LOG_EXC: break; default: break; } return; }
/***************************************************************************** 函 数 名 : hi6559_uvp_die_handle 功能描述 : 欠压2.5V处理函数,电压低于PMU所能容忍的阈值时所要进行的处理(按道 理本函数调用到,系统就会挂) 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 调用函数 : 被调函数 : bbstar中断处理任务 *****************************************************************************/ void hi6559_uvp_die_handle(void* para) { para = para; pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET); /*记录om log */ /* hi6559_om_log_save(PMU_OM_LOG_EXC); */ print2file(PMU_OM_LOG, "pmu_hi6559:vsys under 2.5v !\n"); /* 清除非下电reg */ bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET)); pmic_print_error("\n**********hi6559_uvp_2p5_isr**********\n"); return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_ovp_handle 功能描述 : 过压处理函数 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_ovp_handle(void* para) { para = para; pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_OVER_6P0_OFFSET); /* 记录om log */ /* hi6559_om_log_save(PMU_OM_LOG_EXC); */ print2file(PMU_OM_LOG,"pmu_hi6559:vsys over 6.0v last time!\n"); /* 清除非下电reg */ bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_OVER_6P0_OFFSET)); pmic_print_error("\n**********hi6559_ovp_isr**********\n"); return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_otp_handle 功能描述 : 过温处理函数 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_otp_handle(void* para) { s32 i = 0; para = para; pmic_print_error("hi6559:temperature overflow (>125℃)!\n"); /*由nv控制过温是否关闭*/ pmu_hi6559_om_data[0] |= (0x01 << HI6559_OTMP_125_OFFSET); /*根据nv配置,决定是否关闭非核心电源,后续增加产品形态相关特殊处理*/ if(pmu_exc_pro.ulOtpCurIsOff) { for(i = PMIC_HI6559_VOLT_MIN; i < PMIC_HI6559_VOLT_MAX; i++) { if(pmu_exc_pro.VoltProConfig[i].VoltOtpIsOff) { pmic_print_error("hi6559:volt id %d will be closed !\n",i); bsp_hi6559_volt_disable(i); } } } if(pmu_exc_pro.ulOtpIsRst) { pmic_print_error("hi6559:system will be restart!\n"); system_error(DRV_ERRNO_PMU_OVER_TEMP, PMU_STATE_OVER_TEMP, 0, NULL, 0); } /* 记录om log */ /* hi6559_om_log_save(PMU_OM_LOG_EXC); */ print2file(PMU_OM_LOG, "pmu_hi6559:temperature overflow (>125℃)!\n"); /*clear np int */ bsp_hi6559_reg_write(HI6559_NP_SCP_RECORD1_OFFSET, (0x01 << HI6559_OTMP_125_OFFSET)); pmic_print_error("\n**********hi6559_otp_isr**********\n"); return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_uvp_warning_handle 功能描述 : 欠压处理函数2.85/3.0,电压低于设定的告警阈值,所要进行的处理 输入参数 : void 输出参数 : 无 返 回 值 : void 调用函数 : 被调函数 : bbstar中断处理任务 *****************************************************************************/ void hi6559_uvp_warning_handle(void* para) { para = para; pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET); /* 记录om log */ /* hi6559_om_log_save(PMU_OM_LOG_EXC); */ print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.85/3.0v !\n"); /* 根据nv配置确定是否重启 */ if(pmu_exc_pro.ulUvpIsRst) { pmic_print_error("hi6559:system will be restart!\n"); system_error(DRV_ERRNO_PMU_UNDEF_VOL, PMU_STATE_UNDER_VOL, 0, NULL, 0); } /*清除非下电reg,write 1 clear*/ bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET)); pmic_print_error("**********hi6559_uvp_2p85_isr**********\n"); return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_ocp_scp_handle 功能描述 : 过流处理函数 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_ocp_scp_handle(void* para) { u32 volt_need_off = 0; u32 *pmu_ocp_flag = (u32 *)SHM_PMU_OCP_INFO_ADDR; /* 过流,需要关闭的过流源 */ s32 ret = ERROR; u8 a_ucRecordReg[HI6559_NP_OCP_SCP_REG_NUM] = {0}; /* 过流寄存器读取值 */ u8 i = 0; u8 j = 0; /*lint --e{690,831}*/ para = para; pmic_print_error("******* hi6559_current_overflow! **********\n"); for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++) { bsp_hi6559_reg_read((HI6559_NP_SCP_RECORD1_OFFSET + i), &a_ucRecordReg[i]); /* 在中断处理任务中,是否需要加锁? */ pmu_hi6559_om_data[i + 3] |= a_ucRecordReg[i]; } /* 检查所有SCP_RECORD和OCP_RECORD中的状态, 根据nv配置进行安全处理 */ /* BUCK短路检查,0x18寄存器 */ for (j = 0; j < HI6559_NP_SCP_RECORD1_CONT_NUM; j++) { if (a_ucRecordReg[0] & (u8)((u32)0x1 << reg_np_scp_record1_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s short !\n", reg_np_scp_record1_cont[j].cont); } } /* BUCK过流检查,0x19寄存器 */ for (j = 0; j < HI6559_NP_OCP_RECORD1_CONT_NUM; j++) { if (a_ucRecordReg[1] & (u8)((u32)0x1 << reg_np_ocp_record1_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record1_cont[j].cont); } } /* LDO1~8过流检查,0x1A寄存器 */ for (j = 0; j < HI6559_NP_OCP_RECORD2_CONT_NUM; j++) { if (a_ucRecordReg[2] & (u8)((u32)0x1 << reg_np_ocp_record2_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record2_cont[j].cont); } } /* ldo9~14过流,寄存器0x1B */ for (j = 0; j < HI6559_NP_OCP_RECORD3_CONT_NUM; j++) { if (a_ucRecordReg[3] & (u8)((u32)0x1 << j)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j)); *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j)); print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO09 + j - 1); } } /* ldo22~24过流,寄存器0x1C */ for(j = 0; j < HI6559_NP_OCP_RECORD4_CONT_NUM; j++) { if (a_ucRecordReg[4] & (u8)((u32)0x1 << (j + 5))) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j)); *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j)); print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO22 + j + 6); } } /* lvs7过流,寄存器0x1D */ if(a_ucRecordReg[5] & (u8)((u32)0x1 << HI6559_LVS07_BIT_OFFSET)) { volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS07); *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS07); print2file(PMU_OM_LOG,"pmu_hi6559:LVS7 overflow !\n"); } /* lvs9过流,寄存器0x1E */ if(a_ucRecordReg[6] & (u8)((u32)0x1 << HI6559_LVS09_BIT_OFFSET)) { volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS09); *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS09); print2file(PMU_OM_LOG,"pmu_hi6559:LVS09 overflow !\n"); } /* 异常信息发给C核 */ if(volt_need_off) { ret = bsp_icc_send(ICC_CPU_MODEM, PA_RF_ICC_CHN_ID, (u8*)&volt_need_off, sizeof(u32)); if(sizeof(u32) != (u32)ret) { pmic_print_error("bsp_icc_send failed, ret = %d!\n", ret); } } /* 根据NV值确认是否需要关闭过流的电源 */ for(j = PMIC_HI6559_VOLT_MIN; j <= PMIC_HI6559_VOLT_MAX; j++) { if(pmu_exc_pro.ulOcpIsOff) { if(volt_need_off & ((u32)0x1 << j)) { pmic_print_error("hi6559:volt id %d overflow !\n", j); /* 需要关闭过流的电压源,则关闭 */ if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsOff) { pmic_print_error("hi6559:volt id %d will be closed !\n", j); bsp_hi6559_volt_disable(j); } /* 过流需要重启,则重启 */ if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsRst) { pmic_print_error("hi6559:system will be restart!\n"); system_error(DRV_ERRNO_PMU_OVER_CUR, PMU_STATE_OVER_CUR, j, (char *)&volt_need_off, (u32)sizeof(volt_need_off)); } } } else { if(volt_need_off & ((u32)0x1 << j)) { pmic_print_error("hi6559:volt id %d overflow !\n", j); } } } /*清除非下电中断状态寄存器*/ for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++) { bsp_hi6559_reg_write((HI6559_NP_SCP_RECORD1_OFFSET + i), a_ucRecordReg[i]); /*lint !e661*/ } return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_om_wk_handler 功能描述 : 将非下电状态记录寄存器写入log文件,并判断此次启动是否由PMU引起的重启 输入参数 : 无 输出参数 : 无 返 回 值 : 无 备注说明 : 无 *****************************************************************************/ void hi6559_om_wk_handler(void) { s32 j = 0; /* 保存非下电寄存器值 */ for(j = 0; j < HI6559_NP_RECORD_REG_NUM; j++) { print2file(PMU_OM_LOG,"pmu_hi6559:np%d:%x!\n", j + 1, pmu_hi6559_om_boot[j]); } /* 欠压2.5V */ if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET ) ) { print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.5v last time!\n"); } /* 欠压2.85/3.0V */ if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET ) ) { print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.85/3.0v last time!\n"); } /* 过压6.0V */ if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_OVER_6P0_OFFSET )) { print2file(PMU_OM_LOG,"pmu_hi6559:vsys over 6.0v last time!\n"); } /* 过温125度 */ if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_OTMP_125_OFFSET)) { print2file(PMU_OM_LOG,"pmu_hi6559:temperature over 125℃ last time!\n"); } /* 过温150度 */ if(pmu_hi6559_om_boot[1] & (0x01 << HI6559_OTMP_150_OFFSET ) ) { print2file(PMU_OM_LOG,"pmu_hi6559:temperature over 150℃ last time!\n"); } /* buck短路,寄存器0x18 */ for (j = 0; j < HI6559_NP_SCP_RECORD1_CONT_NUM; j++) { if (pmu_hi6559_om_boot[3] & (u8)((u32)0x1 << reg_np_scp_record1_cont[j].bit_ofs)) { print2file(PMU_OM_LOG,"pmu_hi6559: %s short last time!\n", reg_np_scp_record1_cont[j].cont); } } /* buck过流,寄存器0x19 */ for (j = 0; j < HI6559_NP_OCP_RECORD1_CONT_NUM; j++) { if (pmu_hi6559_om_boot[4] & (u8)((u32)0x1 << reg_np_ocp_record1_cont[j].bit_ofs)) { print2file(PMU_OM_LOG,"pmu_hi6559: %s overflow last time!\n", reg_np_ocp_record1_cont[j].cont); } } /* ldo1~8过流,寄存器0x1A */ for (j = 0; j < HI6559_NP_OCP_RECORD2_CONT_NUM; j++) { if (pmu_hi6559_om_boot[5] & (u8)((u32)0x1 << reg_np_ocp_record2_cont[j].bit_ofs)) { print2file(PMU_OM_LOG,"pmu_hi6559: %s overflow last time!\n", reg_np_ocp_record2_cont[j].cont); } } /* ldo9~14过流,寄存器0x1B */ for (j = 0; j < HI6559_NP_OCP_RECORD3_CONT_NUM; j++) { if (pmu_hi6559_om_boot[6] & (u8)((u32)0x1 << j)) { print2file(PMU_OM_LOG,"pmu_hi6559: LDO%d overflow last time!\n", j + 9); } } /* ldo22~24过流,寄存器0x1C */ for(j = 0; j < HI6559_NP_OCP_RECORD4_CONT_NUM; j++) { if (pmu_hi6559_om_boot[7] & (u8)((u32)0x1 << (j + 5))) { print2file(PMU_OM_LOG,"pmu_hi6559: LDO%d overflow last time!\n", j + 22); } } /* lvs7过流,寄存器0x1D */ if (pmu_hi6559_om_boot[8] & (u8)((u32)0x1 << HI6559_LVS07_BIT_OFFSET)) { print2file(PMU_OM_LOG,"pmu_hi6559: LVS7 overflow last time!\n"); } /* lvs9过流,寄存器0x1E */ if (pmu_hi6559_om_boot[9] & (u8)((u32)0x1 << HI6559_LVS09_BIT_OFFSET)) { print2file(PMU_OM_LOG,"pmu_hi6559: LVS9 overflow last time!\n"); } return; }
int main(int argc, char *argv[]){ if (argc != 3) { printf("USAGE: %s <nx> <nthreads>\n", argv[0]); exit(1); } double start_time = omp_get_wtime(); const int nx = atoi(argv[1]); const int nthreads = atoi(argv[2]); const double pi = acos(0)*2; const double delta = 0.25; const int n = 2*nx*nx; const double dx = pi/nx; double v_sum = 0; int t, i, j; int chunk; chunk = 128/4; string file = argv[0]; file.append(argv[1]); file.append("_output"); double ** T_c = new_Temperature(nx, dx); double ** T_p = new_Temperature(nx, dx); omp_set_num_threads(nthreads); #pragma omp parallel default(none) shared(T_c, T_p) private(i, j, t) for(t = 0; t < n; t++){ #pragma omp for nowait for(i = 0; i < nx; i++){ for(j = 1; j < nx-1; j++){ if(i == 0){ T_c[i][j] = delta*(T_p[nx-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]); } else if(i == nx -1){ T_c[i][j] = delta*(T_p[i-1][j] +T_p[0][j]+T_p[i][j-1]+T_p[i][j+1]); } else{ T_c[i][j] = delta*(T_p[i-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]); } } } #pragma omp barrier #pragma omp for nowait for(int i = 0; i < nx; i ++){ for(int j = 0; j < nx; j++){ T_p[i][j] = T_c[i][j]; } } } double stop_time = omp_get_wtime(); print2file(T_c, nx, file); for(int i = 0; i < nx; i ++){ for(int j = 0; j < nx; j++){ v_sum += T_c[i][j]; } } for(int i = 0; i < nx; i ++){ delete [] T_c[i]; delete [] T_p[i]; } delete [] T_c; delete [] T_p; cout << "Volume average for "<<nx<<" x "<<nx<<" "<<v_sum/nx/nx<<endl; cout << "Running time is: " << stop_time - start_time << "s" << endl; return 0; }
int main(int argc, char *argv[]){ if (argc != 2) { printf("USAGE: %s <nx>\n", argv[0]); exit(1); } const int nx = atoi(argv[1]); const double pi = acos(0)*2; const double delta = 0.25; const int n = 2*nx*nx; const double dx = pi/nx; double ** T_c; double ** T_p; string file = argv[0]; file.append(argv[1]); file.append("_output"); int tag = 123; int n_tsk, rank; double time_start = MPI_Wtime(); MPI_Status status; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &n_tsk); MPI_Comm_rank(MPI_COMM_WORLD, &rank); int interval = nx/n_tsk; /**** Create send and receive ***/ double send_bound1[nx]; double send_bound2[nx]; double receive_bound1[nx]; double receive_bound2[nx]; /****** Create new segment ******/ T_c = new double* [interval + 2]; T_p = new double* [interval + 2]; for(int i = 0; i < interval + 2; i++){ T_c[i] = new double[nx]; T_p[i] = new double[nx]; } /****** Initialize array ********/ for(int i = 0; i < interval + 2; i++){ for(int j = 1; j < nx-1; j ++){ T_c[i][j] = 0; T_p[i][j] = 0; } } for(int i = 0; i < interval + 2; i++){ T_p[i][0] = pow(cos(dx*(rank*interval-1+i)), 2); T_p[i][nx-1] = pow(sin(dx*(rank*interval-1+i)), 2); T_c[i][0] = T_p[i][0]; T_c[i][nx-1] = T_p[i][nx-1]; } for(int t = 0; t < n; t ++){ for(int i = 1; i < interval+1; i++){ for(int j = 1; j < nx-1; j++){ T_c[i][j] = delta*(T_p[i-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]); } } for(int i = 1; i < interval+1; i++){ for(int j = 1; j < nx-1; j++){ T_p[i][j] = T_c[i][j]; } } /*** Initial message ******/ for(int i = 0; i < nx; i++){ send_bound1[i] = T_c[1][i]; send_bound2[i] = T_c[interval][i]; } if (rank != 0){ MPI_Recv(&receive_bound2, nx, MPI_DOUBLE, rank-1, tag+1, MPI_COMM_WORLD, &status); } MPI_Send(&send_bound2, nx, MPI_DOUBLE, (rank+1)%n_tsk, tag+1, MPI_COMM_WORLD); if (rank == 0){ MPI_Recv(&receive_bound2, nx, MPI_DOUBLE, n_tsk-1, tag+1, MPI_COMM_WORLD, &status); } if (rank != n_tsk -1){ MPI_Recv(&receive_bound1, nx, MPI_DOUBLE, rank+1, tag, MPI_COMM_WORLD, &status); } MPI_Send(&send_bound1, nx, MPI_DOUBLE, ((rank-1)%n_tsk+n_tsk)%n_tsk, tag, MPI_COMM_WORLD); if (rank == n_tsk-1){ MPI_Recv(&receive_bound1, nx, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &status); } for(int i = 0; i < nx; i++){ T_p[0][i] = receive_bound2[i]; T_p[interval+1][i] = receive_bound1[i]; } } if(rank != 0){ double send_T[nx*interval]; for(int i = 0; i < interval; i++){ for(int j = 0; j < nx; j ++){ send_T[i*nx+j] = T_c[i+1][j]; } } MPI_Send(&send_T, nx*interval, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD); } else{ double receive_T[nx*interval]; double ** T = new double*[nx]; double v_sum = 0; for(int i = 0; i < nx; i++){ T[i] = new double [nx]; } for(int i = 1; i < interval + 1; i++){ for(int j = 0; j < nx; j ++){ T[i-1][j] = T_c[i][j]; v_sum += T_c[i][j]; } } for(int i = 1; i < n_tsk; i++){ MPI_Recv(&receive_T, nx*interval, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &status); for(int j = 0; j < interval; j++){ for(int k = 0; k < nx; k ++){ T[i*interval+j][k] = receive_T[j*nx+k]; v_sum += receive_T[j*nx+k]; } } } double time_end = MPI_Wtime(); cout << "Volume average for "<<nx<<" x "<<nx<<" "<<v_sum/nx/nx<<endl; cout <<"Running time is "<<time_end-time_start<< "s" <<endl; print2file(T, nx, file); for(int i = 0; i < nx; i++){ delete [] T[i]; } delete [] T; } for(int i = 0; i < interval + 2; i++){ delete [] T_c[i]; delete [] T_p[i]; } delete [] T_c; delete [] T_p; MPI_Finalize(); }