Introduction

Bruce Land developed CodeVision 1.24.6 Debugger for Atmel Mega32 microcontrollers, a debugger which allows a user to link with a target program on a MCU, determine the program's state, and make changes. The program includes commands to read/write I/O registers, data registers, memory, and to determine the locations of the Codevision data stack and hardware stack. This program required using a communication program, such as HyperTerminal, to connect to the MCU and manually enter the commands. A simplified interface was desired so that the program could be more easily used by the ECE 476 Microcontrollers course. This program is an attempt to provide such an interface. Additional features, such as reading compiler generated .map file and printing, were added to the program to make it easier for the user to make sense out of the state of the target program.

Requirements
Create a UI to connect with and make available all functionality available in CodeVision 1.24.6 Debugger for Atmel Mega32 microcontrollers.  The debugger will still be run on the MCU.

Software Design

1) Information To Display
Data Registers - Value, Variable, Byte Location, Full Value of Variable, Type
I/O Registers - Value, Variable
MCU Info - Value of MCU Status Register, Location of Top of Data Stack, Location of Top of Hardware Stack
Memory - Value, Variable, Byte Location, Full Value of Variable

where:
Value - Retrieved from MCU
Variable - Name of variable corresponding to the data location in the loaded map file (see below)
Byte Location - Location of the byte in the variable in the loaded map file. A variable that is only one byte long will have a byte location of 1.
Full Value of Variable - If part of a variable, this is the entire value for the variable. This combines all the values for the different bytes of the variable. A single byte variable will have the same data for value and full value of variable.
Type - Type of data register (Global, Local, or State Info) as listed in datasheet.

2) Programming Language
Visual Basic .Net was selected as the programming language for this project. This program will hopefully be used by future ECE 476 classes, which may require maintenance or changes to the source code. Bruce Land is the instructor for the course and will lead any of the efforts to make changes to this program. He indicated that Visual Basic would more easily allow him to maintain the software. I have past experience in Visual Basic, so I was not against using the language. The advantages of Visual Basic are that it is a fairly easy language to learn and use to create a User Interface.

3) UI Design
The UI is a balance between displaying as much MCU data as possible while keeping the program easy to use. The list view on the left-hand side of the screen enables the user to quickly view different data storage types in the list view on the right-hand side. Scrollbars on the side prevent having to display all the information on the screen at once. The buttons on the left provide easy access to the functions relating to the MCU. The menu bar at top includes functions which do not require communication with the MCU.


Program Screen Shot

4) Communicating With MCU
Visual Basic enables access to unmanaged functions that are stored in external files. I declared reference to the communications procedures included in Kernel32.dll. These functions enabled the program to set the serial connection properties, and read/write to the port. The problem with these functions is that reading from a port required knowing how many bytes would be sent. The functions are blocking and will wait until enough bytes are received. Data received from the MCU is variable in size and that size can not always be predicted. I had to enable timeouts to prevent needing to know how many bytes will be received. Each stream of data received will read the bytes off the port until it times out while waiting for the next byte. I adjusted the settings to reduce the time out as much as possible while preventing slight delays in transmission times from being interpreted as time outs. The status of the MCU (debug mode, running mode, or power off) can change without any notification to the program. For that reason, the connection is re-established each time the program communicates with the MCU.

After receiving the data from the MCU, I parse out the data based on the expected data form of [i,r,or m] address value. The syntax for sending and receiving data from the MCU was taken from Bruce Land's debugger documentation.

5) Reading MAP File
The CodeVisionAVR Compiler generates a .map file which indicates the locations of all variables used by the target program. This locations are needed to debug the target program. In the program I created, the user has the ability to load a map file. Loading a map file allows the program to display the variable names for the data registers and memory. It is slow to display and read the data values for memory, so loading a map files enables the user to only read/display the memory locations used by the map file.

The FileStream and StreamReader classes were used to read the contents of the map file. StreamReader allows the map file to be read a line at the time. The program assumes that the map file is structured as shown below. First the program reads until a line is found that begins with "variable". Next the program reads an arbitrary number of spaces. Then the address is either registers seperated by commas or a single base memory location. The program reads an arbitrary number of spaces again and then reads the size of the variable. The program is not guaranteed to do anything unless the map file is correctly structured.


Example .MAP File

6) Printing
I thought it would be a nice feature to be able to print out the information retrieved from the MCU. Visual Basic does not have any include any helper libraries to simplify pritning. Each printed page has to be manually created and then sent to the printer. The Visual Basic printing event triggers printing and the property HasMorePages manually indicates when there are more pages to print. The first printed page is the data registers. Data registers did not take up the entire page so I also included the MCU state information. The next page is the I/O registers. I/O registers are only one byte long so some of the columns of the other data types did not need to be included, allowing two columns of I/O registers (all 64 I/O registers) to be printed on the page. All other pages contain the memory information. To save trees, only the memory locations used by variables in the map file are printed.


Sample From Print Out

7) Config File
I wanted the program to be distributed by a single file, the program's binary. However, I wanted changes to the communications port number and I/O register to be saved. When any configuration changes are made, I save them back to a config file. If the config file does not exist when the program is run, a new config file is automatically generated with the default I/O register names and comm one as the communication port. The config file is an XML file so that the data can be stored in a readable manner and standard classes can be used to the read the file.


Sample from config file

Results

1) Speed
The program takes approximately 42 seconds to read all values from memory and 3 seconds to read all values from the registers. A feature was added to only read values from memory locations used in the map file to prevent having to read all of memory. Based on only the speed of the communications port, the program could take only 25 seconds (2048x30x8/19200). The reason this speed was not achieved is discussed above. A status bar is displayed on the screen when reading from memory to indicate the overall progress of the read.

2) Resources
The program is not CPU intensive as there are only short bursts of CPU usage. The program uses about 14MB of memory at startup and after use can reach usages of about 24MB. Resource usage is not great enough to cause computer performance issues. Threads are used to read from the MCU to allow the program to be minimized while the data is being retrieved.

3) Accuracy
This program has been tested using the example target programs available on the Cornell University ECE 476 website. For all programs, this debugger program produces the same output as the debugger created by Bruce Land. Since I did not fully test Bruce Land's program, I can only state that this program produces the same output but will make no claim on the accuracy of both programs.

4) Safety
No damage to any microcontrollers has been experienced while testing the program. I have also not experienced any problems switching from debug mode back to running the target program. However, I do not guarantee that there will never be any damage to the microcontroller while using this program.

5) Usability
Use of the program by students in next semester's ECE 476 course will determine if the goal to provide an easy to user interface was accomplished.

Conclusions

The program performs all the required functionality and should be easy enough for future generations of students to use. Testing took up the majority of time during development of the program. Other than getting used to Visual Basic, there were no major difficulties in development.

All the source code was written by myself and time was taken to document the code and make it easy to read. This should enable easier maintenace of the program.

Source Code/Binary

Most current version is available for download at: https://gforge.cis.cornell.edu/projects/mega32debug/. This document, the user manual, and the source code in PDF form is also available on the site.