arachnidlabs / cyflash

Bootloader tool for Cypress PSoC series microcontrollers.
BSD 2-Clause "Simplified" License
44 stars 23 forks source link

Enabling verbose mode crashes cyflash #28

Closed anuraj-rp closed 5 years ago

anuraj-rp commented 5 years ago

Hi,

When I enable the --verbose mode, cyflash crashes with the following traceback

Traceback (most recent call last):
File "..\Scripts\cyflash-script.py", line 11, in <module>
load_entry_point('cyflash==1.7', 'console_scripts', 'cyflash')()
File "..\lib\site-packages\cyflash\bootload.py", line 396, in main
    args.psoc5)
File "..\lib\site-packages\cyflash\bootload.py", line 254, in bootload
    self.enter_bootloader(data)
File "..\lib\site-packages\cyflash\bootload.py", line 304, in enter_bootloader
    silicon_id, silicon_rev, bootloader_version = self.session.enter_bootloader(self.key)
File "..\lib\site-packages\cyflash\protocol.py", line 388, in enter_bootloader
    response = self.send(EnterBootloaderCommand(key))
File "..\lib\site-packages\cyflash\protocol.py", line 380, in send
    self.transport.send(packet)
File "..\lib\site-packages\cyflash\protocol.py", line 432, in send
    print("s: 0x%02x" % ord(char))
TypeError: ord() expected string of length 1, but int found

Is this a known problem?

C47D commented 5 years ago

It's been a lot since i tried to use this module, what python version are you using?

anuraj-rp commented 5 years ago

I am using python version 3.7.2 on a 64 bit Windows 10 machine.

C47D commented 5 years ago

I'm not very fluent in Python, but this is what i guess the problem is:

This is the method where the error comes from (it's part of the SerialTransport class):

    def send(self, data):
        if self._verbose:
            for char in data:
                print("s: 0x%02x" % ord(char))
        self.f.write(data)

So with verbose set to True the elements of data gets printed on the console, based on this question on StackOverflow (TypeError: ord() expected string of length 1, but int found) I'm guessing in Python 3.7.2 it's not neccesary to call ord(), so it may be necessary to modify the send and receive functions as follows:

diff --git a/cyflash/protocol.py b/cyflash/protocol.py
index df839cc..5fa6204 100644
--- a/cyflash/protocol.py
+++ b/cyflash/protocol.py
@@ -428,8 +428,8 @@ class SerialTransport(object):

     def send(self, data):
         if self._verbose:
-            for char in data:
-                print("s: 0x%02x" % ord(char))
+            for char in range(len(data)):
+                print("s: 0x%02x" % data[char])
         self.f.write(data)

     def recv(self):
@@ -439,8 +439,8 @@ class SerialTransport(object):
         size = struct.unpack("<H", data[-2:])[0]
         data += self.f.read(size + 3)
         if self._verbose:
-            for part in data:
-                print("r: 0x%02x" % ord(part))
+            for part in range(len(data)):
+                print("r: 0x%02x" % data[part])
         if len(data) < size + 7:
             raise BootloaderTimeoutError("Timed out waiting for Bootloader response.")
         return data

Maybe Python 2 and 3 compatible method to convert bytes to integer is a solution.

anuraj-rp commented 5 years ago

Hi,

I don't see this change on your fork.

Is the code in previous comment the complete diff patch file?

anuraj-rp commented 5 years ago

Hi,

I tried your code in Python3 and it works but it fails in Python2 with the following error.

TypeError: %x format: a number is required, not str

Ofcourse we could fix this by various methods mentioned in the Stackoverflow link Python 2 and 3 compatible method to convert bytes to integer

Python2 reaches end of life on 1st, Jan, 2020. Is there a plan to keep this module compatible with Python2?

C47D commented 5 years ago

Hi, I don't see this change on your fork. Is the code in previous comment the complete diff patch file?

It's on my machine, I forgot to push it on my fork. I also saw a lot of places where print(''.format()) is being used, while others use print("r: 0x%02x" % data[part]), maybe we can also agree on what format to use.

Python2 reaches end of life on 1st, Jan, 2020. Is there a plan to keep this module compatible with Python2?

I was also thinking about this, maybe @jsiverskog can let us know about his plans.

jsiverskog commented 5 years ago

how about something like this:

for part in bytearray(data, encoding="ascii"):
    print("r: 0x%02x" % part)
anuraj-rp commented 5 years ago

Hi,

It works without the encoding part in the code from @jsiverskog ascii only allows values upt 255.

I created a pull request with the fix. Tested with Python3.7.2 and Python2.7.15 on Windows 10 64 bit machine

anuraj-rp commented 5 years ago

Should I close this issue? @C47D @jsiverskog

C47D commented 5 years ago

You can close it now or until your pull request gets merged.