/* * Brief: Handle all chassis function in this file. Such as: Fan control, update power_good status, update chassis health status. * Author: Jimbo_Zhang@outlook.com * Date: 2019-9-18 */ #include #include #include #include #include #include #include #include #include #include #include #include "main.h" #include "ChassisTimerTask.h" #include "ChassisDevice.h" #include "com_IPMI_Chassis.h" #include "SensorMonitor.h" #include "time.h" #include "com_IPMI_App.h" #include "hal_interface_api.h" int gFd_ChassisPwrHndlrQue; void *ChassisTimerTask(void* pArg) { MsgPkt_T MsgPkt; uint32_t preChassisSeconds; uint32_t preFanSeconds; uint32_t preIdentifySeconds = 0; uint8_t IdentifyTickCnt = 0; prctl(PR_SET_NAME,__FUNCTION__,0,0,0); printf("ChassisTimerTask Started... \n"); //create if(-1 != access(CHASSIS_PWR_HNDLR_Q, F_OK)) { remove(CHASSIS_PWR_HNDLR_Q); } if(0 != mkfifo (CHASSIS_PWR_HNDLR_Q, 0777)) { printf("%s: Create %s fifo failed! %s\n", __FUNCTION__, CHASSIS_PWR_HNDLR_Q, strerror(errno)); return (void*)-1; } gFd_ChassisPwrHndlrQue = open (CHASSIS_PWR_HNDLR_Q, O_RDWR); if(-1 == gFd_ChassisPwrHndlrQue) { printf("%s: Open %s fifo failed! %s\n", __FUNCTION__, CHASSIS_PWR_HNDLR_Q, strerror(errno)); return (void*)-1; } preChassisSeconds = g_BMCInfo.CurTimerSecond; preFanSeconds = g_BMCInfo.CurTimerSecond; while(1) { if(GetMsg(gFd_ChassisPwrHndlrQue, &MsgPkt, 0) == 0) { if(MsgPkt.Param == PARAM_CHASSIS) { //Chassis power control if((NET_FN(MsgPkt.NetFnLUN) == NETFN_CHASSIS) && (MsgPkt.Cmd == CMD_CHASSIS_CONTROL)) { switch(MsgPkt.Data[0]) { case CHASSIS_POWER_DOWN: PDK_PowerOffChassis(); break; case CHASSIS_POWER_UP: PDK_PowerOnChassis(); break; case CHASSIS_POWER_CYCLE: PDK_PowerCycleChassis(); break; case CHASSIS_HARD_RESET: PDK_ResetChassis(); break; case CHASSIS_PULSE_DIAGNOSTIC_INTERRUPT: PDK_DiagInterruptChassis(); break; case CHASSIS_SOFT_SHUTDOWN: PDK_SoftOffChassis(); break; default: printf("Invalid power control cmd\r\n"); break; } } } else if(MsgPkt.Param == PARAM_MC) { if(((MsgPkt.NetFnLUN>>2) == NETFN_APP) && ((MsgPkt.Cmd == CMD_COLD_RESET) || (MsgPkt.Cmd == CMD_WARM_RESET))) { sleep(1); //wait ipmi request response finish. stm32_reset_mcu(); } } } //Chassis timer interval if((g_BMCInfo.CurTimerSecond != preChassisSeconds) &&((g_BMCInfo.CurTimerSecond - preChassisSeconds) >= g_BMCInfo.IpmiConfig.ChassisTimerInterval)) { //log("Chassis interval\r\n"); preChassisSeconds = g_BMCInfo.CurTimerSecond; //TODO: //g_BMCInfo.PowerGoodFlag = 1; g_BMCInfo.IpmiConfig.ChassisPowerState.PowerState = g_BMCInfo.PowerGoodFlag; } //Fan control if((g_BMCInfo.CurTimerSecond != preFanSeconds) && (g_BMCInfo.CurTimerSecond % g_BMCInfo.IpmiConfig.FanControlInterval) == 0) { preFanSeconds = g_BMCInfo.CurTimerSecond; PDK_FanControl(); } //Chassis Identify if(g_BMCInfo.ChassisIdentify == TRUE) //新开个线程实现,默认灯闪烁10s,参考IPMI协议 { if(IdentifyTickCnt == 5) //0.5s { IdentifyTickCnt++; printf("-> Turn on led!\r\n"); } else if(IdentifyTickCnt == 10) { IdentifyTickCnt = 0; printf("-> Turn off led!\r\n"); } else { IdentifyTickCnt++; } //Identify finished if(((g_BMCInfo.CurTimerSecond - preIdentifySeconds) >= g_BMCInfo.ChassisIdentifyTimeout) && (g_BMCInfo.ChassisIdentifyForce != 1)) { g_BMCInfo.ChassisIdentify = FALSE; } } else { preIdentifySeconds = g_BMCInfo.CurTimerSecond; IdentifyTickCnt = 0; } sleep(1); } }