Flashlight Firmware Repository

I went through the same thing, and as far as I can remember, the crucial step was to run pageant (which is part of PuTTY) and load the generated private key into it. Then you can run the SSH session (in PuTTY, never tried it in a cmd prompt).

Yes, frustrating as hell, and it feels like a big FU to the windows plebs.

Because you might as well run Linux in a VM (which is a useful thing, by the way) and not be bothered with any of that when you pull a bzr branch. Just install the bzr package and it works. (Could be that *ubuntu has SSH set up by default, but still.)

Which is what I ended up doing anyways.

Thanks so much! It makes me feel a lot better knowing that other people have done this as Iā€™ve been worried that none of this was necessary. Even TK has said that bzr branch flashlight-firmware is the easiest way to get the firmware. Iā€™m sure sheā€™s right if you type it from Linux :person_facepalming: .

I installed the key into PuTTY, but am then confused about how to run Bazaar from PuTTY. I did manage to do so once back in January, but no longer remember how I did it and I seem recall that I still had problems :blush: . I wonā€™t ask for help with that as thatā€™s surely something I can look up on my own. It seems odd to me that BZR knows my identity on the command-prompt, but does not negotiate the SSH session. I donā€™t understand the system and understanding is key.

[sigh] Iā€™ve got Linux VMā€™s lying around, but Iā€™m a fool that has always coded and flashed with Windows, so thatā€™s what I wanted to do here. Iā€™ve used Linux since first installing Red Hat in 1998 (and Unix since college in 1994), but have never truly moved; Iā€™ve learned the hard way that dipping your toes into Posix from the comfort of Windows does not lead to mastery.

I thought that I was going about this entirely wrong, so your reply at least letā€™s me know that Iā€™m not crazy. I will try to come at this from a Linux VM and see what happens. Thanks again!

It has gotten a bit complicated in structure, in order to make things portable and keep the actual UI code relatively simple.

There are a few different layers or componentsā€¦

  • Thereā€™s the hardware-specific stuff, the hwdef-*.h files and the attiny abstraction header. This helps convert hardware-specific code into a more abstract API for portability.
  • Thereā€™s the UI toolkit, called FSM or ā€œspaghetti monsterā€. Itā€™s sort of a cross between a GUI toolkit and an OS kernel. It talks to the hardware, handles hardware events, does task scheduling, and exports a much friendlier API for applications to use.
  • Thereā€™s the application itself, Anduril. Itā€™s written in the abstract UI language of FSM. It defines states (modes), event handlers, transitions between states, and an idle processing loop.
  • ā€¦ and there are config files for Anduril. These set different options for different build targets. Mostly the build targets are one per supported hardware device. The config files set things like the ramp shape, the thermal response details, the aux LED settings, which modes to include, and other app-specific options.

The main thing you probably need to edit to make UI changes is anduril.c. And to better understand the FSM API itā€™s written in, thereā€™s a thread about how FSM works.

Orā€¦ To add support for a new type of hardware, it may be as simple as adding an Anduril config file for a new build target. It may also require a new hwdef file to map the pins and such. And depending on how different the hardware is, it could also require changing FSM itself, which I wouldnā€™t generally recommend for anyone who hasnā€™t spent a lot of time with it. Normally, people just hire me to do that because itā€™s not a very straightforward task. Itā€™s called a ā€œspaghetti monsterā€ because all the complicated ā€œspaghetti codeā€ is under the hood where UI developers donā€™t have to care about it.

Thatā€™s odd. Itā€™s not supposed to require authentication.

If the ā€œlp:ā€ prefix makes it try to use ssh, it should be able to bypass that by using a different URL. For example:

bzr branch ~toykeeper/flashlight-firmware/trunk : changes

However, I just tried this and itā€™s giving me HTTP errors. As far as Iā€™m aware, Launchpad has only had one or two people maintaining it for the past several years, and bzr itself hasnā€™t really been updated at all in a year or two. The company has basically ended most development on both.

So it may be a good idea to look into moving things to GitHub. I donā€™t like Git as much, especially how it handles branches and mergesā€¦ but at least itā€™s actively maintained and doesnā€™t completely lack any critical features. The hardest parts of a move are the people-related parts, not the tech underneath. Overall, GitHub would probably be easier for everyone except me.

I donā€™t suppose there is a cheat sheet for which firmware will work on which drivers?

Ish.

The INDEX file has something vaguely like this. But itā€™s not per driver; itā€™s per hardware feature and per software feature.

Thanks for this. Would seem I need to learn more about hardware design.

If I was looking for a solid but reasonably priced light that could use to learn about firmware programming (by tweaking your code) and was fairly easy to recover in the event I did something wrong, what might you recommend?

The BLF Q8 or Sofirn Q8 are probably the best choices. Nice large board, you can access the MCU without de-soldering wires (usually), it has lighted switch LEDs (more things to tweak). The thermal config is probably more forgiving too.

Yep, for me that starts to transfer some data, but then reports a 502: Bad Gateway. At the moment, I am relying on a tethered phone for my Internet connection, so itā€™s possible that it actually doesnā€™t like my gateway for some reason. I have made failed lp: attempts from a standard WiFi connection, however, so this seems an unlikely culprit.

And the bzr Windows installer reports a 2012 release date (v2.6b1). Unless the dates on the Windows release page are typos, thatā€™s a long time.

Iā€™ve heard other developers complain about some aspects of Git, so youā€™re not alone.

I donā€™t think you should necessarily move, since you are the key maintainer. If BZR works for you, it seems counterproductive to ask you to use Git. A move should only be made if many contributors agree. Making such a move is inevitably an investment of time and energy that might be better spent elsewhere. On the other hand, moving to Git may be inevitable, anyway.

There is really only one thing that folks like myself need; a way to get the repo or parts of it without downloading individual files one at a time. Github, for example, typically offers a button on each project page which lets visitors download the current repo as a ZIP archive without any need to install Git. I assume that this feature is automated and requires only a one-time setup on Github, but am not certain.

Launchpad offers no such download for the flashlight-firmware repo. If such a feature existed and did not require upkeep from the maintainer, it would satisfy the needs of many visitors. UPDATE: It does; see next post.

Are you looking for this?
Browse the code -> view revision -> download tarball

Ugh this would have saved me so much time since I downloaded all the stuff manually instead of doing all this BZR VM Unix stuff for a one-off edit. Will bookmark these

Yes! 5 months ago I searched and searched for such a link. I suspected it would exist, but it was not obvious to me and I apparently didnā€™t notice it on the revisions pages, which I did open.

Even if I saw it, I may have assumed it was a patch to a prior revision :person_facepalming: , as that page contains the list of changes. In my mind, the tarball would contain only those changes. While that seems non-intuitive to me, it makes perfect sense once you understand that every revision is fully tarballed.

I guess only contributors need to figure out the launchpad system :wink: .

Thanks so much!

Yeah, it probably needs to happen eventually.

Itā€™s just ā€¦ designed to do exactly the things I donā€™t want by default. So itā€™ll be kind of an uncomfortable change. Iā€™ve been using git lately for other projects, particularly ones with simple development modelsā€¦ but for the flashlight repository I often have a dozen branches all moving in parallel, each in its own directory. Git is weirdly not-good at that.

Thanks goodness itā€™s not just me.

The many-branches thing, or the difficulty with making Git handle that?

Sorry, I meant the awkwardness of branch management with Git. It made me feel better to hear a smart person make the same complaint :slight_smile: . This difficulty has trained me to minimize branching, which is a good or bad VCS trait depending on your point of view.

Sorry to ramble in your firmware thread, so Iā€™ll shut up for now.

Warning: Long post, lots of complaining, totally safe to skip.

It seems like git has all the right tools, or at least most of the right tools, but its interface design (and resulting cultural norms) could use some work.

Normally the way I work isā€¦ branch off the trunk so I have a dev area to work in. Hack code there for as long as it takes. Sometimes this is an hour, sometimes itā€™s a few months. Sometimes I merge upstream changes into my branch along the way, especially if itā€™s a long-lived branch. Then when itā€™s all done and fully tested, merge it back into trunk. Typically I then move the old working tree into an ā€œoldā€ or ā€œmergedā€ directory, because it often has extra files in it which arenā€™t and shouldnā€™t be committed into the repository itself. For example, notes from clients, todo lists for that specific branch, intermediate calculations and scripts, measurements, IDE clutter, etc. I donā€™t want to delete those files, but I donā€™t want them in the actual repository either.

And there are often quite a few of these branches being developed simultaneously. I tend to have some shells, editors, and maybe other things open for each one, and I usually leave that stuff open until the branch is merged and ready to be archived.

Any time I need to compare branches, itā€™s trivial. Standard filesystem tools can be usedā€¦ whatever tools I like. And the actual process of creating branches is simple too; simply copying a branch creates a new one. Every copy is its own branch, and its directory name is the branch name.

The default behavior in git is all wrong for this type of workflow. And more generally, the interface is a bit unintuitive.

For starters, that first step (creating a branch) isnā€™t done with the ā€œbranchā€ command. Itā€™s ā€œgit checkout -bā€. Thatā€™s simple enough though. The branch command isnā€™t for switching branches, itā€™s mostly used for listing branches and deleting old ones. The checkout command is used for creating branches and switching between them.

When it comes time to merge though, gitā€™s default behavior is to not merge at all. Instead, it pretends the branch never happened, and rewrites history to make it look like all the commits happened on trunk (er, master). ā€¦ and even though itā€™s default, itā€™s a behavior I literally never want. If I want to pretend history was linear, Iā€™ll use the rebase command. (as an aside: Plus, after merging, if I delete the old branch to get it out of the list of active branches, there is no record that the branch ever happened. Even if there was an actual revision for the merge instead of fast-forwarding.)

So I set a global config option to make ā€œmergeā€ always use the ā€œā€”no-ffā€ option. This tells it to do something sane by default instead of fast-forwarding to make it look like history was linear.

But then ā€œgit pullā€ breaks. Oops. Because ā€œpullā€ is just an alias for ā€œfetchā€ followed by ā€œmergeā€, and ā€œmergeā€ has been told not to fast-forward. There is no first-class concept of updating the current branch to match its upstream counterpart; itā€™s implemented as two separate steps which donā€™t necessarily have quite the same meaning.

So git eventually implemented a workaround for that. And I put it in my global git config, to make it do something sane without extra options. I set pull to use ā€œā€”ffā€ and ā€œā€”ff-onlyā€. So now it works again.

Iā€™ve tried to override some other defaults too, like setting ā€”no-commit by default during merge, because I want to make sure the tests pass before committing any merges. Merge, test, commit. But I havenā€™t found a way to make it do that yet. It tries really hard to enforce ā€œmerge, commit, test, fix, commitā€ instead of ā€œmerge, test, fix, commitā€ā€¦ and this tends to put broken revisions on the mainline, which is a big no-no.

Oh, and git has no concept of a mainline. So it canā€™t really tell which revisions were stable, well-tested parts of the trunk, and which were sloppy dev branch versions which are likely to have problems. This breaks the bisection tool, and makes it harder to read the history. In part because of this, it has become the cultural norm in git circles to make sure no one ever commits any broken revisionsā€¦ even in dev branches. People are expected to do their development and then rewrite history afterward to make sure each individual step works correctly. It creates extra work which shouldnā€™t be necessary.

Anyway, thereā€™s still the problem of git wanting to keep all the branches in the same directory in the filesystem. This is completely incompatible with my workflow. So I tried making copies for each branch with ā€œgit cloneā€. And then do work in the clones, doing things as normalā€¦ but then when it comes time to merge, I discover, oops, those clones donā€™t count as different branches. Different copies of a branch are treated as being still the same branch. But thatā€™s not too difficult to work around. Instead of just doing a clone, do a clone followed by a ā€œcheckout -bā€ with the same name. Work in clone X, in branch X. Then when itā€™s time to merge, donā€™t go back into the original copyā€¦ merge clone X branch X into clone X branch master. And then the original copy can fetch updates from the clone and update its head pointer. Kind of awkward.

Itā€™s a bit wasteful having the entire repository copied each time, but thatā€™s okay. Normally I avoid this in bzr by doing ā€œbzr init-repoā€ in the parent directory, so each branch effectively only has a new working tree without having to duplicate the history data. One parent dir with the metadata, many subdirs where each one is a branch. Pretty simple, straightforward, convenient, and reasonably disk-efficient.

Git finally added something similar, using the ā€œworktreeā€ command. Iā€™ve only just discovered this though, and havenā€™t had a chance to see how well it works in practice.

The ā€œworktreeā€ feature wasnā€™t added until ten years after Git was first released. It should have been the default behavior, yet wasnā€™t available for an entire decade. And from what Iā€™ve seen so far, itā€™s designed as sort of an afterthought so itā€™s still a bit awkward to use.

For example, it appears to not use a shared parent directoryā€¦ instead, one sibling is the primary, and other siblings are kinda just linked back to the primary. Technically, they donā€™t even have to be siblings; the other working trees can be anywhere on the filesystem. If I understand correctly, the primary needs to know about all the secondaries, and the secondaries each need a link back to the primary. It also appears that one cannot create a branch of a branch this way; each one must be branched off the primary.

Regardless, it seems a lot less awkward than working in a bunch of completely independent clones. Itā€™s just not as coherent or as well integrated as the default branching behavior in bzr. So Iā€™m quite disappointed to see bzr being left to die, because I find it to be a better-designed DVCS tool.

Linus does good work with the kernelā€¦ but he really, really should have consulted some user interface designers and VCS / SCM experts during the early phases of creating git.

Oh, bless you TK. Again, your posts have made me feel a lot better as Iā€™ve found Git highly non-intuitive. Though I donā€™t have anything like your workflow, I immediately recognize many of the issues you described. Iā€™ve always assumed I was just too dumb to use the tool, even after reading Pro Git (which is likely out-of-date anyway).

The branch history and merge thing especially rings true for me, as I constantly find myself not using Git for certain things and instead working around it :person_facepalming: , which violates the purpose of a VCS. I will often make a new project in order to avoid committing things to the ā€œpreciousā€ Git history of the mainline.

Iā€™ll have to learn more about ā€œworktreeā€.

Linus does things his own way, for better or worse.

I wonā€™t go on about this further, but your long post made my day :slight_smile: .

Is there a particular reason people have traditionally gone with AVR MCUs for the flashlight driver boards? One had more experience with the TI msp430 family of chips from my work with IoT in college.
I was thinking it might be fun to try and build a driver board/firmware using that.

Probably because the old nanjg driver used attiny13a, and thatā€™s where most of the open-source flashlight firmware development originated.

The PIC chips are also popular, but not well-supported yet in free flashlight software.

For the most part, it doesnā€™t seem to matter much which brand of chips are used, since most little MCUs have similar features and the cost difference isnā€™t large. So BLF-related projects have been using what BLF is familiar with and has code for.