GlasgowEmbedded / glasgow

Scots Army Knife for electronics
BSD Zero Clause License
1.92k stars 183 forks source link

FX2 firmware too large? #99

Closed bgamari closed 5 years ago

bgamari commented 5 years ago

I just built firmware.bin on 8ae10d25574f583828203a85be58edfd92cbc8c7 and found that it contains over 10 kBytes of text:

firmware$ size glasgow.ihex 
   text    data     bss     dec     hex filename
      0   11059       0   11059    2b33 glasgow.ihex

This seems problematic given that the FX2 has only 8kB of RAM.

As one might expect, attempting to load this firmware onto the device fails:

$ sudo result/bin/glasgow  factory
Traceback (most recent call last):
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/bin/.glasgow-wrapped", line 12, in <module>
    sys.exit(main())
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/cli.py", line 656, in main
    exit(loop.run_until_complete(_main()))
  File "/nix/store/yv4pzx3lxk3lscq0pw3hqzs7k4x76xsm-python3-3.7.2/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/cli.py", line 337, in _main
    device = GlasgowHardwareDevice(firmware_file, VID_CYPRESS, PID_FX2)
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 100, in __init__
    self._download_firmware(input_data(f, fmt="ihex"))
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 80, in _download_firmware
    self._write_ram(address, data)
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 72, in _write_ram
    self.usb.controlWrite(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, addr, 0, data)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 1481, in controlWrite
    sizeof(data), timeout)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 1457, in _controlTransfer
    mayRaiseUSBError(result)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 133, in mayRaiseUSBError
    __raiseUSBError(value)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 125, in raiseUSBError
    raise __STATUS_TO_EXCEPTION_DICT.get(value, __USBError)(value)
usb1.USBErrorInvalidParam: LIBUSB_ERROR_INVALID_PARAM [-2]
marcan commented 5 years ago

The FX2 has 16KiB of RAM (CY7C68013A-56LTXC).

bgamari commented 5 years ago

The following is output from glasgow -vv factory, as requested by @whitequark:

$ sudo result/bin/glasgow -vv  factory --revision C
D: glasgow.device.hardware: found revA device without firmware
D: glasgow.device.hardware: loading firmware from /nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/glasgow.ihex
write_ram 58880 1
write_ram 0 6
write_ram 11 3
write_ram 19 3
write_ram 27 3
write_ram 35 3
write_ram 43 3
write_ram 51 3
write_ram 59 3
write_ram 67 3
write_ram 75 3
write_ram 83 3
write_ram 91 3
write_ram 99 98
write_ram 256 3
write_ram 260 3
write_ram 264 3
write_ram 268 3
write_ram 272 3
write_ram 276 3
write_ram 280 3
write_ram 284 3
write_ram 288 3
write_ram 292 3
write_ram 296 3
write_ram 300 3
write_ram 304 3
write_ram 308 3
write_ram 312 3
write_ram 316 3
write_ram 320 3
write_ram 324 3
write_ram 328 3
write_ram 332 3
write_ram 336 3
write_ram 340 3
write_ram 344 3
write_ram 348 3
write_ram 352 3
write_ram 356 3
write_ram 360 3
write_ram 364 3
write_ram 368 3
write_ram 372 3
write_ram 376 3
write_ram 380 3
write_ram 384 3
write_ram 388 3
write_ram 392 3
write_ram 396 3
write_ram 400 3
write_ram 404 3
write_ram 408 3
write_ram 412 3
write_ram 416 3
write_ram 420 3
write_ram 424 3
write_ram 428 3
write_ram 432 3
write_ram 436 3
write_ram 440 1
write_ram 446 10783
Traceback (most recent call last):
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/bin/.glasgow-wrapped", line 12, in <module>
    sys.exit(main())
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/cli.py", line 656, in main
    exit(loop.run_until_complete(_main()))
  File "/nix/store/yv4pzx3lxk3lscq0pw3hqzs7k4x76xsm-python3-3.7.2/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/cli.py", line 337, in _main
    device = GlasgowHardwareDevice(firmware_file, VID_CYPRESS, PID_FX2)
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 100, in __init__
    self._download_firmware(input_data(f, fmt="ihex"))
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 80, in _download_firmware
    self._write_ram(address, data)
  File "/nix/store/5smg02nfkfy3x29zaqcbmqiicggvg2im-python3.7-glasgow-0.1/lib/python3.7/site-packages/glasgow/device/hardware.py", line 72, in _write_ram
    self.usb.controlWrite(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, addr, 0, data)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 1481, in controlWrite
    sizeof(data), timeout)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 1457, in _controlTransfer
    mayRaiseUSBError(result)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 133, in mayRaiseUSBError
    __raiseUSBError(value)
  File "/nix/store/ry142lhv029chh1rh7jsyah11wf7443g-python3.7-libusb1-1.7/lib/python3.7/site-packages/usb1/__init__.py", line 125, in raiseUSBError
    raise __STATUS_TO_EXCEPTION_DICT.get(value, __USBError)(value)
usb1.USBErrorInvalidParam: LIBUSB_ERROR_INVALID_PARAM [-2]

I also have this patch applied for debugging purposes:

diff --git a/software/glasgow/device/hardware.py b/software/glasgow/device/hardware.py
index b4b8ad6..81c8acd 100644
--- a/software/glasgow/device/hardware.py
+++ b/software/glasgow/device/hardware.py
@@ -68,6 +68,7 @@ class GlasgowHardwareDevice:
             pass

     def _write_ram(self, addr, data):
+        print("write_ram", addr, len(data))
         self.usb.controlWrite(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, addr, 0, data)

     def _cpu_reset(self, is_reset):
whitequark commented 5 years ago

This was fixed by commit whitequark/libfx2@a06b7f573f71abe6e. Did you run git submodule update?

bgamari commented 5 years ago

Ahh, this commit wasn't present on the commit pointed to in the revC0 tag.

bgamari commented 5 years ago

Actually, I don't see how this could be fixed by that commit. The fx2 library appears nowhere in the backtrace. It looks to me like this issue just exists independently in software/glasgow/device/hardware.py.

whitequark commented 5 years ago

Good point! Can you try this patch:

diff --git a/software/glasgow/device/hardware.py b/software/glasgow/device/hardware.py
index 8b454a7..7b4d190 100644
--- a/software/glasgow/device/hardware.py
+++ b/software/glasgow/device/hardware.py
@@ -68,7 +68,11 @@ class GlasgowHardwareDevice:
             pass

     def _write_ram(self, addr, data):
-        self.usb.controlWrite(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, addr, 0, data)
+        while len(data) > 0:
+            chunk_length = min(len(data), 4096)
+            self.usb.control_write(usb1.REQUEST_TYPE_VENDOR, REQ_RAM, addr, 0, data[:chunk_length])
+            addr += chunk_length
+            data = data[chunk_length:]

     def _cpu_reset(self, is_reset):
         self._write_ram(REG_CPUCS, [1 if is_reset else 0])
bgamari commented 5 years ago

Made it much farther with that patch (although control_write should be controlWrite).