evil-mad-EggBot/EBB_firmware/Analysis/firmware tests/scripts/EBBCommandParseThroughputTe...

182 wiersze
6.0 KiB
Python

# A standardized way to test the throughput (how many commands per second) of an EBB
# This test can be used to measure the relative changes in command parsing throughput
# as the EBB firmware is changed.
# It can also provide an rough absolute metric of how many USB commands per second an EBB
# can process.
#
# The basic idea is to send various commands to the EBB, and measure the time it takes for
# the EBB to process all of them, then print out the average time/command.
#
# The most basic command is something like the "NI" (Node Increment) command, which is
# not a motion command, executes very quickly since it only modifies one internal
# variable, and returns very little (just an "OK"). This will be the fastest command.
#
# This command (NI) can be tested during various conditions:
# * When no motion or other commands are happening
# * When simple SM/XM/HM commands are ongoing (i.e. both steppers are moving)
# * When complex motion commands are ongoing (LM/LT)
# Comparing the values for these times can give an idea of how much the various types
# of motion commands load down the USB processing
#
# After sending the command, we wait for the full response to come back from the EBB
# before continuing with the next command. This is the worst-case timing use case.
#
# The other test is to use a simple SM command which is very short, and repeat it
# over and over to see how fast motion commands can be processed.
#
# Each command is sent one a a time, rather than multiple commands packet together,
# to mimic the real life usage of the EBB.
import sys
import time
from plotink import ebb_serial
def query(port_name, cmd):
''' Simple serial query function '''
port_response = ''
if port_name is not None and cmd is not None:
try:
port_name.write(cmd.encode('ascii'))
port_response = port_name.readline()
n_retry_count = 0
while len(port_response) == 0 and n_retry_count < 100:
port_response = port_name.readline()
n_retry_count += 1
except:
print("Error reading serial data.")
return port_response
the_port = ebb_serial.openPort()
if the_port is None:
print("failed to connect")
sys.exit() # end script
the_port.reset_input_buffer()
print("Starting EBB USB throughput testing.")
response = query(the_port, 'V\r')
print(response)
"""
# Test 10000 "NI" commands with no motion
startTime = time.perf_counter()
for x in range(10000):
query(the_port, "NI" + '\r')
endTime = time.perf_counter()
print(f"{((endTime - startTime)*1000)/10000:3.3f} ms per NI command when motion idle")
time.sleep(5)
# Test 10000 "NI" commands with simple motion
query(the_port, "SM,10000,200000,200000" + '\r')
startTime = time.perf_counter()
for x in range(10000):
query(the_port, "NI" + '\r')
endTime = time.perf_counter()
print(f"{((endTime - startTime)*1000)/10000:3.3f} ms per NI command with simple (SM/XM/HM) motion")
time.sleep(10)
# Test 10000 "NI" commands with complex motion
query(the_port, "LT,250000,858999350,-5436,858999350,-5436,3" + '\r')
startTime = time.perf_counter()
for x in range(10000):
query(the_port, "NI" + '\r')
endTime = time.perf_counter()
print(f"{((endTime - startTime)*1000)/10000:3.3f} ms per NI command with complex (LM/LT) motion")
time.sleep(15)
"""
# Section to test fastest separate move commands tolerated by EBB Firmware
# Note that worst case timings are used here - max step rate (25Khz) and both steppers stepping
# together at that rate. This gives the CPU the least amount of time to parse USB commands as
# possible.
#
# When this code is run, it should be used with the GPIO_DEBUG and UART_OUTPUT_DEBUG defined so that
# it is easy to see on the logic analyzer when the FIFO is not full all the time. The UART output
# can then be used to see which command caused the un-full FIFO.
# First for SM command
for x in range(100):
query(the_port, "SM,10,250,250" + '\r')
for x in range(100):
query(the_port, "SM,9,225,225" + '\r')
for x in range(100):
query(the_port, "SM,8,200,200" + '\r')
for x in range(100):
query(the_port, "SM,7,175,175" + '\r')
for x in range(100):
query(the_port, "SM,6,150,150" + '\r')
for x in range(100):
query(the_port, "SM,5,125,125" + '\r')
for x in range(100):
query(the_port, "SM,4,100,100" + '\r')
for x in range(100):
query(the_port, "SM,3,75,75" + '\r')
for x in range(100):
query(the_port, "SM,2,50,50" + '\r')
for x in range(100):
query(the_port, "SM,1,25,25" + '\r')
time.sleep(0.5)
# Then for XM command
for x in range(100):
query(the_port, "XM,10,250,0" + '\r')
for x in range(100):
query(the_port, "XM,9,225,0" + '\r')
for x in range(100):
query(the_port, "XM,8,200,0" + '\r')
for x in range(100):
query(the_port, "XM,7,175,0" + '\r')
for x in range(100):
query(the_port, "XM,6,150,0" + '\r')
for x in range(100):
query(the_port, "XM,5,125,0" + '\r')
for x in range(100):
query(the_port, "XM,4,100,0" + '\r')
for x in range(100):
query(the_port, "XM,3,75,0" + '\r')
for x in range(100):
query(the_port, "XM,2,50,0" + '\r')
for x in range(100):
query(the_port, "XM,1,25,0" + '\r')
time.sleep(0.5)
# Then for LM command
for x in range(100):
query(the_port, "LT,250,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,225,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,200,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,175,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,150,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,125,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,100,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,75,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,50,2147483647,-1,2147483647,-1" + '\r')
for x in range(100):
query(the_port, "LT,25,2147483647,-1,2147483647,-1" + '\r')
time.sleep(0.5)
print("Test complete")
the_port.close()