views:

292

answers:

2

I'm working on a new project that I plan to keep in a git repository. I know how I would do this in CVS, but I'm a bit new to git and could use some suggestions.

The project is firmware for two embedded devices that talk to each other and are packaged as a pair. For both devices there is a production variant and a manufacturing variant of the code. Both device projects have a number of sub/sibling projects for exercising various bits of the hardware (blink the LEDs, etc), or hardware related bits of code (drivers, etc). Most of the code is common across everything.

I also have a requirement to be able to rev the production and manufacturing firmware independently of each other to prevent a change to one from sending the other back through verification.

Below is my existing directory layout. It grew organically and was largely laid down before I knew I would be using git. I'm not averse to reorganizing the whole thing if there's a better way to do it.

  • ProjectRoot
    • include
    • src
    • DeviceA
      • production
      • manufacturing
      • blink
      • buttons
      • ...
    • DeviceB
      • production
      • manufacturing
      • blink
      • buttons
      • ...

I'm tempted to put production and manufacturing on branches, but I typically work on both in a given day and git only allows one branch to be active at a time. And then I wouldn't know what to do with blink, buttons, etc because they're not really manufacturing or production. Suggestions?

Clarifications:

  • The manufacturing version of the code is used on the manufacturing line to test the hardware. The production code is loaded after the hardware passes the test station and is what's shipped to the customer. The two are at least 75% similar, but they need to be independent so I can fix a bug in the production code without having to stop the manufacturing line.

  • Because DeviceA and DeviceB are a pair, both code sets are tagged and released at the same time with the same release version number.

+1  A: 

I think you could use sub-modules. I am not 100% sure how this works, but you can create a git repo for you common code (say LED and user interface, or even one repo for each), and include a copy of this repo as a submodule of your repo for A, and another copy as a submodule of the repo for B.

If you want to make changes to the common part, do that on the unit your currently working on. When you're done, push the changes to the submodules of the other product. You could also have the repo for the common part somewhere else if that feels more comfortable.

To sum up: have your reusable code in separate repos, so you CAN reuse it.

I'm no king of submodules, but I will soon need to do the same thing as you're doing. So I'm interested in how you will get it working.

Gauthier
+2  A: 

I used git to manage hardware/software codesigns, so I may have some useful advice to give.

As a rule of thumb, if you have parts of the design that can interoperate with each other regardless of the revision you're working on, you're better off making separate git repositories for these.

To give an example, you want your driver to sit in a separate repository from your hardware design. This is because the interface between software and hardware is very clear-cut and is a natural seam to decompose by. Furthermore, the same driver version will apply to a range of design stages of your device.

I am not sure what you mean by production and manufacturing editions of the design. If you want to decouple the development and stable versions, you should be fine with having separate branches for these.

Branching and merging in git is as cheap as you can get, and switching between branches is lightning fast; so there's no penalty for having branches. It is also fairly easy to cherry-pick compatible changes between branches. The approach that you usually see in software world (branches for releases, plus one HEAD) works fairly well.

You should probably keep the demo/test modules (blinkers etc) together with the modules they are supposed to demo/test. This is because the demo coupling interfaces are often change-prone. This way you will have to keep the demo code in sync with the actual devices, which should help design stability in the long run.

As a side note, in the FPGA world, you are usually prototyping on a large device, and productionizing on a restricted device. This way, your modules end up having two varieties that are developed independently. You will probably want to keep these varieties in separate repositories, because they are, in effect, different entities. In this case, the code that is shared between the two (there's always some portable code you can reuse) can live in a separate repo, and be a separate library. Especially if the code size justifies it.

You can then bind all the mentioned modules together by using git submodules.

filmil
Is there some way to have multiple branches active/visible at the same time? I serve multiple masters so I'm constantly bouncing between tasks (yes, it's as wonderful as it sounds). It looks like git requires all changes to a branch to be checked in before switching.
Brandon Fosdick
Ok, I've read through the submodule tutorials. Now I'm thinking about making two repositories: a submodule for the common code and one for the main project. The main project would have branches for production, manufacturing and demo/test. If I do this, will the submodule show up in each branch?
Brandon Fosdick
Yes, you can have multiple branches active/visible at the same time. Simply make a second clone of the same repository (or pull it from the same source, depending on how you set up your work environment). Then do 'git checkout' on different branches in each repository, and there you have it. Use git push/git pull afterwards to bring the repos in sync.
filmil