Archive for the ‘software’ Category

Sharkfest ‘08 Conference for Wireshark

Monday, April 7th, 2008

sharkfest logoI was invited to attend Sharkfest ‘08, a conference for Wireshark users and developers, held March 31-April 2 at Foothill College in Los Altos Hills, California. I had a great time, and am so grateful that Gerald invited me to attend. I attended as a Wireshark developer since I actively maintain the BACnet dissector. I went to the conference with several goals in mind:

  1. Figure out how to do BACnet segmentation
  2. Figure out how to get BACnet MS/TP into libpcap/winpcap.
  3. Add a couple of BACnet dissector enhancements to Wireshark.
  4. Learn about using Wireshark for problem network analysis.

I attended Laura Chappell’s training sessions, and learned a whole lot about Network analysis and the love-hate relationship between TCP/IP SYN, ACK, and Keepalives (#4 completed). I also wrote some Wireshark code during the classes which I promply submitted (#3 completed). Loris came into the activity center and sat down with my son Joshua and me, and so we discussed how to integrate BACnet MS/TP RS485 from serial port into libpcap/winpcap (#2 completed). On the last day and the last session of the conference, I attended a session by Richard Sharpe about file sharing protocols and learned about Wireshark conversations (#1 completed).

Vint Cerf and Gerald CombsWe were treated to an inspiration talk on Tuesday morning by Vint Cerf. After the talk, I went to Laura’s session, and Joshua talked to Vint. Vint signed Joshua’s Half-Life player guide, had photos taken with Vint and Gerald, and the Wireshark crew gave Joshua some swag.

Gerald treated the developers to dinner on Tuesday night at Trader Vic’s. I drove to dinner with Joshua and Jaap Keuter, and learned about PBX systems and Jaap’s passion for skydiving. At dinner I sat next to Ulf Lamping and learned about yet another division of Siemens and about Ulf’s love for motorcycle riding. Guy Harrris and Mike sat across from me.  Joshua ate with Gerald’s wife and daughter, and John Bruno’s wife.

The Foothill College campus was beautiful and on Spring Break. The food was awesome and plentiful.  The people were great!  The Wireshark sessions were helpful.  Maybe I will get to attend next year.

Read the Fine Manual or Datasheet

Sunday, March 30th, 2008

I found a bug in my Atmel AVR ATmega168 port of the BACnet Stack at SourceForge. It was the result of having not read the AVR datasheet close enough. Here is what the datasheet said:

The Transmit Complete (TXCn) Flag bit is set one when the entire frame in the Transmit Shift egister has been shifted out and there are no new data currently present in the transmit buffer. The TXCn Flag bit is automatically cleared when a transmit complete interrupt is executed, or it can be cleared by writing a one to its bit location.

SAGE_Instruction_Counter.JPGI had initially written the code to clear the TXC0 flag by clearing it, rather than setting it. Since the code could not determine when the end of the transmission occurred, I had added a _delay_us() function from the AVR-GCC library. This is what the AVR-GCC manual says about that function:

In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application.

ENIAC_tubes.jpgSevere code bloat indeed! I had used a non-constant (the Baud Rate) in the delay call, and that resulted in a 4k increase in code size. After fixing the Transmit Complete flag functionality, I was able to remove the _delay_us, and the code size dimimished by 4k. On this 16k device, that means alot!

Statistics for the BACnet Stack at SourceForge on the ATmega168 are as follows:

IAR Atmel AVR C/C++ Compiler V5.10A/W32
10 191 bytes of CODE memory (+ 36 range fill )
775 bytes of DATA memory (+ 24 absolute )

avr-gcc (GCC) 4.2.2 (WinAVR 20071221rc1)
Program: 12052 bytes (73.6% Full)
Data: 481 bytes (47.0% Full)

With all the extra code space, I went on to add more functionality to the demo. The BACnet capabilities include WhoIs, I-Am, ReadProperty, and WriteProperty support. The BACnet objects include a Device object, 10 Binary Value objects, and 10 Analog Value objects. An LED is controlled by Binary Value object instance 0. All required object properties can be retrieved using ReadProperty. The Present_Value property of the Analog Value and Binary Value objects can be written using WriteProperty. The Object_Identifier, Object_Name, Max_Info_Frames, Max_Master, and baud rate (property 9600) of the Device object can be written using WriteProperty.

After adding all that functionality, I learned the hard way about the C-Stack differences between the IAR AVR compiler and the GCC-AVR compiler. The IAR compiler uses a fixed CStack size. If it is not set correctly, the CStack can overflow and cause problems in your code.

Johnniac.jpgThe GCC compiler uses the RAM not allocated to variables and text for the C-Stack. That means that the data value reported by the avr-size program is only part of the picture. If the data value is 481 bytes, and the device has 1024 total, then 1024-481=543 bytes are used by the C-Stack. In other words, don’t be fooled by the “47% Full” printed by avr-size and think that you have extra RAM. You might be able to add some more functionality, but certainly leave some RAM (or alot in my case) for the C-Stack. The GCC-AVR has two intrinsic variables for tracking the C-Stack: _end and __stack. These can be used to paint the C-Stack prior to its usage, and monitor the C-Stack during runtime. I added this technique to the demo.

The final statistics on ATmega168 demo of the BACnet Stack at SourceForge:

IAR Atmel AVR C/C++ Compiler V5.10A/W32
12 732 bytes of CODE memory (+ 36 range fill )
955 bytes of DATA memory (+ 24 absolute ) (CStack=0×200)

avr-gcc (GCC) 4.2.2 (WinAVR 20071221rc1)
Program: 15790 bytes (96.4% Full)
Data: 414 bytes (40.4% Full) (CStack=0×262)

Note: The photos are ancient computer memory from The Computer History Museum in Mountain View, California.  I’m visiting the area for the Wireshark Sharkfest ‘08.

C/C++ Compiler Macros

Tuesday, November 27th, 2007

cityscape_night.pngEvery once in awhile, I need a macro to work around a difference in a C compiler.

For example, not every compiler for the Win32 platform has implemented C99 integer and boolean types, so I have stdint.h and stdbool.h files. Fortunately, The Open Group maintains an online definition for stdint.h and stdbool.h so I don’t have to guess about what is supposed to go in there. C99 also defines some new keywords: restrict, inline, _Complex, _Imaginary, _Bool. Since _Bool is used by stdbool.h, it may or may not have been defined by the compiler. What I needed was a macro defined by the compiler that tells me which compiler it is so I can avoid compiler warnings.

Digging up the compiler macros on the internet can be challenging. However, there is a nice project at SourceForge to track Pre-defined C/C++ Compiler Macros.

That makes things a whole lot easier!

Using GCC for ARM7 or AVR

Monday, September 3rd, 2007

Inspired by Building Bare-Metal ARM Systems with GNU series of articles, I recently ported the BACnet MS/TP datalink layer to an Atmel AT91SAM7S-EK board - an ARM7 processor - using a GCC cross compiler for ARM.

I evaluated GNU Toolchain for ARM, GNU ARM, WinARM, and YAGARTO toolchains on the Windows platform. They all have their merits, but all have some slight differences too. I followed an excellent tutorial by James P. Lynch called Using Open Source Tools for AT91SAM7S Cross Development to get me up and running quickly. Jim used the YAGARTO project as his toolchain.

I used the YAGARTO toolchain and created my own Makefile. Makefiles are an interesting bit of programming that seems to be a lost art. Any of the cross compiler toolchain builds should work with the Makefile with a slight modification to the name of the compiler (one of the differences in each of the various GNU ARM cross compiler projects).

During my travels down the GCC road, I found the GCC-AVR and WinAVR for Atmel AVR series of microcontrollers. I searched for GCC for an 8051. I found the SDCC project - Small Device C Compiler - for Intel 8051, Maxim 80DS390, Zilog Z80 and the Motorola 68HC08. Both projects are also in the Ubuntu Linux repository.  I noticed that the Microchip PIC24 compiler C30 is based on GCC and the source code is available on their website.

Quiet Surroundings without Distractions

Monday, April 2nd, 2007

QCAD and DXF drawing of a pumpI found Technical Drawing, Fifth Edition, by Giesecke, Mitchell, Spencer, and Hill, at a local Goodwill store. It is a wonderful book for those who want to learn about drafting. It is also great for woodworkers since it contains a detailed chapter on Geometric Constructions. It is great for graphic artists as it describes how to construct a large number of geometric shapes. However, the gem that I found that relates to software engineering comes from the beginning of the book in Chapter 2, section 2.3:

2.3 Drafting at Home or School. If a draftsman is to turn out drawings rapidly and accurately, he must work in quiet surroundings without distractions. Technical drawing requires headwork, and the draftsman who is whistling, singing, talking, eating, or smoking, is probably “pushing the pencil” without much mental activity behind it.

Someone knew the secret in 1967, the date the book was published, of how to get headwork done. The same technique for reducing interruptions applies to software engineering. We could say:

If a software engineer is to produce software rapidly and accurately, he must work in quiet surroundings without distractions. Software engineering requires headwork, and the engineer who is whistling, singing, talking, eating, or smoking, is probably “pounding the keyboard” without much mental activity behind it.

I think Joel had this concept of quiet surroundings right when he designed the Bionic Office. Peopleware also came to this same conclusion.

Daylight savings time

Monday, March 12th, 2007

Nightstand and alarm clockIt’s that time of year again. Time to spring forward. Well, not exactly the same time as last year. The formula for daylight savings time changed for this year. That meant that I had to rewrite firmware that used daylight savings time. According to Wikipedia,

Beginning in 2007, DST will start on the second Sunday in March (March 11, 2007), and change back to standard time on the first Sunday in November (November 4, 2007). Under Section 110 of the Energy Policy Act of 2005, the U.S. Department of Energy is required to study the impact of the DST extension no later than nine months after the change takes effect. Congress has retained the right to revert to the DST schedule set in 1986 if it cannot be shown that there are significant energy savings from an extension of DST or if the extension may prove to be unpopular with the American public. One potential issue is that some northern regions on the western edge of time zones will for the first time since the 1974-75 “almost year round” DST experiment have sunrise times that occur after 8am.

In two of my controllers I use, the built in hardware clock of the PC/104 card automatically handles the daylight savings time change. I simply set a bit and it would automatically spring forward or fall back. Well, almost. One of the controllers used a realtime clock chip by Odin which didn’t come out of daylight savings time and got stuck at 1am on the last Sunday of October. Since I could no longer utilize the hardware clock, I had to handle the daylight savings time change in software. There were two cases that I needed to cover. The first case is handling the timer interrupt and springing forward one hour or falling back one hour. The timer interrupt code turned out to be much simpler than I first thought. It is a good thing to be simple in an interrupt. Here is part of the code:

  1. if (data.tm_year >= (2007-1900)) {    /* begin DST - Second Sunday in March */    /* ANSI is months since January */    if ((data.tm_mon == 2 /*March*/) &amp;&amp;        (data.tm_wday == 1 /*Sunday*/) &amp;&amp;        (data.tm_mday >= 8) &amp;&amp; /* second Sunday */        (data.tm_mday <= 14) &amp;&amp;        (data.tm_hour == 2) &amp;&amp; /* 2:00 am */        (data.tm_min == 0) &amp;&amp;        (data.tm_sec == 0)) {        /* do something here */         }}

The second case was to determine if the date and time was during daylight savings time or not. This is used when the date and time get set on the controller, and to display the daylight savings time status. The code is more complex than the interrupt routine. Here is part of the code:

  1. if (year >= 2007) {    /* simple bounds check */     if ((month >= 3) &amp;&amp; (month <= 11)) {        /* get the start date for DST - Second Sunday in March */         if (month == 3) {            for (i = 8; i <= MonthDays(month,year); i++) {                if (DayOfWeek(DaysSinceEpoch(year,month,i)) == SUNDAY) {                    if (day == i) {                        time_now = TO_SECONDS(hour,minute,second);                         time_dst = TO_SECONDS(3,0,0);                         if (time_now >= time_dst) {                            dst = true;                        }                    } else if (day > i) {                        dst = true;                    }                     break;                }            }        }    }}

Testing the Daylight Savings Time algorithm was fairly routine using Unit Testing:

  1. void testDaylightSavings(Test* pTest){  /* original DST */  ct_test(pTest, IsDaylightSavings(31,12,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(26,10,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(25,10,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(10,7,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(6,4,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(1,4,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(1,1,2003) == FALSE);  /* new for 2007 DST */  ct_test(pTest, IsDaylightSavings(1,1,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(3,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(7,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(8,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(9,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(10,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(11,3,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(10,7,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(3,11,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(4,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(7,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(8,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(30,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(31,12,2007) == FALSE);
  2.  
  3.   return;}

Hope you are getting used to waking up earlier!

Removing Airplane Window Haze

Monday, February 19th, 2007

I like to take photographs of the earth while traveling in airplanes. Usually the passenger windows have a bit of a haze to them. I use The GIMP to get rid of the haze. Tools->Color Tools->Levels.

gimp_adjust_color_levels.jpg

I normally only have to use the Auto button. Sometimes I have to change an individual channel. Sometimes I can set the Black Level or White Level by selecting objects in the photograph. Sometimes I just move the little triangles under the histogram. The left triangle should be just at the start of the left side of the histogram. The right triangle should just be at the end of the right side of the histogram. The middle triangle adjusts the gamma value.
IMG_3090.JPG Before Adjusting Levels

Image above before adjusting levels. Image below after auto adjusting levels.

IMG_3090.JPG After Adjusting Levels

Linux in-flight entertainment

Thursday, October 19th, 2006

Linux entertainment LCD touch screen in every headrest of a Song airline 757.I traveled to Phoenix this week to give a BACnet and Lighting Applications presentation to the NEMA JSC on DALI. I flew there aboard a Song Airlines 757. During the powerup sequence for the plane, all the passengers were greeted with the image of Tux and the Linux boot sequence as the in-flight entertainment system in each headrest initialized. The touch panel color LCD screens provided games, movies, music, flight information, and satellite television. During the 3 hour flight, I watched Fox News, Mythbusters on Discovery, TLC, and Sunday night football. I also listened to some Ramones and The Smiths. I played trivia with other passengers - I came in 3rd place out of 3 players. I normally dread longer flights, but having satellite TV and Linux serving up entertainment really made the trip go by quickly.

BACnet Plugfest Complete

Friday, October 6th, 2006

Today was the final day of the BACnet Interoperability Workshop, or Plugfest as it is commonly called. Over the two and a half days we found only two bugs in the open source BACnet stack at SourceForge that I ported into our lighting panel in 5 days. I fixed both bugs in a few minutes and uploaded the firmware into the lighting panels using the in-circuit-debugger. The fixes were verified by the other vendor.

BTL Plugfest - Lighting panels and laptops

The MS/TP state machine worked. We tested it at 9600 baud, 19200 baud, and 38400 baud and worked fine. 76800 baud did not work, so I will need to figure out why. I may need to clock the processor at 40 MHz instead of 20 MHz to get some extra horsepower. I will also need to optimize the other processes, like the input reading and debouncing, to take less time in the main loop.

Lithonia Lighting and Loytec testing BACnet and DALI and LON.

The food was great and I met a lot of nice folks. Hopefully my flight home tomorrow will be uneventful.

Random Photos

Sunday, June 4th, 2006

Random photos and random music have different user expectations than what a random number generator provides. If I am listening to a bunch of songs on an MP3 player at random on a long airline flight, I don’t expect to hear the same song again until I have heard all the songs at least once in a random order. If I have desktop wallpaper displaying at random, I expect to see all the wallpaper in my list of wallpapers at least once before I see the same wallpaper again.

Pinwheel

So why don’t programmers in the photo display and music playing arenas meet the user expections? I suppose it is significantly easier to write the code using “x = random()” than it is to actually keep track of which photos have been seen or which music has been heard. Or perhaps they are just unaware of the user expectations.