#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()