objects

Menu

Monthly Archives: March 2017

This gives a high level overview or strategy for laying out a simple PCB in KiCad or other EDA tool. This is for beginners. It doesn’t give details, exactly how to use the user interface. This is not polished. It tries to teach something which is obvious only to experienced users, that might save beginners some learning time.

This is for a ‘simple’ design where:

most of the components are surface mount (SMD) on the front

the board is a 2-layer board (copper on the front and back, and not in a middle layer. Such a board is the cheapest to buy, design, and assemble.)

there are few components, and few busses (bundles of signal lines routed together.)

The strategy is:

read the netlist

auto spread or place your components

add a board outline larger than you think the board will take

move and rotate the components into the board outline, to minimize crossing of rats nest lines

add a front zone for the ground net

add a zone on the back for the power net

run the DRC tool

Now many of the rats nest lines will be gone, since the ground and power nets are usually the largest nets, and the DRC tool will connect the front and back zones to many of the pads on those nets. Most of the remaining rats nest lines are for “signal” nets.

Now add tracks and vias to any power pads (that are not through holes) to the power plane (zone) on the back.

Now iterate:

move and rotate components to reduce crossing of rats nest lines and to shrink the board area

run the DRC tool

When you have in some sense done all you can do to minimize crossing rats nest lines:

switch to the OpenGL view (push-and-shove only works in that view)

choose “Do not show filled areas in zones” (fill obscures tracks)

manually route the remaining rats nest lines, using push-and-shove instead of clicking at many places along the track’s route to make it go exactly where you want it.

If you need to move some components to get room for a signal track, use Grab instead of Move, since that will keep the tracks you have already connected to the component.

Now you might tweak by moving components and nodes of tracks, running the DRC often to check you haven’t violated design rules. Generally you might tweak to reduce the size of the board, but it is better if you did that before you did manual routing.

Finally:

redraw your board outline

run DRC again and insure your zones are still contiguous, connected planes (if you reduce the outline too much, it might island your ground and power planes. Generally a ring of copper around the board edge connects islands of the zone together. The ground and power planes can have some enclosed island, but one point of a ground plane is to let the signals go where they want in short paths.)

This is a report of one cryptic symptom (and possible) fixes you might encounter when you are embedded programming. I report it because I have experienced it more than once and always forget what it means.

When you are trying to flash your embedded mcu, the debugger seems to download to the chip, the debugger starts and then stops showing a stack trace something like this:

0xFFFFFFFE
reclaim_reent()

Usually you expect the debugger to stop at main() and wait for you to tell the debugger to run (but that depends on whether you have configured your IDE and debugger to breakpoint at main.)

About the latter. I am not sure, but modules you buy might already be flashed with a program such as a DFU bootloader, and are configured to protect a debugger from overwriting that code in ROM. For example, on the Nordic NRF51, to remove the protection and erase all of ROM so that you can then use the debugger:

So here I try to install Rust. Ultimately I want to program in Rust an embedded ARM mcu on a NRF52 radio chip using the NRF52DK dev board.

Meta

Typically a developer knows/remembers how to set up a development machine (how to install the OS, development packages, an IDE, etc.) Typically, you use the GUI, maybe write a shell script, take good notes, iterate when you discover packages missing.

Vagga helps you capture the entire process of setting up a development machine. You capture the process in a vagga configuration file. Which is a text configuration file or script; no GUI.

This blog itself is an annotated record of writing and debugging such a vagga configuration file.

Strategy

The Rust project moves fast. I don’t want to struggle with keeping up to date. I am not sure I will keep it. So I will install Rust in a container. A container is like a virtual machine, but lighter weight, and only on Linux.

Vagga is written in Rust. (I hoped Vagga might even install Rust for me but no, although written in Rust, I install a binary Vagga, which means I need to install Rust separately, but in a container.) In this case, using Vagga is a form of “eating your own dog food”: if you are going to learn Rust, you might as well use tools that are written in Rust.

More meta

Rustup is also a package manager (toolchain manager) exclusively for Rust.

Xargo is also a toolchain manager, exclusively for cross-compiling Rust language programs.

So it seems strange that to combat the proliferation of package managers, we invent yet another higher-level package manager. And here we use a chain/graph of package managers: vagga, rustup, cargo, xargo, your favorite Linux distribution’s package manager.

A high-level package manager makes more sense if you are targeting your app to many Linux distributions. Here, I am only targeting (ultimately) one embedded architecture. But by using a high-level package manager, I can distribute my development environment. And I can easily replicate my home dev machine in other remote physical locations.

Which seems like a problem with online repositories. I entered “sudo apt-get update”, and tried again. This time vagga seemed to install an OS in the container (in about a minute) and run the command, yielding:

Installing Rust compiler in the container

From my reading, I know the rust compiler command is “rustc”. Entering that at a command line, expect:

The program 'rustc' is currently not installed. You can install it by typing:
sudo apt install rustc

So I know that ubuntu has a package. I don’t want it installed directly, but in the vagga container.

Make this change in vagga.yaml:

- !Ubuntu yakkety
- !Install [rustc]

IOW, tell vagga you want to install the package named “rustc” in the container.

Now “vagga test” first checks the container configuration for updates and yields:

Generating locales (this might take a while)...
en_US.UTF-8... done
Generation complete.
Reading package lists... Done
E: Method mirror has died unexpectedly!
E: Sub-process mirror received a segmentation fault.
WARN:vagga::builder::commands::ubuntu: The `apt-get update` failed. You have no mirror setup, and default one is not always perfect.
Add the following to your ~/.vagga.yaml:
ubuntu-mirror: http://CC.archive.ubuntu.com/ubuntu
Where CC is a two-letter country code where you currently are.

So I created a file named “.vagga.yaml” in my home directory (this is a hidden “settings” file. Do not change your yagga configuration file i.e. ~/rustdev/vagga.yaml) with the contents

ubuntu-mirror: http://us.archive.ubuntu.com/ubuntu

Now, “vagga test” yields:

...
E: Failed to fetch http://security....
...
E: Some index files failed to download. They have been ignored, or old ones used instead.
WARN:vagga::builder::commands::ubuntu: The `apt-get update` failed. If this happens too often, consider changing the `ubuntu-mirror` in settings

So I followed this thread to find the “best” mirror, and changed the mirror, but it still fails.

So now I rethink: I really want embedded Rust, which suggests the nightly build of Rust, not the outdated package that Ubuntu provides. I don’t want to install packaged Rust, I want to install rustup….

Installing rustup

Rust is usually installed by the “rustup” tool. New goal: install rustup in the container. It seems like Ubuntu does not package rustup separately. So edit vagga.yaml to add the instructions given by Rust.org for installing rustup, wrapped in a shell inside vagga. Neively:

- !Ubuntu yakkety
- !Sh "curl https://sh.rustup.rs -sSf | sh"

But those instructions download a shell script and pipe it to a shell and the shell script is interactive. So I hacked some more. Summarizing the struggle:

curl was absent from the container

the curl package would not install because of mirrors outdated

I switched OS version to Xenial (Ubuntu 16.04LTS) hoping the mirrors were more stable

Now I wondering whether I can run my IDE in the container, and how my source code gets into and out of the container (probably git.) The answer seems to be that the directory where you invoke vagga is the “project” directory and is mapped into the container as /work. Your IDE can work outside the container. All artifacts of the build should be in the container and not pollute your project directory?

Brief notes

Until you get your vagga.yml correct, vagga seems to repeatedly download dependency packages. IOW, errors prevent completion of the container. When you achieve a correct container, then vagga knows, and only downloads dependency packages as needed (when the repository publishes a security update or a nightly update? Commands don’t establish dependencies?)

Doing “sudo apt-get update” between iterations seems to help some errors.

The directory where you invoke vagga is the “project” directory and is mapped into the container as /work.

Vagga stores the container in the hidden file .vagga in the project directory (alongside your vagga.yaml.) (To delete a container?)

absolute: origin is in one of the corners of the “paper” sheet, displays as “X…Y…”

relative: origin is wherever you set it using the space bar, displays as “dx…dy….”

KiCad continually displays the location of the cursor in the right side of the status bar which appears near the bottom of the application window. KiCad updates the displayed location even as you use some tool to draw, place, etc. KiCad displays the location of the cursor in both coordinate systems.

Use the relative coordinate system to layout a board mechanically. First set the origin, say to the upper left corner of your board: