Monday, September 27, 2004
How to Build an Application
Digi's implicit assumption is that you will go through the example programs under netos60_gnu/src/examples, find one that approximates your needs, and cut&paste the appropriate code into your own app. If you have any questions, you can always read the source, post to support forums or ask tech support. There is help - quite a big help file - but it is a typical reference document. That is to say, if you already know the answer, you can learn the details, but if you don't even know the question yet, you are SOL.
In addition to my core logic, my application needed telnet code (from example project natelserl), ftp code (from example project naftpapp) and raw socket access (from example project nafsockapp).
There is no facility in the standard libraries to reload code. You must include some method of updating code in your application. I use ftp, but tftp and http are both possibilities. If you ever load code with a dysfunctional update method into a ConnectMe, you have just made that ConnectMe into an OTP device.
War Story: After putting all the elements together, the ftp service didn't work. At this point, I really wasn't clear on the memory map so it was tough to know how things were failing. But they were failing. After (only) one sleepless night, I found that the ftp service needs nearly exclusive CPU access. After putting in handshake logic to idle the other threads when FTP was active, the application started working like a champ.
Hint: The FTP service has a nasty quirk. Unless your code ends on a segment boundary, there will always be some bytes left in buffer when the ftp client says "download complete." the ftp library will not write those dangling bytes to Flash until the ftp client disconnects ("bye"). So if you do what comes naturally and cycle power when the PC says "download complete" you will have a ConnectMe with a corrupt Flash image. When updating code via FTP, ALWAYS type "bye" and wait at least 30 seconds before removing power.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
In addition to my core logic, my application needed telnet code (from example project natelserl), ftp code (from example project naftpapp) and raw socket access (from example project nafsockapp).
There is no facility in the standard libraries to reload code. You must include some method of updating code in your application. I use ftp, but tftp and http are both possibilities. If you ever load code with a dysfunctional update method into a ConnectMe, you have just made that ConnectMe into an OTP device.
War Story: After putting all the elements together, the ftp service didn't work. At this point, I really wasn't clear on the memory map so it was tough to know how things were failing. But they were failing. After (only) one sleepless night, I found that the ftp service needs nearly exclusive CPU access. After putting in handshake logic to idle the other threads when FTP was active, the application started working like a champ.
Hint: The FTP service has a nasty quirk. Unless your code ends on a segment boundary, there will always be some bytes left in buffer when the ftp client says "download complete." the ftp library will not write those dangling bytes to Flash until the ftp client disconnects ("bye"). So if you do what comes naturally and cycle power when the PC says "download complete" you will have a ConnectMe with a corrupt Flash image. When updating code via FTP, ALWAYS type "bye" and wait at least 30 seconds before removing power.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Wednesday, September 22, 2004
How ConnectMe Boots
When a ConnectMe boots up, it first executes the Boot Loader. I have described that piece of code in another entry. When the Boot Loader executes your application, here's what happens:
The first code that executes is netos60_gnu/src/bsp/arm7init/INIT.s, which is part of libbsp.a (see "How Stuff is Arranged in Flash" 21Sep04). Branching from there, the BSP sets up the board and all the standard libraries. It finally calls your application's applicationStart() function from netos60_gnu/src/bsp/common/bsproot.c. Your app then sets up its own threads. After applicationStart() returns, execution passes to an idle task, and the ConnectMe is basically dead except for your application's threads.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
The first code that executes is netos60_gnu/src/bsp/arm7init/INIT.s, which is part of libbsp.a (see "How Stuff is Arranged in Flash" 21Sep04). Branching from there, the BSP sets up the board and all the standard libraries. It finally calls your application's applicationStart() function from netos60_gnu/src/bsp/common/bsproot.c. Your app then sets up its own threads. After applicationStart() returns, execution passes to an idle task, and the ConnectMe is basically dead except for your application's threads.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Embedded Development vs. Linux
Since starting my own consulting operation, I've been trying to do everything in Linux. KDE and Star Office make it possible to work in Linux at the office and document level (my desktop PC has 512 MB RAM and runs at 1GHz), but embedded tools are distressingly Windows-centric. I can't even inspect the files on the NetOS development kit CD using Linux because they are packaged as a self-extracting Windows executable. The exec won't open with wine because it is bigger than my system RAM (haven't tried increasing swap space).
I solved that by running the tools on my laptop (486, 64MB, Win2kPro). I loaded the development kit CD onto the laptop, and set up FTP and Telnet servers on the laptop. I used FileZilla for ftp and CygWin for telnet. Here's the command to start a telnet server on a cygWin equipped Windows box:
/sbin/inetd --install-as-service
So then I fixed up the Makefile on my Linux desktop system to ftp changed files to the Windows laptop. With a telnet session still active in another window, I could compile, load and debug from the laptop without losing the context of my desktop, with all the editors, data sheets and explanatory emails I could cram onto the screen. It really was a nice setup, and I'd recommend it to anyone.
Another advantage was I could take my laptop out to the field, tweak the code, and synch with the desktop on returning home.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
I solved that by running the tools on my laptop (486, 64MB, Win2kPro). I loaded the development kit CD onto the laptop, and set up FTP and Telnet servers on the laptop. I used FileZilla for ftp and CygWin for telnet. Here's the command to start a telnet server on a cygWin equipped Windows box:
/sbin/inetd --install-as-service
So then I fixed up the Makefile on my Linux desktop system to ftp changed files to the Windows laptop. With a telnet session still active in another window, I could compile, load and debug from the laptop without losing the context of my desktop, with all the editors, data sheets and explanatory emails I could cram onto the screen. It really was a nice setup, and I'd recommend it to anyone.
Another advantage was I could take my laptop out to the field, tweak the code, and synch with the desktop on returning home.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Tuesday, September 21, 2004
How Stuff Is Arranged In Flash
It took a while to figure this out. As far as I know this is not documented by Digi. I kinda think their tech support guys think it's obvious, but like I say, it took me a while to figure it out. While I was able to write my source without this knowledge, I could not understand the instructions for loading code into a non-JTAG target until this picture formed in my head.
=============================================
Memory Top
NonVolatile Memory
Flash File System (if compiled into application)
User Application (includes BSP)
-----
Boot Loader
Memory Bottom
Maybe someday I'll draw a real picture. For now, the outline above will do.
In the original ConnectMe, the Boot Loader was not user accessible. It is, however, built by the Development Kit (DK) along with the Board Support Package (BSP). In the latest DK, the boot loader image is linked as:
netos60_gnu/src/bsp/bootloader/romImage/rom.bin
In the original ConnectMe, everything above the dashed line is changeable, but everything below the dashed line is locked. So, you cannot change the boot loader (or can you...). Changing the boot loader would be convenient because it kinda sucks. When the system boots, the boot loader does a sum check of the code in application space. If good, the boot loader jumps to that code. If bad, the boot loader attempts DHCP; if that works, then it tries to bootp a new image from the DHCP server. I have not verified this part experimentally, but I have read that the bootp will only be attempted from the successful dhcp server. There is no way to escape to the boot loader on reset, or from the application; therefore, if you load code into the ConnectMe that satisfies the boot loader's sumcheck, but makes the thing continually reset, you have just wasted a ConnectMe.
The BSP source ends up as:
netos60_gnu/lib/32b/libbsp.a
and is linked into the Boot Loader as well as into your application. That took a while for me to verify - the BSP is linked into my app, as opposed to residing in system Flash like some kind of BIOS. Again, when I verified this observation with Digi Tech Support, they just said, yeah, how else would it be done?
Your application is compiled to image.elf (JTAG/gdb image) and image.bin (Flash image).
If your application requires a Flash File System, you will need to compile and link it into your app. I have not worked with this yet.
=============================================
Once I put together the information above, I was able to understand the procedures for updating firmware at the end of the Programmers' Guide:
Rebuild BSP, bootloader and application
Use JTAG and gdb to run an FTP server in RAM
Use the RAM based ftp server to load the bootloader with reserved filename rom.bin
Use the RAM based ftp server to load the application with reserved filename image.bin
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
=============================================
Memory Top
NonVolatile Memory
Flash File System (if compiled into application)
User Application (includes BSP)
-----
Boot Loader
Memory Bottom
Maybe someday I'll draw a real picture. For now, the outline above will do.
In the original ConnectMe, the Boot Loader was not user accessible. It is, however, built by the Development Kit (DK) along with the Board Support Package (BSP). In the latest DK, the boot loader image is linked as:
netos60_gnu/src/bsp/bootloader/romImage/rom.bin
In the original ConnectMe, everything above the dashed line is changeable, but everything below the dashed line is locked. So, you cannot change the boot loader (or can you...). Changing the boot loader would be convenient because it kinda sucks. When the system boots, the boot loader does a sum check of the code in application space. If good, the boot loader jumps to that code. If bad, the boot loader attempts DHCP; if that works, then it tries to bootp a new image from the DHCP server. I have not verified this part experimentally, but I have read that the bootp will only be attempted from the successful dhcp server. There is no way to escape to the boot loader on reset, or from the application; therefore, if you load code into the ConnectMe that satisfies the boot loader's sumcheck, but makes the thing continually reset, you have just wasted a ConnectMe.
The BSP source ends up as:
netos60_gnu/lib/32b/libbsp.a
and is linked into the Boot Loader as well as into your application. That took a while for me to verify - the BSP is linked into my app, as opposed to residing in system Flash like some kind of BIOS. Again, when I verified this observation with Digi Tech Support, they just said, yeah, how else would it be done?
Your application is compiled to image.elf (JTAG/gdb image) and image.bin (Flash image).
If your application requires a Flash File System, you will need to compile and link it into your app. I have not worked with this yet.
=============================================
Once I put together the information above, I was able to understand the procedures for updating firmware at the end of the Programmers' Guide:
Rebuild BSP, bootloader and application
Use JTAG and gdb to run an FTP server in RAM
Use the RAM based ftp server to load the bootloader with reserved filename rom.bin
Use the RAM based ftp server to load the application with reserved filename image.bin
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Command Line GDB
The NetOS development kit comes with a Tcl/Tk GUI version of GNU Debugger (gdb). I could not figure out how to drive it, and ended up using command line gdb. While I'd toyed with gdb in the past, mainly doing post mortems on core dumps, this was the first project on which I'd used it seriously. I wish I'd started long ago. This program is phenomenal.
You can set a breakpoint, then program a bunch of stuff to happen when the breakpoint fires. The last command in that sequence can be a "continue", so you can do printf debugging without changing the executable!
These are my favorite gdb commands:
p print p structure.element
b break b file:line
c continue c
^c break execution
clear clear break clear file:line
b file:line gives you a breakpoint number e.g., 1
To set the command sequence for break 1:
commands 1
p structure.element
c
end
this sequence prints the contents of structure.element and continues execution.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
You can set a breakpoint, then program a bunch of stuff to happen when the breakpoint fires. The last command in that sequence can be a "continue", so you can do printf debugging without changing the executable!
These are my favorite gdb commands:
p print p structure.element
b break b file:line
c continue c
^c break execution
clear clear break clear file:line
b file:line gives you a breakpoint number e.g., 1
To set the command sequence for break 1:
commands 1
p structure.element
c
end
this sequence prints the contents of structure.element and continues execution.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Monday, September 20, 2004
ConnectMe Dev Kit
Digi provides a JTAG development kit (DK) for around $1500 US. The kit includes a development board, a JTAG ConnectMe module, a JTAG interface module, a CD with ThreadX, NetOS and MicroCross/GNU development tools, lots of cables, all the right power supplies, just everything you need to write ConnectMe applications. Except intelligence. You have to provide that. That fact was my first problem.
The DK came with a printed Programmer's Guide that told you how to hook up the wires, but not why. After reading that manual, and the Hardware Reference, it was not clear to me how the JTAG and the two serial ports were supposed to interact with the processor. Nor was it clear to me where the second serial port was coming from - the non-JTAG ConnectMe has only one.
As it turned out:
1. The ConnectMe module has a JTAG variant that is intended for use with this kit. The JTAG signals come out of the metal case on a little wing of circuit board material. So do the second serial port signals. You lose the second serial port when you go to the standard module.
2. The Programmer's Guide tells you how to line up the serial ports as stdin/stdout. It mentions the second serial port, but neglects to tell you that, in order to enable the second serial port, you have to change a Board Support Package (BSP) header file and recompile the BSP. I have the details somewhere, but they will probably change over time. Just be aware that it's a problem and ask Digi tech support before wasting time on it.
3. DO NOT use code that has the second serial port enabled on a non-JTAG ConnectMe (i.e. no second serial port). The BSP will hang while initializing the nonexistent port, and your ConnectMe will be TRASH (more on that later). I decided not to use the second serial port, since I hate having code that's different between the emulator and the target.
4. The JTAG interface takes over the ARM7 (NS7520) processor via debugging logic embedded in the ARM. When you load code through JTAG, you are writing the code to the processor's RAM. When you execute your code, you are forcing the processor to jump directly to your RAM based code. Once the JTAG pod takes over, no FLASH-based code is executed. That includes the boot loader as well as application code. The JTAG does not directly erase Flash, though you can load RAM based code that does so, e.g., sample project naftpapp.
5. The serial connections are not used to control the debug sessions. They come into play only when your RAM based application code is executing. The language in the Programmer's Guide implies otherwise. It makes more sense my way, but I was not sure what the truth was until I did some experiments.
6. The second serial connection is intended as a debug console for your debug session. You can line it up as stdin/stdout if you want, then do printf debugging as long as you're using the JTAG module. In fact, you can load your app onto the JTAG module's FLASH using naftpapp running in RAM, then reboot, and do printf debugging without the JTAG pod. If you want to.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
The DK came with a printed Programmer's Guide that told you how to hook up the wires, but not why. After reading that manual, and the Hardware Reference, it was not clear to me how the JTAG and the two serial ports were supposed to interact with the processor. Nor was it clear to me where the second serial port was coming from - the non-JTAG ConnectMe has only one.
As it turned out:
1. The ConnectMe module has a JTAG variant that is intended for use with this kit. The JTAG signals come out of the metal case on a little wing of circuit board material. So do the second serial port signals. You lose the second serial port when you go to the standard module.
2. The Programmer's Guide tells you how to line up the serial ports as stdin/stdout. It mentions the second serial port, but neglects to tell you that, in order to enable the second serial port, you have to change a Board Support Package (BSP) header file and recompile the BSP. I have the details somewhere, but they will probably change over time. Just be aware that it's a problem and ask Digi tech support before wasting time on it.
3. DO NOT use code that has the second serial port enabled on a non-JTAG ConnectMe (i.e. no second serial port). The BSP will hang while initializing the nonexistent port, and your ConnectMe will be TRASH (more on that later). I decided not to use the second serial port, since I hate having code that's different between the emulator and the target.
4. The JTAG interface takes over the ARM7 (NS7520) processor via debugging logic embedded in the ARM. When you load code through JTAG, you are writing the code to the processor's RAM. When you execute your code, you are forcing the processor to jump directly to your RAM based code. Once the JTAG pod takes over, no FLASH-based code is executed. That includes the boot loader as well as application code. The JTAG does not directly erase Flash, though you can load RAM based code that does so, e.g., sample project naftpapp.
5. The serial connections are not used to control the debug sessions. They come into play only when your RAM based application code is executing. The language in the Programmer's Guide implies otherwise. It makes more sense my way, but I was not sure what the truth was until I did some experiments.
6. The second serial connection is intended as a debug console for your debug session. You can line it up as stdin/stdout if you want, then do printf debugging as long as you're using the JTAG module. In fact, you can load your app onto the JTAG module's FLASH using naftpapp running in RAM, then reboot, and do printf debugging without the JTAG pod. If you want to.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
Wednesday, September 15, 2004
Second Verse, Same as the First
My second brush with the ConnectMe is going to take a while to relate. The month I put on this project was one of the most intense software development experiences of my career. Like my first ConnectMe project, it started out easy, but ended up as a crisis. this time, though, the crisis was partly my fault.
In early September, my former employer approached me about consulting on a new ConnectMe project. One customer needed some special processing done on the serial command stream, and neither side had time or compute capacity to make the changes in the time available - 6 weeks. I accepted the project, but my wife had just been in a car accident, and I was not able to focus on the project until mid September - T minus 4 weeks.
The project should have been easy. I expected it to be easy. I wrote a command line program that implemented and tested the core logic in about a day. I think it was a Sunday. Then I tried to port that program to the ConnectMe. Four weeks later, I was still struggling with the ConnectMe platform. I lost so much time struggling with the ConnectMe platform that I ended up traveling to the customer site to finish the software there, on their ship day.
Lest you think I'm some kind of liberal whiner, be aware that over the past five years I have delivered the software for an entire product line, including 3 different processors as well as Xilinx programmable logic. I designed the communication protocols involved here. The ConnectMe environment kicked my ass. For a while. I finally figured it out, and still believe it was worth the struggle. Even if you pay full price - U$D 40 - you can't beat what this little guy can do.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.
In early September, my former employer approached me about consulting on a new ConnectMe project. One customer needed some special processing done on the serial command stream, and neither side had time or compute capacity to make the changes in the time available - 6 weeks. I accepted the project, but my wife had just been in a car accident, and I was not able to focus on the project until mid September - T minus 4 weeks.
The project should have been easy. I expected it to be easy. I wrote a command line program that implemented and tested the core logic in about a day. I think it was a Sunday. Then I tried to port that program to the ConnectMe. Four weeks later, I was still struggling with the ConnectMe platform. I lost so much time struggling with the ConnectMe platform that I ended up traveling to the customer site to finish the software there, on their ship day.
Lest you think I'm some kind of liberal whiner, be aware that over the past five years I have delivered the software for an entire product line, including 3 different processors as well as Xilinx programmable logic. I designed the communication protocols involved here. The ConnectMe environment kicked my ass. For a while. I finally figured it out, and still believe it was worth the struggle. Even if you pay full price - U$D 40 - you can't beat what this little guy can do.
Larry Martin
www.GlueLogix.com
Copyright (c) 2004 Larry Martin. All Rights reserved.