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 7 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.
28 changes: 15 additions & 13 deletions mbed_flasher/flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,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 All @@ -89,7 +89,7 @@ def __find_by_platform_name(platform_name, ls):
def flash_multiple(self, build, platform_name, pyocd=False, target_prefix=''):
device_mapping_table = self.get_available_device_mapping()
aux_device_mapping_table = []

if not platform_name:
found_platform = ''
for item in device_mapping_table:
Expand All @@ -115,10 +115,8 @@ def flash_multiple(self, build, platform_name, pyocd=False, target_prefix=''):
if platform_name:
if item['platform_name'] == platform_name:
aux_device_mapping_table.append(item)

if len(aux_device_mapping_table) > 0:
device_mapping_table = aux_device_mapping_table


device_mapping_table = aux_device_mapping_table
device_count = len(device_mapping_table)
if device_count == 0:
self.logger.error('no devices to flash')
Expand All @@ -133,19 +131,18 @@ def flash_multiple(self, build, platform_name, pyocd=False, target_prefix=''):
# pyOCD support for Linux based OSs is not so robust, flashing works sequentially not parallel
i = 0
for device in device_mapping_table:
ret = self.flash(build, device['target_id'], None, device_mapping_table, pyocd)
ret = self.flash(build, device['target_id'], platform_name, device_mapping_table, pyocd)
if ret == 0:
self.logger.debug("dev#%i -> SUCCESS" % i)
else:
self.logger.warning("dev#%i -> FAIL :(" % i)
retcodes += ret
i += 1

else:
passes = []
retcodes = 0
for target in device_mapping_table:
retcode = self.flash(build, target['target_id'], None, device_mapping_table, pyocd)
retcode = self.flash(build, target['target_id'], platform_name, device_mapping_table, pyocd)
retcodes += retcode
if retcode == 0:
passes.append(True)
Expand Down Expand Up @@ -179,19 +176,21 @@ def flash(self, build, target_id=None, platform_name=None, device_mapping_table=

if target_id.lower() == 'all':
return self.flash_multiple(build, platform_name, pyocd)
elif len(target_id) < 48:
elif len(target_id) < 48 and platform_name == 'K64F': # prefix flashing support, ID length is 48 for K64F
return self.flash_multiple(build, platform_name, pyocd, target_id)

elif len(target_id) < 20 and platform_name == 'SAM4E': # prefix flashing support, ID length is 20 for SAM4E
Copy link
Contributor

Choose a reason for hiding this comment

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

why there is SAM4E hard coded here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

platform_name has to be given when flashing and for SAM4E target_id length is max 20. if we do not have the separation of K64F and SAM4E prefix support stops working. i.e. giving a prefix 02 that would flash all devices that start with 02 would go to either ATMEL flash or Mbed flash.

return self.flash_multiple(build, platform_name, pyocd, target_id)

if device_mapping_table:
if isinstance(device_mapping_table, dict):
device_mapping_table = [device_mapping_table]
elif not isinstance(device_mapping_table, list):
raise SystemError('device_mapping_table wasn\'t list or dictionary')
else:
device_mapping_table = self.get_available_device_mapping()

self.logger.debug(device_mapping_table)

try:
if target_id:
target_mbed = self.__find_by_target_id(target_id, device_mapping_table)
Expand All @@ -210,6 +209,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, pyocd=pyocd)
except KeyboardInterrupt:
Expand Down
83 changes: 51 additions & 32 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):
FlasherAtmelAt.logger = logging.getLogger('mbed-flasher')
if exe is None:
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,28 @@ def get_available_devices():
return connected_devices

# actual flash procedure
def flash(self, source, target):
def flash(self, source, target, pyocd=None):
"""flash device
:param sn: device serial number to be flashed
:param binary: binary file to be flash
: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 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:
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

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
21 changes: 3 additions & 18 deletions mbed_flasher/flashers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,6 @@
from FlasherAtmelAt import FlasherAtmelAt

AvailableFlashers = [
FlasherMbed
]

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)
FlasherMbed,
FlasherAtmelAt
]
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(name='mbed-flasher',
setup(
name='mbed-flasher',
version='0.3.1',
description=DESCRIPTION,
long_description=read('README.md'),
Expand All @@ -46,9 +47,9 @@ def read(fname):
maintainer_email=OWNER_EMAILS,
url='https://github.com/ARMmbed/mbed-flasher',
packages=find_packages(),
package_data={'': ['FlasherMbed.target_info.json']},
package_data={'': ['FlasherMbed.target_info.json', 'edbg_ubuntu', 'edbg_raspbian', 'edbg.exe']},
license=LICENSE,
test_suite = 'test',
test_suite='test',
tests_require=["mock"],
entry_points={
"console_scripts": ["mbedflash=mbed_flasher:mbedflash_main",],
Expand Down
Loading