⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 无线传感器网络mica2平台下的增加串口调试源程序
💻 TXT
字号:
Tutorial of VDB


Lin Gu, Liqian Luo

Department of Computer Science

University of Virginia



 

Introduction

VDB is a wiring-free utility that help debug TinyOS programs. The best way to learn VDB is by examples. This tutorial provides several short examples with step-by-step descriptions. All the files used are in the shamrock package named "shamrock.tar.gz". This tutorial is applicable to Berkeley Mica2 platforms, like Mica2, XSM1, Exscal, etc.

In all the examples, we use the Surge application in TinyOS as a sample application. The Surge application is in the apps/Surge directory in the TinyOS source tree. The programs are tested on the Mica2 motes.


Example 1: printing debug information to the serial port (UART)

This example illustrates how to use "print" to print a string and four long integers on the VDB terminal.

0. Prerequisite: Make sure the TinyOS environment is set up correctly. 
For example, the TOSDIR environment is correctly set.

1. Copy the files vdbavr.inc, vdbavr.h into the Surge directory.

2. Use your favorite editor to edit SurgeM.nc. Modify it to include the "vdbavr.inc" file.
For example, add the following line at the beginning of the "implementation" block.

#include "vdbavr.inc"

3. In the "Timer.fired()" event, add a call to print() to print debug information to the UART.

For example, add the following line in Timer.fired(),

print("hello world", timer_ticks, TOS_LOCAL_ADDRESS, 0x200, 0x300);

4. Build the Surge application, and upload the Surge application to the mote.

For example, if using an MIB510 serial programming board, you may run the following command:

make mica2
make mica2 reinstall mib510

5. Copy the files VDBTerm.class and VDBTerm.java to a directory you choose, and configure the CLASSPATH environment variable to include that directory.

For example, if the files are copied to the tools/java directory in the TinyOS source tree, the following command line configures CLASSPATH accordingly (Usually /opt/tinyos-1.x/tools/java is in the CLASSPATH. If this is the case, just this).

In a Linux environment:
export CLASSPATH=$CLASSPATH:$TOSDIR/../tools/java

In Cygwin:
export CLASSPATH="$CLASSPATH;c:\Progra~1\cygwin\opt\tinyos-1.x\tools\java"

6. Run VDB terminal to display the debug output, specify the COM port if necessary (the default is COM1). 

For example, if you are using COM1, run the following command:

java VDBTerm

If you are using COM2, run the following command.

java VDBTerm COM2

The "hello world" message, as well as 4 numbers, should be displayed on the terminal. If the VDBTerm class does not run with the java VM in your system, rebuild the VDBTerm class from VDBTerm.java with "javac".


Example 2: Assert


The "assert" functions evaluate a boolean expression, and, like the semantics in many C++ libraries, abort the program if the boolean expression is false. This can be used as the most reliable way to debug a program, as illustrated in this example.

Task: Suppose you are skeptical whether the Timer.fired() event is fired. How can we debug it?

0. Prerequisite: Make sure the TinyOS environment is set up correctly. 
For example, the TOSDIR environment is correctly set.

1. Copy the files vdbavr.inc, vdbavr.h into the Surge directory.

2. Use your favorite editor to edit SurgeM.nc. Modify it to include the "vdbavr.inc" file.
For example, add the following line at the beginning of the "implementation" block.

#include "vdbavr.inc"

3. In the beginning of Timer.fired(), add the following line:

assert(0);

The function assert() accepts a boolean expression as its parameter. Here the boolean expression is "0". Hence, it always evaluate to false when this sentence is executed. When the boolean expression evaluates to false, the program aborts and all the LEDs are turned on to indicate an abnormal situation.

4. Build and upload the Surge application. When the application runs, all the LEDs should turn on. This indicates that Timer.fired() event has been executed.

5. Sometimes we want to assert some situations in several places and, when one of the situations does not hold, know which assertion has failed. This is the place assertNum() can coem to help. It accepts a boolean expression as well as a number from 0 to 7. When the boolean expression is false, the LEDs show the number.

As an example, modify "assert(0);" to be 

assert((1+1)==2);

and add another line 

assertNum((1+1)==100, 5);

near the end of the Timer.fired() event, before the "return SUCCESS;" statement. 

Again, build and upload the Surge application. This time, the first assertion at the beginning of Timer.fired() evaluates to true, hence it does not stop. The second assertion (assertNum) evaluates to false, the program stops there and the LED shows 5 (the red and yellow LEDs are on).

Example 3: Use the in-chip 4KB EEPROM


This example illustrates how to use "logEepromByte/readEepromByte" to write to and read from the in-chip 4KB EEPROM.

0. Prerequisite: Make sure the TinyOS environment is set up correctly. 
For example, the TOSDIR environment is correctly set.

1. Copy the files vdbavr.inc, vdbavr.h into the Surge directory.

2. Use your favorite editor to edit SurgeM.nc. Modify it to include the "vdbavr.inc" file.
For example, add the following line at the beginning of the "implementation" block.

#include "vdbavr.inc"

3. At the beginning of the "Timer.fired()" event, add the following code:

{
char c;

c = readEepromByte(2000); // read from EEPROM address 2000
logEepromByte(2000, c+1); // write to EEPROM address 2000 with c+1 (increment it)
print("Current EEPROm value", c, 0, 0, 0); // show the result
}


4. Build the Surge application, and upload the Surge application to the mote.

For example, if using an MIB510 serial programming board, you may run the following command:

make mica2
make mica2 reinstall mib510

5. Copy the files VDBTerm.class and VDBTerm.java to a directory you choose, and configure the CLASSPATH environment variable to include that directory.

For example, if the files are copied to the tools/java directory in the TinyOS source tree, the following command line configures CLASSPATH accordingly (Usually /opt/tinyos-1.x/tools/java is in the CLASSPATH. If this is the case, just this).

In a Linux environment:
export CLASSPATH=$CLASSPATH:$TOSDIR/../tools/java

In Cygwin:
export CLASSPATH="$CLASSPATH;c:\Progra~1\cygwin\opt\tinyos-1.x\tools\java"

6. Run VDB terminal to display the debug output, specify the COM port if necessary (the default is COM1). 

For example, if you are using COM1, run the following command:

java VDBTerm

If you are using COM2, run the following command.

java VDBTerm COM2

The current value of the byte at EEPROM address 2000 should be displayed on the terminal. If you restart the mote, the sequence continues since the EEPROM is a nonvolatile stoarge, hence its values are kept acrose the restarts of the mote.

If the VDBTerm class does not run with the java VM in your system, rebuild the VDBTerm class from VDBTerm.java with "javac".

Example 4: stack boundary checking

This example illustrates how to use the stack checking functions to examine the state of the stack boundaries. This is important for programs with a big memory footprint when the stack growth may invade and contaminate the program's global data storage.

Prerequisite: Make sure the TinyOS environment is set up correctly. For example, the TOSDIR environment is correctly set.


Copy the files vdbavr.inc, vdbavr.h into the Surge directory. 


Use your favorite editor to edit SurgeM.nc. Modify it to include the "vdbavr.inc" file.
For example, add the following line at the beginning of the "implementation" block.

#include "vdbavr.inc"


At the beginning of the "Timer.fired()" event, add a call to isStackBelow() to check whether the stack's lower boundary is lower than a certain address. For example, add the following sentense. 

if (isStackBelow(0x1100)) assert(0); 

or, equivallantly, 

assert(!isStackBelow(0x1100));

Compile and upload the Surge application. Most likely, the three LEDs should all turn on. The reason is that 0x1100 is beyond the 4K address space. Hence the stack pointer is always below that address. The purpose of using 0x1100 is to reliably show how the use of the isStackBelow() function can detect a wrong stack state. In real applications, you want to change 0x1100 to a value that suits your application.


Now, let's try a more reasonable setting. When you use "make mica2" to build the Surge application for Mica2, NesC probably reports a RAM usage of about 1.9K bytes (You should see a message like "19xx bytes in RAM"). This is the heap area that the application uses. The stack on the Mica2 platform (ATmega128 processor) grows downward. Hence, the stack pointer should not be as low as close to 1.9K. Considering that the real RAM's address is from 0x100-0x10ff, we have reasons to believe, approximately, the stack pointer should be above 0x900. Otherwise, there is a danger that the stack may invade the heap. Therefore, at the beginning of the "Timer.fired()" event, we can add the following sentense. 

assert(!isStackBelow(0x900));

or, equivallantly, 

assert(isStackAbove(0x900));

Compile and upload the Surge application. Most likely, the application should run well, since the stack should not grow downward beyond 0x900 in healthy situations.


If you would like to know what the exact value the stack pointer is, getSP() comes to help. At the beginning of the "Timer.fired()" event, add the following sentense. 

print("SP is", getSP(), 0, 0, 0);

Compile and upload the Surge application. The application should print out the stack pointer's value in each timer event. Using VDBTerm, as described in examples above, you can display the output. 


Limitations and caveats:


1. Like most of the debugging tools, VDB changes the timing of the running of the program.

2. If the application uses UART, print() should be used very cautiously. Otherwise, there may be a conflict on the UART operations.

3. If the application does not use the GenericComm/GenericCommPromiscurious components, and there is no handler for UART interrupts, the macro NO_COMM must be defined so that the vdb handles the UART interrupt. Note that, though any multiple modules can include "vdbavr.inc", only one can have NO_COMM defined.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -