Note

Following a national ballot, the union, UCU, that represents staff in the higher education sector has called a strike on three days in late November, and also "action short of a strike" during a period that starts on Wednesday, 23 November. During this period, colleagues are invited to take various actions, including abstaining from voluntary activities. I view the maintenance of Spivey's Corner as an activity I undertake voluntarily and not part of any contract of employment, and I cannot guarantee that it will remain accessible during the period of the dispute. In addition, some materials on the site may pertain to lectures that are cancelled by myself or others as part of the strike, and we are asked not to make them available online. Further details of the reasons for the strike and how it affects teaching in Oxford are on a brief FAQ page.

# Laboratory exercises

The course has four-and-a-bit lab exercises, each designed to be done in a single session or less. There is another page with hints for demonstrators.

I've added a couple of exercises related to things in the Trinity Term part of the course. They are there as a way of preserving and making available some existing materials – the Thumb simulator and a simulation of a carry-lookahead adder – in case participants want to experiment with them. There are no lab sessions in Trinity, and no expectation that participants will actually do these labs.

Is science a kind of playing? – Tom Spivey

## Rules

The labs for this course will run in a way that is slightly different from other courses, reflecting the wide variety of prior experience possessed by participants.

• No lab reports will be required. However, you may print out your code at the end of each lab session and have it initialled by one of the demonstrators if you want physical evidence of participation.
• In order to get a mark of S for the term, you must attend and participate in the lab sessions. Some participants will want to spend the time in the sessions practising assembly language programming; others will find that easy, and want to pass quickly on to later exercises, or pursue ideas of their own. All ways of engaging with the material are acceptable, and you won't be assessed on how far you have got through the sequence of suggested activities.
• In order to get a mark of S+ for the term, you must have shown a spark of originality at some point. Please don't ask us to suggest what degree of originality or what idea would be thought of as a spark.
• If you can't come to the lab sessions in person but want credit for them, then you must contact one of the demonstrators to discuss how you can participate remotely.
• We will be giving credit for participating in the lab sessions in a productive way in the context of your previous experience with low-level programming. It will not be possible to get credit for the lab exercises by attending only towards the end of term, whatever completed work you offer to show at that time.

The labs will be run Hanno Nickau with the assistance of the lecturer.

## Instructions

Each lab has its own page with instructions.

• Lab zero: getting started. Follow the instructions for building, loading and running a simple program that echoes input sent over the serial port. (Beyond building and running the program, there's nothing to do here – it's just a way of getting started and becoming more familiar with the tools.)
• Lab one: assembly language. Implement various arithmetic operations in assembly language.
• Lab two: general purpose I/O. Enhance an electronic Valentine's card to respond to button presses.
• Lab three: interrupts. Investigate a program that uses interrupts to overlap computing a list of primes with printing it.
• Lab four: micro:bian. Experiment with an embedded operating systems that supports concurrent processes communicating by messages.

Though there are no lab sessions scheduled for Trinity Term, nevertheless there are some (entirely optional) lab exercises that illustrate the material in the lectures and problem sheets.

• Lab five: Thumb simulator. Enhance an architectural simulation of a processor that implements the Thumb instruction set.

Software resources for the lab exercises are provided via a Mercurial repository, allowing for updates during term. You can browse the repository using a web interface, and instructions for making a local clone are provided as part of Lab zero. There are seven subdirectories in the repository corresponding to Labs zero to six, plus a setup directory used in the installation process. Several files appear as independent copies in multiple directories, for example, the file hardware.h that specifies the locations of various I/O registers on the micro:bit, and the file startup.c containing the code that runs when the micro:bit starts up. As far as possible, all files with the same name are identical, but in any event, they are consistent with each other. Naturally enough, each directory has its own unique Makefile.

Other pages contain information about programming the micro:bit and using the Linux-hosted toolchain to compile programs.

## Problems and fixes

Problems marked "(Fixed in rev n:123abc)" can be solved by pulling from the software repository and updating your working copy. Instructions for that are given below.

There was an error on the description of device registers in hardware.h, now fixed. Briefly, packets would be sent and received, but no data was stored in the received packet. The driver uses a single packet buffer for sending and receiving, and this caused the received data to be replaced by the contents of the packet buffer for the last message sent.
013 The debug script in Labs zero and one does not work.
Typically, gdb gives a message saying that the attempt to connect to :3333 has timed out. The last part of the instructions for Lab zero has instructions for starting the debug adapter and the debugger manually, making the chance of success higher, or at least making the cause of failure apparent.
012 Linking gives the message undefined reference to memset in Lab 2.
If the source program does not contain an explicit reference to memset, this is likely because the C compiler has inserted such a reference for itself, perhaps to initialise a local array. The Lab 2 linker command does not specify -lc, as a way of assuring us that almost all the code in the program appears explicitly in the source code, but the C library is needed for memset. Solution: add -lc to the link step (just before -lgcc) if needed. Alternatively, add versions of memcpy, memset, memmove and memcmp to startup.c.
011 Plugging in a micro:bit doesn't cause the MICROBIT drive to show up.
The micro-USB connector on a new micro:bit can be a little stiff, and if not pushed fully home can result in power and ground being connected but not the two data pins. (USB connectors are designed to connect the pins in that order.) Before suspecting software problems on the lab workstations, check the connector is fully home. Second, check that you don't have a power-only USB cable. Such cables are, in my experience, most commonly supplied for charging bike lights; they have the power and ground wires, but not the two wires that are used for transmitting data. If you use such a cable (or a poorly connected standard cable) to plug in a brand-new micro:bit, then out-of-box software will run, but the micro:bit will not show up as a drive on the host computer.
010 Compiling heart-intr.c in Lab 2 gives a message saying TIMER_INTEN_COMPARE0 is undeclared.
It should read TIMER_INT_COMPARE0. Now fixed in the repository.
008 On a Mac, the linking step for Lab 1 may possibly find the wrong version of libgcc.a. The symptom is that the integer division subroutine doesn't work, and the program crashes after printing "foo(" and before converting the argument to decimal for printing.
This is potentially due to misconfiguration or misguided Makefile editing by the participant. A good compromise would be to provide, commented out, the linking command that invokes gcc, so that it can be enabled in case of difficulty.
004 pyocd-gdbserver reports the micro:bit as an 'unknown board'.
This doesn't seem to matter much, if at all: the debugger works well for most participants. It certainly is not the cause of the problem reported in 002.
003 Adding a delay between successive characters output by serial_putc (such as simulating the seven stars of death) leads to a lock-up if characters are typed too quickly.
This happens for a similar reason to problem 002, because the serial_getc routine uses serial_putc to echo each character of input. If that is too slow, an overrun error is the result. The solution is to have the serial I/O and blinking lights run by independent processes: watch this space.
002 Typing in the minicom window when the echo or add program is stopped in the debugger leads to a lock-up.
This is inevitable: when the program is stopped, it is not able to fetch characters from the UART buffer quickly enough, and the UART enters an error state (see also this FAQ entry). Simple programs like those in Labs 0 and 1 assume they are able to fetch the characters fast enough to avoid this, and are not written to recognise or handle such error states, even when they are restarted by the debugger.
001 Building the echo program gives the message,
/usr/lib/gcc/arm-none-eabi/5.4.1/armv6-m/libgcc.a: file not found

This problem is fixed, but may recur if the list of places to look for libgcc.a turns out to be insufficient.

$hg pull  (issued from any directory inside your working copy). If that command reports that new revisions have been downloaded, then you can incorporate them into your working copy with the command, $ hg up

This will keep the changes to files you have edited or added, and merge in the changes to other files from the repository. The only problem arises if a file has been edited both by you and by Mike as part of the new revision(s) in the repository. In this case, Mercurial tries to merge the changes, but it doesn't always succeed, and may report a 'conflict'. This is most likely to affect Makefiles, where you have manually incorporated a fix to the build process, and Mike has later added the fix to the master repoitory. If conflicts happen, the Makefile will contain a mixture of the two versions, with lines marked as coming from one or the other. Your original file is preserved as Makefile.orig. If you get into this situation, it's generally safe to go with the updated master copy of Makefile, but I suggest you ask us for help with the commands needed to resolve the situation.