This assignment is a team assignment. Please work in teams of two unless approved by the instructor.
Equipment Needed
- The lab checklist. I will provide a printout of this.
- From the BeagleBone kit you purchased:
- Your BeagleBone black
- 5 V power supply (probably good to get in the habit of using this)
- Two network cables, or more if you want to share
- USB Oscilloscope (Digilent Analog Discovery)
- From the SE3910 Kit (Check out from Tech Support)
- Basic Proto Cape and the small breadboard (or, if available, BeagleBone Breadboard Cape)
- (optional) BeagleBone Breakout Board
- A few 1KΩ or 2.2 KΩ resistors (Exact resistance doesn't matter for this lab.)
- (optional) NMap/zenmap installed on your computer to scan for the BeagleBone
- Your BeagleBone black
If you have any difficulty with Linux, the VM, the Beaglebone, or Networking during this lab, check out the SE3910 Tips Page. (You may find these tips helpful even if you don't have any trouble.
Prelab
Read through the Lab Procedure. Do what you can without the check-out hardware.
This includes running the two example programs compiled differently for the VM and for the BeagleBone, recording the output, and reflecting on the differences.
This includes writing a network communication program in C, compiling it in your virtual machine (both regular and cross-compiled), and testing it either between two virtual machines, or between the BeagleBones, or some combination of these.
You may also wish to draw how you will wire your test circuits as part of the prelab. You can draw your circuits as they would appear on the Breadboard or BeagleBone Solderless Breadboard Cape. (The BeagleBone solderless breadboard cape is not available in every SE3910 check-out kit.)
Please demonstrate all your pre-lab accomplishments at the beginning of lab, and let me know any challenges you overcame in the process.
Cross Compiling with Eclipse
In this section, we compile a program using Eclipse rather than the command line. Many students find developing code in Eclipse to be more pleasant because of the syntax highlighting, error highlighting, etc. However, you are welcome to use the command line if you prefer.
We will also set up a remote connection to the Beaglebone through Eclipse. I am not sure whether this is actually more convenient or not. You may want to try it once, and then use whichever mode you prefer to deliver the code to the Beaglebone and execute it there.
Regardless which technique you use, be sure to compile the program and run it both on the VM and on the Beaglebone.
In the virtual machine, start eclipse under Linux using the command eclipse &
from the console, or Development->Eclipse from the Applications menu. Select a workspace that you would like to use, e.g., with File->Switch Workspace->Other.... Ideally this will be in the shared folder that you can access from both Windows and Linux. Recall these appear on the VM in the /media
folder. I use /media/sf_vmshare/workspace
. In Eclipse, select "File->New->Project" and "New C Project". Enter a project name of "Lab4Test". Click on next until you get to the Cross GCC Command screen. Enter the compiler prefix arm-linux-gnueabihf-
and the path /usr/bin
, then click "Finish".
Add a new C file to the project in the Lab4Test Source folder (File->New->Source File). Name the file test.c, and enter this code:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int bss_var; /* This is an uninitialized global variable. */ int data_var = 1; /* This is an initialized global variable. */ static int lv; static int lv2 = 1; int main(int argc, char* argv[]) { void *stack_var; /* This is a local variable declared on the stack.*/ char hostname[1024]; // This is an array declared Pon the stack which will hold the hostname. stack_var = (void*) main; printf("Hello World! Main is executing at address %p\n", stack_var); printf("This address (%p) is in our stack frame\n", &stack_var); printf("The printf function is located at location %p.\n", printf); /* The bss section contains uninitialzed data. */ printf("This address (%p) is our bss section\n", &bss_var); /* Data section contains initialized data */ printf("This address (%p) is in our data section\n", &data_var); /* This is a static variable which is uninitialized. */ printf("The address of the static variable which is uninitialized is %p.\n", &lv); /* This is a static variable which is initialized. */ printf("The address of an initialized lv variable is %p\n", &lv2); /* read the hostname. */ gethostname(hostname, 1024); /* Print out the hostname to the console.*/ printf("Hostname: %s\n", hostname); return 0; }
Save and build the code (Project->Build All). It should build cleanly. Goto the tool Window -> Show View -> Other -> Remote Systems -> Remote Systems. This will open up the Remote Systems tab. Right click on "Local" and select "New -> Connection". Select "Linux" and configure the connection with the IP address or domain name of your beaglebone (e.g. 192.168.1.100
) for both the "Host name," and the description. Remember that you cannot connect to your Beaglebone from the VM through the USB connection, so 192.168.7.2 will not work.
As you go through the remaining setup screens, set them up to match the images below:
Right click on the line with the Linux penguin you just created for your Beaglebone and click connect. Enter root
as the user id and no password. debian.
temppwd
as the password
With the connection made, select the built binary (Lab4Test->Binaries->Lab4Test, also available through Debug folder), right click, and select copy. Copy the binary to the remote machine (Under the remote machine, open Sftp Files, the My Home.) On the remote system, right click on Ssh Shells under the beaglebone machine and "launch shell". You should now be able to run the program on the remote machine. (Note: You may have to change permissions to allow you to execute the program. These were the permission commands talked about in operating systems. As a refresher, chmod u+x Lab4Test
is probably what you need.)
When the program runs, record the output including the various addresses for main, the stack, the bss section, and the data section. Also record the size of the executable file in bytes. (You can find this information by right-clicking on the file in Eclipse and looking at the properties, or by running the command du -b Lab4Test
Compiling for the VM
Now in Eclipse right click on the project (Lab4Test under Project) and select properties. Select the Tool chain editor (You can find by typing "tool chain" in the the search box), and change the current toolchain to LinuxGCC and hit OK. This will cause Eclipse to build for your Linux virtual machine instead of the Beaglebone target. Go to Project -> Build all to build your source code. Then, right-click on Lab4Test->Binaries->Lab4Test go to Run As -> Local C/C++ Application and execute the program. Record the addresses for main, the stack, the bss section, and the data section. Also record the size of the executable file. Write how they are different from what you recorded for the Beaglebone Black. If either the size or the addresses are not substantially different, please consult your instructor.
Once you are done with this, set your environment back to use the Cross GCC
. You can do this by going to the same properties dialog and reverting your changes: Under C/C++ Build->Tool Chain Editor, select Cross GCC, and under C/C++ Build->Settings, set the Prefix back to arm-linux-gnueabihf-
and the Path back to /usr/bin
(Sadly, this important prefix is cleared when you switch environments, so you must reset it every time you switch back to Cross GCC!).
Including libraries from Eclipse
If you need to link to a library for an Eclipse project, right click on the project and select Properties. Under C/C++ Build, select Settings. In the main window, under "Cross GCC Linker", select "Libraries." Add the library name here, without the lib prefix. For example, if you want to link against the pre-compiled library libm.m, only put m
for the library name, not libm
or libm.m
. For a full example of a program using the math library, see the appendix. Similarly, to link against libpthread.m, put pthread
rather than libpthread or libpthread.m
Measuring interrupt and network latency
In this part of the lab, you will create a system consisting of two Beaglebones connected by a network. When a button is pressed on the first BeagleBone, LEDs will light up on both the first and the second Beaglebone. The LEDs will turn on and off with several button-presses.
Source Code
As a team, split the two programs to be written between the two members of your team:
- Client. This program should create a TCP connection to the server. When a button is pressed, it should send a message to the server. It should also turn on an LED as mentioned above.
- Server. This program should accept a TCP connection from the client. When a message is received, based on the message received, it should turn an LED on or off.
For each program, the user should be able to specify as command-line arguments:
- How many button-presses the Beaglebone will respond to as a command-line argument. When run without arguments, the program should state whether this argument counts presses and releases together or separately. (In other words, if you accept an argument of 2, will the program respond to DOWN-UP and then be don, DOWN-UP-DOWN-UP and then done?)
- Which GPIO pin to use for input (or output)
- What IP address to connect to (for the client)
- What port to bind or connect to
- Anything else you find convenient
Create new C++ projects for the client and for the server. Both programs need to be written in C/C++ using the low-level Linux/C socket libraries.
Before you begin writing your programs, agree on a simple protocol that the two programs will use to indicate if the LEDs should be turned on or off. Both the server and client should exit cleanly once the agreed-upon number of iterations has been reached.
To test the programs before you get into lab, the client program should have a testing mode that sends the messages for button-down and button-up whenever the user presses ENTER. The server code should print out debug messages when it changes the state of the LED.
In writing the code for the client and server, these simple client.c and server.c files could be useful. Note that these programs are written in C, but you will probably need to translate them to C++ while working the lab. There are a few issues that come up when translating this code to C++. Please try to resolve the errors as they arise and ask your instructor if you have any questions.
As an example of responding to interrupts, see Derek Malloy's GPIO.h and GPIO.cpp, which provide a simple C interface to GPIO pins. Derek Malloy's GPIO needs to be linked against the pthread
library (in the same way the short example links against the m
library above.) This simple example demonstrating using it with interrupts: interrupt.cpp.
Wiring
When selecting GPIO ports, choose those in the range highlighted in the figure below. (Image compiled from images on ti.com and elinux.org)
See last week's lab for the formula needed to convert the numbers on the basic proto cape to the export pin numbers.
Connect an input switch to a GPIO input port as illustrated in the schematic below: (You may use any resistor over 1kΩ in both these circuits)
Connect an output LED to a GPIO output port as illustrated in the schematic below:
Note that these circuits are separate circuits — they don't share anything in common except the connection to digital ground.
Measure these signals:
- The button press
- A local GPIO port written right after the button press
- A remote GPIO port written right after the receive on the remote client
You will only be able to measure two signals at any given time. To measure both the button press and the remote GPIO port, you can wire up the system something like the figure below:
Determine the delay due to the interrupt response, and the delay due to sending a message over the network
On your printouts, clearly mark what each signal is. Is this the button-press, the output on the first BeagleBone, or the output on the second BeagleBone?
Staple the lab checklist to the top of your materials. Make sure the materials are in the order on the checklist. I will provide a printout of the checklist.
The deadline for the in-lab demo and lab packet is printed on the lab checklist.
No Excellent Credit This Week
You do not need to do any excellent credit activities this week.
Appendix: Compiling a project with dependencies
This section is purely optional.
In this appendix, we build an example program that serves as a calculator. This program requires some external libraries to be built successfully.
Create a new cross compiled C project called "Lab4Calculator" in Eclipse and download the tar file from the course website. Extract the source file calculator.c into the directory, and the source code should be included into your project (If it is not, manually create a new C file with any other name, and copy-paste the code from the calculator.c into this file. Delete any files that you don't want to later appear from your project folder.). Click on build and you should see the error messages shown in Figure 15. What kind of error is this message indicating?
To see the compile-time console output for a specific project, click on that project in the tab on the left.
Right click on the project and select Properties. Under C/C++ Build, select Settings. In the main window, under "Cross GCC Linker", select "Libraries. Add the "m" library. (As discussed in class, this will link against the pre-compiled library libm.m, but you only need to put "m" for the library name.) Rebuild the code and you should have a working calculator. Test the program on the BeagleBone using the techniques shown previously. Take a screen capture of your remote terminal session to the BeagleBone. (It's a litle flakey.)
Now that you have the program working on the BeagleBone, switch back to the command console and connect to the BeagleBone using the ssh command. (When not using putty, you should specify the username with @. For example: ssh root@192.168.1.100
). Verify that you can start the program from a plain console independent of Eclipse.