python 串口修改bios
#python2 import sys,platform from serial import Serial import time,re if str(platform.python_version().split('.')(0)) == '3': print "Error:can not support python3" sys.exit(1) class BIOSCMD(object): # BIOS MENU UI BIOS_SETUP_MENU_ENTRY_PAT = r'Press[\w\W]+\[F2\]' BIOS_BOOTOPTON_SELECT_PAT= r'Press[\w\W]+\[F7\]' BIOS_CMD_KEY_ENTER = '\r' BIOS_CMD_KEY_ESC = '\33'+' ' BIOS_CMD_KEY_UP = '\33'+'[A' BIOS_CMD_KEY_DOWN = '\33'+'[B' BIOS_CMD_KEY_RIGHT = '\33'+'[C' BIOS_CMD_KEY_LEFT = '\33'+'[D' BIOS_CMD_KEY_PAGEUP = '\33'+'?' BIOS_CMD_KEY_PAGEDOWN = '\33'+'/' BIOS_CMD_KEY_F1 = '\33'+'1' BIOS_CMD_KEY_F2 = '\33'+'2' BIOS_CMD_KEY_F3 = '\33'+'3' BIOS_CMD_KEY_F4 = '\33'+'4' BIOS_CMD_KEY_F5 = '\33'+'5' BIOS_CMD_KEY_F6 = '\33'+'6' BIOS_CMD_KEY_F7 = '\33'+'7' BIOS_CMD_KEY_F8 = '\33'+'8' BIOS_CMD_KEY_F9 = '\33'+'9' BIOS_CMD_KEY_F10 = '\33'+'0' BIOS_CMD_KEY_F11 = '\33'+'!' BIOS_CMD_KEY_F12 = '\33'+'@' BIOS_CMD_KEY_Y = 'y' BIOS_CMD_KEY_N = 'n' BIOS_CMD_KEY_DELETE = '\33'+'-' BIOS_CMD_KEY_HOME = '\33'+'h' BIOS_CMD_KEY_END = '\33' + 'k' BIOS_CMD_KEY_INSERT = '\33' + '+' BIOS_CMD_KEY_SPACE = ' ' BIOS_CMD_KEY_BACKSPACE = '\10' BIOS_CMD_KEY_CTRL_ALT_DELETE = '\33R\33r\33R' BIOS_CMD_KEY_CTRL = '\21' BIOS_CMD_KEY_ALT = '\22' BIOS_CMD_KEY_SHIFT = '\20' BIOS_CMD_KEY_PLUS = '\20' + '+' BIOS_CMD_KEY_MINUS = '\20' + '-' class Test(): def __init__(self,Port,Bps,Timeout=None): self.Port = Port self.Bps = Bps self.Timeout = Timeout self.depth = 1 try: self.con=Serial(self.Port,self.Bps,timeout=self.Timeout) except: print('Open Serial Port Error') sys.exit(1) def read(self): #read form in_waiting try: lenth = self.con.in_waiting if lenth > 0: data = self.con.read(lenth) return data except Exception as e: print('read error:{}'.format(e)) def write(self,cmd): self.con.flushOutput() try: self.con.write(cmd) except Exception as e: print("write error:{}".format(e)) def enter_into_UEFI(self,timeout=100): """ :param timeout: :return: True or False """ serial_data = '' s_time=time.time() is_PressF7 = False is_IntoUEFI = False pattern_f7=re.compile(BIOSCMD.BIOS_BOOTOPTON_SELECT_PAT) while True: if time.time() - s_time > timeout: print ('into F7 Timeout') return False data = self.read() if not data: continue serial_data += data if is_PressF7: if not is_IntoUEFI: if serial_data.find(r'Please select boot device:') != -1: if self.select_bios_option(option=r'UEFI Internal Shell'): self.write(BIOSCMD.BIOS_CMD_KEY_ENTER) is_IntoUEFI = True else: print ('Select UEFI Internal Shell Failed') return False else: if serial_data.find(r'Shell>') != -1: return True else: for serial_data_line in serial_data.split('\n'): if pattern_f7.search(serial_data_line): self.write(BIOSCMD.BIOS_CMD_KEY_F7) is_PressF7 = True def enter_into_f2(self,timeout=100): """ :param timeout: :return: True or False """ serial_data = '' s_time = time.time() is_PressF2 = False pattern_f2 = re.compile(BIOSCMD.BIOS_SETUP_MENU_ENTRY_PAT) while True: if time.time() - s_time > timeout: print ('into F2 Timeout') return False data = self.read() if not data: continue serial_data += data if is_PressF2: if serial_data.find(r'EDKII Menu') != -1: self.depth = 1 return True else: for serial_data_line in serial_data.split('\n'): if pattern_f2.search(serial_data_line): self.write(BIOSCMD.BIOS_CMD_KEY_F2) is_PressF2 = True def load_default_setup(self): if self.select_bios_option(optionpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration'],option=r'Hardware Prefetcher'): print "Wait a few seconds to load default BIOS setup" self.write(BIOSCMD.BIOS_CMD_KEY_F9) time.sleep(3) self.write(BIOSCMD.BIOS_CMD_KEY_Y) time.sleep(30) if self.back_to_setup_toppage(): return True return False def reset_from_bios_setup(self): self.write(BIOSCMD.BIOS_CMD_KEY_CTRL_ALT_DELETE) def save_bios_setup(self): print 'Wait a few seconds to save setup' self.write(BIOSCMD.BIOS_CMD_KEY_F10) time.sleep(3) self.write(BIOSCMD.BIOS_CMD_KEY_Y) time.sleep(30) return True def back_to_setup_toppage(self): if self.depth == 1: return True for i in range(1,self.depth): self.write(BIOSCMD.BIOS_CMD_KEY_ESC) time.sleep(3) return True def set_highlight_option(self,option=None,timeout=180): """ :param option: :return: True or False """ if option is None: return False #pat1 is to findout F2 setup highlight line #pat2 is to findout F7 highlight line pat1 = re.compile('\33\[0m\33\[37m\33\[40m\33\[(\d+);\d+H[\w\s\d<>\[\]&-]+\33\[0m') pat2 = re.compile('\33\[1m\33\[37m\33\[40m\33\[\d+;\d+H([\w\s\d<>\[\]&-]+)\33\[1m') #flush serial buffer in 5 sec for i in range(0,5): self.read() time.sleep(1) s_time = time.time() #set timeout flag while True: serial_data = '' if time.time() - s_time > timeout: print "set highlight option timeout" return False self.write(BIOSCMD.BIOS_CMD_KEY_DOWN) #read serial log in 2 sec for i in range(0,2): data = self.read() if data: serial_data += data time.sleep(1) #get F2 or F7 highlignt number pat1_res = pat1.findall(serial_data) pat2_res = pat2.findall(serial_data) if not pat1_res and not pat2_res: continue if pat1_res and pat2_res: print 'Error' return None if pat1_res: for n in pat1_res: #according to current highlight line number to findout all words in this line pat3 = re.compile('{};\d+H([\w\s\d\[\]\(\)\?\*\.\-<>&/]+)'.format(n)) pat3_res = pat3.findall(serial_data) print(''.join(pat3_res)) if ''.join(pat3_res).find(option) != -1: return True else: continue if pat2_res: if ''.join(pat2_res).find(option) != -1: return True else: continue return False def select_bios_option(self, optionpath, option=None): """ this func is help to goto Bios Setup Option which you want ex.dirpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration'] option = r'Hardware Prefetcher' return value : True or False """ #goto option dir for path in optionpath: if self.set_highlight_option(path): print "==>Enter into",path self.write(BIOSCMD.BIOS_CMD_KEY_ENTER) self.depth += 1 else: return False #just goto optionpath if not option: return True #set hihglight option return self.set_highlight_option(option) def set_option_value(self,optionpath,option,value=None,type='select'): #ex: value = enable #type: # select: select a value # write: write a value if not self.select_bios_option(optionpath,option): print "select bios option failed" return False if value is None: print ('set option value is None') return False if not type is 'select' and not type is 'write': print ('type should be select or write,that means select a value or write a value') return False #flush buffer in 5 sec for i in range(0,5): self.read() time.sleep(1) #enter into option self.write(BIOSCMD.BIOS_CMD_KEY_ENTER) if type is 'write': if not isinstance(value,str): value = str(value) self.write(value+'\r') if self.save_bios_setup(): self.back_to_setup_toppage() return True else: return False #read buffer serial_data = '' for i in range(0,2): data = self.read() if data: serial_data += data time.sleep(1) #cut out the part of serial data which only include option value pat1 = re.compile('\33\[0m\33\[37m\33\[44m([\w\W]+)') pat1_res = pat1.findall(serial_data) #findout option values pat2 = re.compile('\33\[\d+;\d+H([\w][\w\s]+)') option_values = pat2.findall(''.join(pat1_res)) option_values_length = len(option_values) #print option,'option_values=',option_values for i in range(0,option_values_length-1): serial_data = '' self.write(BIOSCMD.BIOS_CMD_KEY_DOWN) #read buffer in 2 sec for i in range(0,2): data = self.read() if data: serial_data += data time.sleep(1) if serial_data == '': continue pat3 = re.compile('\33\[1m\33\[37m\33\[46m\33\[\d+;\d+H([\w][\w\s]+)') get_highlight_value = pat3.findall(serial_data) if value in get_highlight_value: self.write(BIOSCMD.BIOS_CMD_KEY_ENTER) if self.save_bios_setup(): self.back_to_setup_toppage() return True else: return False for j in range(0,option_values_length-1): serial_data = '' self.write(BIOSCMD.BIOS_CMD_KEY_UP) #read buffer in 2 sec for i in range(0,2): data = self.read() if data: serial_data += data time.sleep(1) if serial_data == '': continue pat3 = re.compile('\33\[1m\33\[37m\33\[46m\33\[\d+;\d+H([\w][\w\s]+)') get_highlight_value = pat3.findall(serial_data) if value in get_highlight_value: self.write(BIOSCMD.BIOS_CMD_KEY_ENTER) if self.save_bios_setup(): self.back_to_setup_toppage() return True else: return False return False if __name__ == '__main__': T = Test(Port='COM4',Bps='115200') if T.enter_into_f2(timeout=200): print "Enter into F2 Setup successfully" #change bios option value if T.set_option_value(optionpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration'],option=r'Hardware Prefetcher',value=r'Disable',type='select'): print "Set BIOS Option value successfully" #T.reset_from_bios_setup()