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

Assembler refactor #4

Closed
theandrew168 opened this issue May 11, 2021 · 2 comments
Closed

Assembler refactor #4

theandrew168 opened this issue May 11, 2021 · 2 comments

Comments

@theandrew168
Copy link
Owner

theandrew168 commented May 11, 2021

The current design of running multiple passes over the instructions is a bit too cute. I think it'd make more sense to let the lexing / parsing phase be distinct from how labels / vars get resolved and how instructions get encoded down into bytes.

It could be cleaner to whip up a few descriptors for each instruction component / field. Each descriptor should validate the input when written and present the split / shifted encoding when read. Then, each instruction type is just a collection of these descriptors and their values can be or'd together to create the final instruction.

Also, I'm considering a rewriting the project in Go. I've been using it for my other recent projects and I've gotten used to the safety and confidence that its static typing provides. It frustrates me more than it used to when a syntax error only shows itself upon execution (or a missing import, a missing param, etc). The assembler itself wouldn't be very difficult (its just data in, data out). The fussy part would be the simple DFU implementation that I built for flashing the GD32 devices.

From what I've researched on USB programming in Go, it isn't pretty. On *nix platforms, it's the standard fair: make sure libusb is installed and cgo will take the wheel (the gousb module comes into play here). On Windows, though... big RIP. The docs are slim, the maintainer(s) don't seem very helpful, and it requires GCC to be installed. I looked at some other WinUSB based modules but nothing seemed very trustworthy (at this point).

However, the GD32 devices have a 2nd method of flashing new firmware: the STM32 loader. From what I can tell, this is a very common serial-based mechanism that can be used to program the STM32 family of devices and any other that implements the protocol. There is a python library for this process and I've tested it on the Longan Nano (seemed to work fine). The benefit of this method from a Go perspective is that it doesn't require fussing with USB! It only requires a serial connection.

As it turns out, dealing with serial devices is much more straightforward than USB on all platforms. Here is an existing library that does it. On *nix, you can read / write a device through the regular file API. Config options are handled with IOCTL calls (which Go supports via the syscall and unix modules). On Windows, serial devices can be accessed by means of a small set of functions within the winbase.h API. These functions are located in kernel32 and can dynamically loaded / called using the syscall library).

Sure, the syscall and unsafe modules have their downsides and risks. But I'd take them over cgo anyday! Not having to fuss with C compilers everywhere is a win. Anyway, if I can write a simple and clean STM32 loader in Go that works on all major platforms (Windows, macOS, Linux), I'll plan on continuing with the rewrite. There would be a lot of tests to convert to Go but... price of progress, I guess?

@aw
Copy link

aw commented May 18, 2021

Hi Andrew,

The current python-based assembler works perfectly, particularly with the USB-C DFU. I intend to continue using that because the code is simple, small, auditable, and it "just works" (python/libusb are very common on any Linux system).

I personally dislike UART/usb serial interfaces. I own 3 different ones and they never work correctly or as intended. Given the choice, I'd much rather program a device over USB without dealing with an external serial adapter.

If Bronzebeard is something you interact with, and maintain daily, and you constantly find it painful dealing with the Python code, and have performance issues and difficulty adding new features, then perhaps a rewrite can be justified. From your explanations though, it seems like the coding process and final outcome would be a regression rather than an improvement. I don't really see the advantage even from a developer's perspective.

However, I think if you just want to write and maintain Go moving forward because you prefer Go, then that's fine and entirely your choice. Nobody is stopping you there.

@theandrew168
Copy link
Owner Author

theandrew168 commented May 18, 2021

Alex,

This is great feedback and exactly the type of concerns that I want to hear about. The prospect of migrating Bronzebeard to Go was purely one of curiosity: would the project be any better off if it was written in Go? The language does work well for the web apps I've worked on recently and static typing is nice for code confidence. However, this project doesn't really suffer from performance issues or feature complexity. It is still a simple, single-file assembler with a low barrier to entry and is very easy to hack on.

I also appreciate your point of view on DFU (over USB-C) vs STM32 (over UART). While they have both worked for me personally, I don't have nearly as much experience with UART adapters as others do. Interacting with USB devices is much easier in Python and I've simplified the Windows workflow as much as I can (by bundling libusb.dll).

Given that the project is already cross-platform and meets its goals of being simple and effective, I think that it is better suited for Python. If the choice of language ever becomes an actual bottleneck / hindrance then maybe I'll reconsider. But without any obvious benefits beyond my own curiosity, it doesn't make much sense to proceed.

Thanks again for the honest feedback. I want to keep this project useful and approachable to as many programmers as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants