[Python] 3, embedded device based on the serial communication of the computer Automatic test program framework (Rough framework)

Source: Internet
Author: User
Tags ord

Monday, 20. August 2018 01:53 am-beautifulzzzz

1. Preface

Do similar zigbee, ble mesh ... Wireless network node performance testing, manual operation and then look at the appearance is often difficult to find out the real cause, and some deep-seated problems hidden in the weak network environment, or a large number of tests, because in the upper computer with the script to implement automated hanging machine test is particularly important.

This paper introduces an automatic test program framework (rough frame) for PC based on serial communication written in Python.

2. Introduction to Code Framework

As follows: The entire code consists of two layers of app+bsp, where:

    • BSP layer of hardware-related code (such as the Linux system with python2.7 write serial drive Class);
    • The app layer contains two apps app_app_auto_test_0xda_0xdb_adapter and a app_app_auto_test_off_line ;

Where the application is implemented based on the code in BSP, enter each separate application folder, run make all to run ~

➜  mesh_test_toos git:(master) ✗ tree.├── app│   ├── app_app_auto_test_0xda_0xdb_adapter│   │   ├── app_auto_test.py│   │   ├── app_frame.py│   │   ├── main.py│   │   └── makefile│   └── app_app_auto_test_off_line│       ├── app_frame.py│       ├── app_frame.pyc│       ├── main.py│       └── makefile└── bsp    ├── bsp_serial.py    ├── bsp_serial.pyc    ├── bsp_system.py    └── bsp_system.pyc4 directories, 12 files

3. BSP Code Introduction

bsp_system.py: The file currently only has a function to get the current timestamp, accurate to milliseconds:

#!/usr/bin/env python# coding=utf-8import timedef get_time_stamp():    ct = time.time()    local_time = time.localtime(ct)    data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)    data_secs = (ct - long(ct)) * 1000    time_stamp = "[%s.%03d] " % (data_head, data_secs)    return time_stampversion = '0.1'

bsp_serial.py: The file encapsulates a bsp_serial class on pyserial that contains several member functions:

    • Instantiation function: Automatically read all the serial ports in the system, if there are multiple will let you choose one, and open, produce a SER member variable
    • iswaiting function: Call this function before reading to see if there is any data
    • Read function: Reads a byte
    • Write function: Writes an array of data
    • Close function: Closing function

A Demo for read:

ser1 = bsp_serial.bsp_serial(9600)  while 1<2:    if ser1.iswaiting() > 0:        x = ser1.read()        print x

Note: If you want to write datas when reading, you should use the thread (next'll show you)!

4, App_app_auto_test_off_line Demo Introduction

This script is to automatically test whether a node in the wireless network with a long-hanging machine in case there is a drop condition:

The network has a mesh lamp point and a dongle mesh node connected to the PC due to the features of the BLE mesh:

处于同一mesh网络中的节点中维护一个全部节点的在线/离线状态的表

So if you want to realize the online/offline status of the Lantern Festival, you only need to read the status table periodically from the dongle node! Each 15S dongle node here passes the status table to the PC in the format of the frame shown in the figure:

    • Head is the frame head, fixed
    • CMD is the frame command, and its value is 0x07 when synchronizing the state table
    • Length is the data size, here is 8
    • Data1, data2 are data, each 4 bytes represents the state of a node, the 1th byte represents the node ID, and the second byte is 0 means offline
    • Check is a checksum, except for the bit data and modulo 256

The class that is used to parse the packet is implemented in app_frame.py :

#!/usr/bin/env python# coding=utf-8import sysimport termiosclass frame:head1=0 head2=1 VERSION=2 CMD=3 LEN 1=4 len2=5 len_head=6 max_data_buf_size = + def __init__ (self,fun_analysis): Self.data_buf = "" Self.     Fun_analysis = fun_analysis "Judge Frame is OK" def FRAME_OK (self,str): Start_pos = 0 Fram_len = 0 End_pos = 0 Str_len = len (str) While start_pos<str_len:pos = Start_pos if (ord (str[pos]) = = 0x (pos!=str_len-1) and (Ord (str[pos+1]) = = 0xAA): Break Start_pos = start_pos+1 if (start_p OS = = Str_len): #no find Return ( -1,start_pos,end_pos) if (Start_pos + FRAME. Len_head < Str_len): #print str_len,start_pos,frame. LEN2 Fram_len = Ord (str[start_pos+frame. LEN2]) End_pos = Start_pos + FRAME.     Len_head +fram_len #print Fram_len,end_pos if (End_pos < Str_len): return (0,start_pos,end_pos) Return ( -2,start_pos,end_pos) "Insert data to frame FIFO" Def insert_data (self,data): Self.data_buf+=data If Len (self.data_buf ) > Self. MAX_DATA_BUF_SIZE:self.data_buf = "" "Analysis frame and perform" def Run (self): while 1&lt ; 2: (Ret,start_pos,end_pos) = SELF.FRAME_OK (self.data_buf) #print (Ret,start_pos,end_pos) if (ret = = 0 ): Self.fun_analysis (self.data_buf[start_pos:end_pos+1]) Self.data_buf = Self.data_buf[end_pos:]

The instantiation function of the frame class needs to register a command parsing function FUN_ANALYSIS;FRAME_OK to determine if the packet is correct; Insert_data is used to insert the data received from the serial port into the FIFO, receiving the insertion data and processing separate The run function is used to continuously fetch data from the FIFO and determine if it is a valid packet, and then call fun_analysis for parsing and subsequent processing.

Note: The Run function requires a single thread!


Two threads are opened in main.py -serial receive thread and frame run thread:

import threadingimport app_frameimport syssys.path.append('../../bsp')import bsp_serialimport bsp_systemdef init():    #......(略)def analysis_cmd(str):    #......(略)def ser_receive():    global ser1    global frame    while 1<2:    if ser1.iswaiting() > 0:        x = ser1.read()        frame.insert_data(x)total_num = 0fail_times = 0ser1 = bsp_serial.bsp_serial(9600)frame = app_frame.FRAME(analysis_cmd)      try:    init()    threads = []     t1 = threading.Thread(target=ser_receive)    t2 = threading.Thread(target=frame.run)    threads.append(t1)    threads.append(t2)       for t in threads:    t.setDaemon(True)    t.start()    t.join()except Exception, e:    ser1.close()             # close port    print("safe exit"+str(e))
    • The serial receiving thread continuously reads the serial port data and inserts it into the FIFO of the Frame object.
    • The frame run function continuously parses the data in the FIFO and, if a valid packet is detected, calls Analysis_cmd processing

The final effect is as follows:

5, App_app_auto_test_0xda_0xdb_adapter Demo Introduction

This example is similar to the above, and is used to test the success rate of a Get state command:

    • 1) The whole mesh network architecture or dongle+1 a node lamp;
    • 2) The PC sends the request command to the dongle through the serial port;
    • 3) dongle received cmd1 immediately through the serial port to answer the command, and to the Lantern point request status;
    • 4) The lamp receives the request to return the status to the Dongle,dongle again through the serial port to the PC;

Visible: Automated testing the entire process is not as simple as DEMO1, there are multiple responses, so we have to pay attention to setting timeout!

So the app_auto_test.py implementation is as follows:

#... Slightly class auto_process:start=0 process1=1 process2=2 finish=3 def __init__ (self,ser): Self.auto = AUTO _process. START self.ser = Ser def analysis_cmd (self,str): # ... slightly if cmd1 = = 0x08:print "\033[1;34m>> \033[0m", Self.auto = self. PROCESS2 def run (self): # ... Slightly all_times = 0 Fail1_times = 0 fail2_times = 0 while 1<2:if Self.auto = = self. Start:all_times = all_times + 1 time.sleep (2) self.ser.write (cmd_get_status_ All) Self.auto = auto_process. PROCESS1 Time.sleep (2) elif Self.auto = = self. Process1:fail1_times = fail1_times + 1 print "Fail%d"%self.auto Self.auto = self. START elif Self.auto = = self. Process2:fail2_times = fail2_times + 1 print "Fail%d"%self.auto Self.auto = self. START else:print "Success%d total:%d fail1:%d fail2:%d"% (self.auto,all_times,fail1_times,fail2_ti MES) Self.auto = self. START

Frame's analysis_cmd function is used to parse the command returned by the serial port to determine the value of changing the member variable auto; the Run function is used to actively send the request and wait for the return, if the timeout is not received, it will change auto to fail and print the result.

Link
    • Project GitHub Address: Github.com/nbtool/auto_test_tool

@beautifulzzzz智能硬件、物联网,热爱技术,关注产品博客:http://blog.beautifulzzzz.com园友交流群:414948975

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.