Browse Source

Merged in ryan_jarvis/espurna/dev (pull request #45)

Conflicts:
	code/ota.py
i18n
Xose Pérez 6 years ago
parent
commit
ff2b110b2a
2 changed files with 151 additions and 141 deletions
  1. +94
    -92
      code/memanalyzer.py
  2. +57
    -49
      code/ota.py

+ 94
- 92
code/memanalyzer.py View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# coding=utf-8
# -------------------------------------------------------------------------------
# ESPurna module memory analyser
# xose.perez@gmail.com
#
@ -11,23 +12,24 @@
# https://github.com/Sermus/ESP8266_memory_analyzer
# by Andrey Filimonov
#
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
from __future__ import print_function
from collections import OrderedDict
from sortedcontainers import SortedDict
import argparse
import os
import re
import shlex
import commands
import subprocess
import sys
import os
import re
import argparse
from collections import OrderedDict
#-------------------------------------------------------------------------------
from sortedcontainers import SortedDict
TOTAL_IRAM = 32786;
TOTAL_DRAM = 81920;
env="esp8266-4m-ota"
# -------------------------------------------------------------------------------
TOTAL_IRAM = 32786
TOTAL_DRAM = 81920
env = "esp8266-4m-ota"
objdump_binary = "xtensa-lx106-elf-objdump"
sections = OrderedDict([
("data", "Initialized Data (RAM)"),
@ -38,7 +40,8 @@ sections = OrderedDict([
])
description = "ESPurna Memory Analyzer v0.1"
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
def file_size(file):
try:
@ -46,8 +49,8 @@ def file_size(file):
except:
return 0
def analyse_memory(elf_file):
def analyse_memory(elf_file):
command = "%s -t '%s' " % (objdump_binary, elf_file)
response = subprocess.check_output(shlex.split(command))
if isinstance(response, bytes):
@ -56,59 +59,59 @@ def analyse_memory(elf_file):
# print("{0: >10}|{1: >30}|{2: >12}|{3: >12}|{4: >8}".format("Section", "Description", "Start (hex)", "End (hex)", "Used space"));
# print("------------------------------------------------------------------------------");
ret={}
usedRAM = 0
usedIRAM = 0
i = 0
for (id, descr) in list(sections.items()):
sectionStartToken = " _%s_start" % id
sectionEndToken = " _%s_end" % id
sectionStart = -1
sectionEnd = -1
ret = {}
for (id_, descr) in list(sections.items()):
section_start_token = " _%s_start" % id_
section_end_token = " _%s_end" % id_
section_start = -1
section_end = -1
for line in lines:
if sectionStartToken in line:
if section_start_token in line:
data = line.split(' ')
sectionStart = int(data[0], 16)
section_start = int(data[0], 16)
if sectionEndToken in line:
if section_end_token in line:
data = line.split(' ')
sectionEnd = int(data[0], 16)
section_end = int(data[0], 16)
if sectionStart != -1 and sectionEnd != -1:
if section_start != -1 and section_end != -1:
break
sectionLength = sectionEnd - sectionStart
section_length = section_end - section_start
# if i < 3:
# usedRAM += sectionLength
# usedRAM += section_length
# if i == 3:
# usedIRAM = TOTAL_IRAM - sectionLength;
# usedIRAM = TOTAL_IRAM - section_length;
ret[id]=sectionLength
# print("{0: >10}|{1: >30}|{2:12X}|{3:12X}|{4:8}".format(id, descr, sectionStart, sectionEnd, sectionLength))
ret[id_] = section_length
# print("{0: >10}|{1: >30}|{2:12X}|{3:12X}|{4:8}".format(id_, descr, section_start, section_end, section_length))
# i += 1
# print("Total Used RAM : %d" % usedRAM)
# print("Free RAM : %d" % (TOTAL_DRAM - usedRAM))
# print("Free IRam : %d" % usedIRAM)
return(ret)
return ret
def run(env, modules):
def run(env_, modules_):
flags = ""
for item in modules.items():
for item in modules_.items():
flags += "-D%s_SUPPORT=%d " % item
command = "export ESPURNA_BOARD=\"WEMOS_D1_MINI_RELAYSHIELD\"; export ESPURNA_FLAGS=\"%s\"; platformio run --silent --environment %s" % (flags, env)
command = "export ESPURNA_BOARD=\"WEMOS_D1_MINI_RELAYSHIELD\"; export ESPURNA_FLAGS=\"%s\"; platformio run --silent --environment %s" % (flags, env_)
subprocess.check_call(command, shell=True)
def modules_get():
modules = SortedDict()
modules_ = SortedDict()
for line in open("espurna/config/arduino.h"):
m = re.search(r'(\w*)_SUPPORT', line)
if m:
modules[m.group(1)] = 0
del modules['LLMNR']
del modules['NETBIOS']
return modules
modules_[m.group(1)] = 0
del modules_['LLMNR']
del modules_['NETBIOS']
return modules_
try:
@ -120,23 +123,22 @@ try:
args = parser.parse_args()
# Hello
print
print description
print
print()
print(description)
print()
# Check xtensa-lx106-elf-objdump is in the path
status, result = commands.getstatusoutput(objdump_binary)
status, result = subprocess.getstatusoutput(objdump_binary)
if status != 512:
print "xtensa-lx106-elf-objdump not found, please check it is in your PATH"
print("xtensa-lx106-elf-objdump not found, please check it is in your PATH")
sys.exit(1)
# Load list of all modules
available_modules = modules_get()
if args.list > 0:
print "List of available modules:\n"
print("List of available modules:\n")
for key, value in available_modules.items():
print "* " + key
print
print("* " + key)
print()
sys.exit(0)
# Which modules to test?
@ -150,7 +152,7 @@ try:
# Check test modules exist
for module in test_modules:
if module not in available_modules:
print "Module %s not found" % module
print("Module %s not found" % module)
sys.exit(2)
# Define base configuration
@ -163,19 +165,19 @@ try:
# Show init message
if len(test_modules) > 0:
print "Analyzing module(s) %s on top of %s configuration\n" % (", ".join(test_modules), "CORE" if args.core > 0 else "DEFAULT")
print("Analyzing module(s) %s on top of %s configuration\n" % (", ".join(test_modules), "CORE" if args.core > 0 else "DEFAULT"))
else:
print "Analyzing %s configuration\n" % ("CORE" if args.core > 0 else "DEFAULT")
print("Analyzing %s configuration\n" % ("CORE" if args.core > 0 else "DEFAULT"))
output_format="{:<20}|{:<11}|{:<11}|{:<11}|{:<11}|{:<11}|{:<12}"
output_format = "{:<20}|{:<11}|{:<11}|{:<11}|{:<11}|{:<11}|{:<12}"
print(output_format.format(
"Module",
"Cache IRAM",
"Init RAM",
"R.O. RAM",
"Uninit RAM",
"Flash ROM",
"Binary size"
"Module",
"Cache IRAM",
"Init RAM",
"R.O. RAM",
"Uninit RAM",
"Flash ROM",
"Binary size"
))
# Build the core without modules to get base memory usage
@ -183,13 +185,13 @@ try:
base = analyse_memory(".pioenvs/%s/firmware.elf" % env)
base['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
print(output_format.format(
"CORE" if args.core == 1 else "DEFAULT",
base['text'],
base['data'],
base['rodata'],
base['bss'],
base['irom0_text'],
base['size'],
"CORE" if args.core == 1 else "DEFAULT",
base['text'],
base['data'],
base['rodata'],
base['bss'],
base['irom0_text'],
base['size'],
))
# Test each module
@ -198,18 +200,18 @@ try:
modules[module] = 1
run(env, modules)
results[module]=analyse_memory(".pioenvs/%s/firmware.elf" % env)
results[module] = analyse_memory(".pioenvs/%s/firmware.elf" % env)
results[module]['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
modules[module] = 0
print(output_format.format(
module,
results[module]['text'] - base['text'],
results[module]['data'] - base['data'],
results[module]['rodata'] - base['rodata'],
results[module]['bss'] - base['bss'],
results[module]['irom0_text'] - base['irom0_text'],
results[module]['size'] - base['size'],
module,
results[module]['text'] - base['text'],
results[module]['data'] - base['data'],
results[module]['rodata'] - base['rodata'],
results[module]['bss'] - base['bss'],
results[module]['irom0_text'] - base['irom0_text'],
results[module]['size'] - base['size'],
))
# Test all modules
@ -223,23 +225,23 @@ try:
if len(test_modules) > 1:
print(output_format.format(
"ALL MODULES",
total['text'] - base['text'],
total['data'] - base['data'],
total['rodata'] - base['rodata'],
total['bss'] - base['bss'],
total['irom0_text'] - base['irom0_text'],
total['size'] - base['size'],
"ALL MODULES",
total['text'] - base['text'],
total['data'] - base['data'],
total['rodata'] - base['rodata'],
total['bss'] - base['bss'],
total['irom0_text'] - base['irom0_text'],
total['size'] - base['size'],
))
print(output_format.format(
"TOTAL",
total['text'],
total['data'],
total['rodata'],
total['bss'],
total['irom0_text'],
total['size'],
"TOTAL",
total['text'],
total['data'],
total['rodata'],
total['bss'],
total['irom0_text'],
total['size'],
))
except:


+ 57
- 49
code/ota.py View File

@ -1,31 +1,40 @@
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# coding=utf-8
# -------------------------------------------------------------------------------
# ESPurna OTA manager
# xose.perez@gmail.com
#
# Requires PlatformIO Core
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
from __future__ import print_function
import sys
import argparse
import re
import logging
import socket
import argparse
import subprocess
import sys
from time import sleep
from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf
#-------------------------------------------------------------------------------
try:
# noinspection PyUnresolvedReferences
input = raw_input # Python2
except NameError:
pass # Python3
# -------------------------------------------------------------------------------
devices = []
description = "ESPurna OTA Manager v0.1"
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
def on_service_state_change(zeroconf, service_type, name, state_change):
'''
"""
Callback that adds discovered devices to "devices" list
'''
"""
if state_change is ServiceStateChange.Added:
info = zeroconf.get_service_info(service_type, name)
@ -46,10 +55,11 @@ def on_service_state_change(zeroconf, service_type, name, state_change):
device['free_space'] = info.properties.get('free_space')
devices.append(device)
def list():
'''
"""
Shows the list of discovered devices
'''
"""
output_format="{:>3} {:<25}{:<25}{:<15}{:<15}{:<30}{:<10}{:<10}{:<10}"
print(output_format.format(
"#",
@ -79,12 +89,13 @@ def list():
device.get('free_space', ''),
))
print
print()
def get_boards():
'''
"""
Grabs board types fro hardware.h file
'''
"""
boards = []
for line in open("espurna/config/hardware.h"):
m = re.search(r'defined\((\w*)\)', line)
@ -92,10 +103,11 @@ def get_boards():
boards.append(m.group(1))
return sorted(boards)
def flash():
'''
"""
Grabs info from the user about what device to flash
'''
"""
# Choose the board
try:
@ -103,13 +115,13 @@ def flash():
except:
index = 0
if index < 0 or len(devices) < index:
print "Board number must be between 1 and %s\n" % str(len(devices))
print("Board number must be between 1 and %s\n" % str(len(devices)))
return None
board = {'board': '', 'ip': '', 'size': 0 , 'auth': '', 'flags': ''}
board = {'board': '', 'ip': '', 'size': 0, 'auth': '', 'flags': ''}
if index > 0:
device = devices[index-1]
device = devices[index - 1]
board['board'] = device.get('device', '')
board['ip'] = device.get('ip', '')
board['size'] = int(device.get('mem_size', 0) if device.get('mem_size', 0) == device.get('sdk_size', 0) else 0) / 1024
@ -117,68 +129,64 @@ def flash():
# Choose board type if none before
if len(board['board']) == 0:
print
print()
count = 1
boards = get_boards()
for name in boards:
print "%3d\t%s" % (count, name)
print("%3d\t%s" % (count, name))
count = count + 1
print
print()
try:
index = int(input("Choose the board type you want to flash: "))
except:
index = 0
if index < 1 or len(boards) < index:
print "Board number must be between 1 and %s\n" % str(len(boards))
print("Board number must be between 1 and %s\n" % str(len(boards)))
return None
board['board'] = boards[index-1]
board['board'] = boards[index - 1]
# Choose board size of none before
if board['size'] == 0:
try:
board['size'] = int(input("Board memory size (1 for 1M, 4 for 4M): "))
except:
print "Wrong memory size"
print("Wrong memory size")
return None
# Choose IP of none before
if len(board['ip']) == 0:
try:
board['ip'] = raw_input("IP of the device to flash (empty for 192.168.4.1): ") or "192.168.4.1"
board['ip'] = input("IP of the device to flash (empty for 192.168.4.1): ") or "192.168.4.1"
except:
print "Wrong IP"
print("Wrong IP")
return None
board['auth'] = raw_input("Authorization key of the device to flash: ")
board['flags'] = raw_input("Extra flags for the build: ")
board['auth'] = input("Authorization key of the device to flash: ")
board['flags'] = input("Extra flags for the build: ")
return board
def run(device, env):
command = "export ESPURNA_IP=\"%s\"; export ESPURNA_BOARD=\"%s\"; export ESPURNA_AUTH=\"%s\"; export ESPURNA_FLAGS=\"%s\"; platformio run --silent --environment %s -t upload"
command = command % (device['ip'], device['board'], device['auth'], device['flags'], env)
subprocess.check_call(command, shell=True)
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
if __name__ == '__main__':
# Parse command line options
parser = argparse.ArgumentParser(description=description)
#parser.add_argument("-v", "--verbose", help="show verbose output", default=0, action='count')
parser.add_argument("-c", "--core", help="flash ESPurna core", default=0, action='count')
parser.add_argument("-f", "--flash", help="flash device", default=0, action='count')
parser.add_argument("-s", "--sort", help="sort devices list by field", default='hostname')
args = parser.parse_args()
print
print description
print
# Enable logging if verbose
#logging.basicConfig(level=logging.DEBUG)
#logging.getLogger('zeroconf').setLevel(logging.DEBUG)
print()
print(description)
print()
# Look for sevices
zeroconf = Zeroconf()
@ -193,7 +201,7 @@ if __name__ == '__main__':
# Sort list
field = args.sort.lower()
if field not in devices[0]:
print "Unknown field '%s'\n" % field
print("Unknown field '%s'\n" % field)
sys.exit(1)
devices = sorted(devices, key=lambda device: device.get(field, ''))
@ -212,14 +220,14 @@ if __name__ == '__main__':
env = "esp8266-%sm-ota" % device['size']
# Summary
print
print "ESPURNA_IP = %s" % device['ip']
print "ESPURNA_BOARD = %s" % device['board']
print "ESPURNA_AUTH = %s" % device['auth']
print "ESPURNA_FLAGS = %s" % device['flags']
print "ESPURNA_ENV = %s" % env
response = raw_input("\nAre these values right [y/N]: ")
print
print()
print("ESPURNA_IP = %s" % device['ip'])
print("ESPURNA_BOARD = %s" % device['board'])
print("ESPURNA_AUTH = %s" % device['auth'])
print("ESPURNA_FLAGS = %s" % device['flags'])
print("ESPURNA_ENV = %s" % env)
response = input("\nAre these values right [y/N]: ")
print()
if response == "y":
run(device, env)

Loading…
Cancel
Save