1#!/usr/bin/env python
2#
3# Demonstrates the use of otatool.py, a tool for performing ota partition level
4# operations.
5#
6# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
7#
8# Licensed under the Apache License, Version 2.0 (the "License");
9# you may not use this file except in compliance with the License.
10# You may obtain a copy of the License at
11#
12#     http:#www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an "AS IS" BASIS,
16# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17# See the License for the specific language governing permissions and
18# limitations under the License.
19import argparse
20import os
21import re
22import subprocess
23import sys
24from subprocess import CalledProcessError
25
26import serial
27
28
29def get_running_partition(port=None):
30    # Monitor the serial output of target device. The firmware outputs the currently
31    # running partition
32
33    IDF_PATH = os.path.expandvars('$IDF_PATH')
34    sys.path.append(os.path.join(IDF_PATH, 'components', 'esptool_py', 'esptool'))
35    import esptool
36
37    ESPTOOL_PY = os.path.join(IDF_PATH, 'components', 'esptool_py', 'esptool', 'esptool.py')
38
39    baud = os.environ.get('ESPTOOL_BAUD', esptool.ESPLoader.ESP_ROM_BAUD)
40
41    if not port:
42        error_message = 'Unable to obtain default target device port.\nSerial log:\n\n'
43        try:
44            # Check what esptool.py finds on what port the device is connected to
45            output = subprocess.check_output([sys.executable, ESPTOOL_PY, 'chip_id'])  # may raise CalledProcessError
46            pattern = r'Serial port ([\S]+)'
47            pattern = re.compile(pattern.encode())
48
49            port = re.search(pattern, output).group(1)  # may raise AttributeError
50        except CalledProcessError as e:
51            raise Exception(error_message + e.output)
52        except AttributeError:
53            raise Exception(error_message + output)
54
55    serial_instance = serial.serial_for_url(port.decode('utf-8'), baud, do_not_open=True)
56
57    serial_instance.dtr = False
58    serial_instance.rts = False
59
60    serial_instance.rts = True
61    serial_instance.open()
62    serial_instance.rts = False
63
64    # Read until example end and find the currently running partition string
65    content = serial_instance.read_until(b'Example end')
66    pattern = re.compile(b'Running partition: ([a-z0-9_]+)')
67    running = re.search(pattern, content).group(1)
68
69    return running.decode('utf-8')
70
71
72def main():
73    parser = argparse.ArgumentParser()
74    parser.add_argument('--port', default=None)
75    args = parser.parse_args()
76
77    try:
78        res = get_running_partition(args.port)
79    except Exception as e:
80        print(e.message)
81        sys.exit(1)
82
83    print(res)
84
85
86if __name__ == '__main__':
87    main()
88