Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atmel support and fixes #18

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include README.md LICENSE
recursive-include bin *
20 changes: 20 additions & 0 deletions bin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
mbed SDK
Copyright (c) 2011-2015 ARM Limited

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

"""! @package binary_files
binary files for mbed-flasher
"""
20 changes: 20 additions & 0 deletions bin/edbg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
mbed SDK
Copyright (c) 2011-2015 ARM Limited

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

"""! @package binary_files
binary files for mbed-flasher
"""
Binary file added bin/edbg/edbg.exe
Binary file not shown.
Binary file added bin/edbg/edbg_raspbian
Binary file not shown.
Binary file added bin/edbg/edbg_ubuntu
Binary file not shown.
44 changes: 36 additions & 8 deletions mbed_flasher/erase.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import types
from time import sleep
from os.path import join, isfile
import subprocess
import platform

EXIT_CODE_SUCCESS = 0
EXIT_CODE_RESET_FAILED_PORT_OPEN = 11
Expand All @@ -31,6 +33,7 @@
SLEEP_TIME_FOR_REMOUNT = 5
EXIT_CODE_ERASE_FAILED_NOT_SUPPORTED = 33
EXIT_CODE_TARGET_ID_MISSING = 34
EXIT_CODE_NOT_SUPPORTED_METHOD_FOR_PLATFORM = 37


class Erase(object):
Expand Down Expand Up @@ -115,17 +118,20 @@ def erase(self, target_id=None, method=None):
:param method: method for erase i.e. simple, pyocd or edbg
"""
self.logger.info("Starting erase for given target_id %s" % target_id)
self.logger.info("method used for reset: %s" % method)
self.logger.info("method used for erase: %s" % method)
available_devices = self.get_available_device_mapping()
targets_to_erase = []

if target_id is not None:
if isinstance(target_id, types.ListType):
for target in target_id:
for device in available_devices:
if target == device['target_id']:
if device not in targets_to_erase:
targets_to_erase.append(device)
if 'all' in target_id:
targets_to_reset = available_devices
else:
for target in target_id:
for device in available_devices:
if target == device['target_id']:
if device not in targets_to_erase:
targets_to_erase.append(device)
else:
if target_id == 'all':
targets_to_erase = available_devices
Expand Down Expand Up @@ -158,10 +164,32 @@ def erase(self, target_id=None, method=None):
pass
self.logger.info("erase completed")
elif method == 'edbg':
print "Not supported yet"
return EXIT_CODE_NOT_SUPPORTED_METHOD_FOR_PLATFORM
else:
print "Selected method %s not supported" % method
print "Selected method %s not supported by K64F" % method
return EXIT_CODE_NONSUPPORTED_METHOD_FOR_ERASE
elif item['platform_name'] == 'SAM4E':
from flash import Flash
flasher = Flash.get_flasher('atmel')
if method == 'simple':
cmd = [flasher.exe, "-t", "edbg", "-i", "SWD", "-d", "atsam4e16e", "-s", item['target_id'], "erase"]
elif method == 'edbg':
flasher.set_edbg_exe(flasher.exe, True)
if platform.system() == 'Windows':
cmd = [flasher.exe, "-t", "atmel_cm4", "-s", item['target_id'], "--erase"]
else:
cmd = ['sudo', flasher.exe, "-t", "atmel_cm4", "-s", item['target_id'], "--erase"]
else:
print "Selected method %s not supported by SAM4E" % method
return EXIT_CODE_NOT_SUPPORTED_METHOD_FOR_PLATFORM
self.logger.info("erasing device")
flasher.logger.debug(cmd)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
flasher.logger.debug(stdout)
flasher.logger.debug(stderr)
self.logger.info("erase completed")
return proc.returncode
else:
print "Only mbed devices supported"
return EXIT_CODE_IMPLEMENTATION_MISSING
Expand Down
17 changes: 12 additions & 5 deletions mbed_flasher/flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def __get_flasher(self, platform_name):
raise NotImplementedError("Flashing %s is not supported" % platform_name)

for Flasher in self.FLASHERS:
if platform_name in self.SUPPORTED_TARGETS.keys():
if platform_name in Flasher.get_supported_targets().keys():
return Flasher()

raise Exception("oh nou")
Expand Down Expand Up @@ -171,7 +171,8 @@ def flash_multiple(self, build, platform_name, method='simple', target_ids_or_pr
passes = []
retcodes = 0
for target in device_mapping_table:
retcode = self.flash(build, target['target_id'], None, device_mapping_table, method)

retcode = self.flash(build, target['target_id'], platform_name, device_mapping_table, method)
retcodes += retcode
if retcode == 0:
passes.append(True)
Expand All @@ -195,11 +196,12 @@ def flash(self, build, target_id=None, platform_name=None, device_mapping_table=
:param device_mapping_table: individual devices mapping table
:param method: method for flashing i.e. simple, pyocd or edbg
"""

K64F_TARGET_ID_LENGTH = 48
SAM4E_TARGET_ID_LENGTH = 20

if target_id is None and platform_name is None:
raise SyntaxError("target_id or target_name is required")
raise SyntaxError("target_id or platform_name is required")

if not isfile(build):
self.logger.error("Given file does not exist")
Expand All @@ -209,7 +211,9 @@ def flash(self, build, target_id=None, platform_name=None, device_mapping_table=
else:
if target_id.lower() == 'all':
return self.flash_multiple(build, platform_name, method)
elif len(target_id) < K64F_TARGET_ID_LENGTH:
elif len(target_id) < K64F_TARGET_ID_LENGTH and platform_name == 'K64F':
return self.flash_multiple(build, platform_name, method, target_id)
elif len(target_id) < SAM4E_TARGET_ID_LENGTH and platform_name == 'SAM4E':
return self.flash_multiple(build, platform_name, method, target_id)

if device_mapping_table:
Expand Down Expand Up @@ -240,6 +244,9 @@ def flash(self, build, target_id=None, platform_name=None, device_mapping_table=
self.logger.debug("Flashing: %s", target_mbed["target_id"])

flasher = self.__get_flasher(platform_name)
if target_mbed['platform_name'] != platform_name:
raise SyntaxError("Platform '%s' is not supported by Flasher %s, please change the selected flasher" % (target_mbed['platform_name'], flasher.name))

try:
retcode = flasher.flash(source=build, target=target_mbed, method=method)
except KeyboardInterrupt:
Expand Down
97 changes: 63 additions & 34 deletions mbed_flasher/flashers/FlasherAtmelAt.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import subprocess
import logging
import tempfile
import platform


class FlasherAtmelAt(object):
Expand Down Expand Up @@ -52,18 +53,18 @@ def get_supported_targets():

@staticmethod
def set_atprogram_exe(exe):
FlasherAtmelAt.logger = logging.getLogger('mbed-flasher')
if exe is None:
path = ''
if os.path.exists('C:\\Program File\\Atmel\\'):
if os.path.exists('C:\\Program Files\\Atmel\\'):
path = 'C:\\Program Files\\Atmel\\'
elif os.path.exists('C:\\Program File (x86)\\Atmel\\'):
elif os.path.exists('C:\\Program Files (x86)\\Atmel\\'):
path = 'C:\\Program Files (x86)\\Atmel\\'
if path:
for dirpath, subdirs, files in os.walk(path):
for x in files:
if x.find("atprogram.exe") != -1:
FlasherAtmelAt.exe = os.path.join(dirpath, x)
print FlasherAtmelAt.exe
if not FlasherAtmelAt.exe:
for ospath in os.environ['PATH'].split(os.pathsep):
if ospath.find('Atmel') != -1:
Expand All @@ -73,22 +74,50 @@ def set_atprogram_exe(exe):
FlasherAtmelAt.exe = exe

FlasherAtmelAt.logger.debug("atprogram location: %s", FlasherAtmelAt.exe)


@staticmethod
def set_edbg_exe(exe, force_edbg=False):
FlasherAtmelAt.logger = logging.getLogger('mbed-flasher')
if exe is None or force_edbg:
if platform.system() == 'Windows':
FlasherAtmelAt.exe = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..', 'bin', 'edbg', 'edbg.exe'))
elif platform.system() == 'Linux':
if os.uname()[4].startswith("arm"):
FlasherAtmelAt.exe = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..', 'bin', 'edbg', 'edbg_raspbian'))
else:
FlasherAtmelAt.exe = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..', 'bin', 'edbg', 'edbg_ubuntu'))
elif platform.system() == 'Darwin':
print "Support for OS X is missing"
FlasherAtmelAt.exe = None

@staticmethod
def get_available_devices():
"""list available devices
"""
FlasherAtmelAt.logger = logging.getLogger('mbed-flasher')
if platform.system() == 'Windows':
FlasherAtmelAt.set_atprogram_exe(FlasherAtmelAt.exe)
if not FlasherAtmelAt.exe:
FlasherAtmelAt.set_edbg_exe(FlasherAtmelAt.exe)
if str(FlasherAtmelAt.exe).find('atprogram.exe') != -1:
cmd = [FlasherAtmelAt.exe, "list"]
lookup = 'edbg\W+(.*)'
else:
cmd = [FlasherAtmelAt.exe, "--list"]
lookup = '(\S.*) - Atmel.*'
else:
FlasherAtmelAt.set_edbg_exe(FlasherAtmelAt.exe)
cmd = [FlasherAtmelAt.exe, "--list"]
lookup = '(\S.*) - Atmel.*'
if not FlasherAtmelAt.exe:
return []
FlasherAtmelAt.set_atprogram_exe(FlasherAtmelAt.exe)
cmd = FlasherAtmelAt.exe + " list"
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
connected_devices = []
if proc.returncode == 0:
lines = stdout.splitlines()
for line in lines:
ret = FlasherAtmelAt.find(line, 'edbg\W+(.*)')
ret = FlasherAtmelAt.find_match(line, lookup)
if ret:
connected_devices.append({
"platform_name": "SAM4E",
Expand All @@ -101,38 +130,38 @@ def get_available_devices():
return connected_devices

# actual flash procedure
def flash(self, source, target):
def flash(self, source, target, method):
"""flash device
:param sn: device serial number to be flashed
:param binary: binary file to be flash
:param target: device serial number to be flashed
:param source: binary file to be flash
:param method: method used for flashing
:return: 0 when flashing success
"""
with tempfile.TemporaryFile() as temp:
temp.write(source)
temp.close()
temp.name
# actual flash procedure

cmd = self.exe+" -t edbg -i SWD -d atsam4e16e -s "+target['target_id']+" -v -cl 10mhz program --verify -f "+temp.name
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
FlasherAtmelAt.logger.debug(stdout)
FlasherAtmelAt.logger.debug(stderr)
return proc.returncode

@staticmethod
def lookupExe(alternatives):
"""lookup existing exe
:param alternatives: exes
:return: founded exe
"""
for exe in alternatives:
if os.path.exists(exe):
return exe
return None
if method == 'simple':
if str(self.exe).find('atprogram.exe') != -1:
cmd = [self.exe, "-t", "edbg", "-i", "SWD", "-d", "atsam4e16e", "-s", target['target_id'], "-v", "-cl", "10mhz", "program", "--verify", "-f", source]
else:
print "atprogram.exe not found, try with edbg"
return 66
elif method == 'edbg':
FlasherAtmelAt.set_edbg_exe(FlasherAtmelAt.exe, True)
if platform.system() == 'Windows':
cmd = [self.exe, "-bpv", "-t", "atmel_cm4", "-s", target['target_id'],"-f", source]
else:
cmd = ['sudo', self.exe, "-bpv", "-t", "atmel_cm4", "-s", target['target_id'],"-f", source]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably shouldn't execute using sudo inside the flasher

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least it did not work on my setup without sudo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree to @kuggenhoffen

There might not even be a sudo on some systems (say vanilla Debian).

I believe this is once again a case for some udev rule writing rehearsal

else:
print "unsupported flashing method"
return 67

FlasherAtmelAt.logger.debug(cmd)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
FlasherAtmelAt.logger.debug(stdout)
FlasherAtmelAt.logger.debug(stderr)
return proc.returncode

@staticmethod
def find(line, lookup):
def find_match(line, lookup):
"""find with regexp
:param line:
:param lookup:
Expand Down
22 changes: 3 additions & 19 deletions mbed_flasher/flashers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,7 @@
from FlasherAtmelAt import FlasherAtmelAt

AvailableFlashers = [
FlasherMbed
]
FlasherMbed,
FlasherAtmelAt
]

'''
if platform.system() == 'Windows':
for ospath in os.environ['PATH'].split(os.pathsep):
if ospath.find('Atmel') != -1:
AvailableFlashers.append(FlasherAtmelAt)
if FlasherAtmelAt not in AvailableFlashers:
path = ''
if os.path.exists('C:\\Program Files\\Atmel\\'):
path = 'C:\\Program Files\\Atmel\\'
elif os.path.exists('C:\\Program Files (x86)\\Atmel\\'):
path = 'C:\\Program Files (x86)\\Atmel\\'
if path:
for dirpath, subdirs, files in os.walk(path):
for x in files:
if x.find("atprogram.exe") != -1:
AvailableFlashers.append(FlasherAtmelAt)
'''
Loading