Discussion:
AVR Board, and Debug and Development?
(too old to reply)
apluscw
2013-05-07 01:26:23 UTC
Permalink
I see there is architecture support for the Atmel AVR, but I don't recognize a board in the config list. Can anyone name a specific board or controller with a working NuttX demo?

Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.

THX!
talkingtoken
2013-05-07 01:52:00 UTC
Permalink
Hi Apluscw,
Post by apluscw
I see there is architecture support for the Atmel AVR, but I don't recognize a board in the config list. Can anyone name a specific board or controller with a working NuttX demo?
Doing a "grep -R ARCH_AVR=y configs/*" revels the following boards:

configs/amber/README.txt
configs/avr32dev1/README.txt
configs/micropendous3/README.txt
configs/teensy/README.txt

I don't know which of them would be best for you to start with, but I suspect they probably all work.
Post by apluscw
Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.
I am using OpenOCD with my STM32F4 development boards and can comment on this.

1. Think of OpenOCD as "interface software" to your board. It really just sits in the background and transforms gdb commands into JTAG commands. All the real work is done in gdb.

2. You need to configure OpenOCD to use the right configuration based on your board / processor (AVR in your case). I create an openocd.cfg file, and OpenOCD knnows to read this file from the current directory automatically, so once it's setup, you don't have to think about it any more. In the openocd.cfg file, you have to enable programming the flash from gdb, etc.

3. I use Eclipse to perform source level debugging using gdb. This is done by creating a debug configuration within Eclipse, telling it to use the right version of gdb (the ARM version in my case), and the OpenOCD port to communicate with (port 3333).

4. Eclipse will communicate with OpenOCD via gdb to download your code and start debugging. Then it will use the symbol information in the program binaries to locate your sources and provide full debugging capability, including setting breakpoints, single stepping, viewing variables / registers, etc.

Hope this helps some,
Ken
apluscw
2013-05-07 01:58:57 UTC
Permalink
Post by talkingtoken
Hi Apluscw,
Post by apluscw
I see there is architecture support for the Atmel AVR, but I don't recognize a board in the config list. Can anyone name a specific board or controller with a working NuttX demo?
configs/amber/README.txt
configs/avr32dev1/README.txt
configs/micropendous3/README.txt
configs/teensy/README.txt
Thx. I am afraid I am not familiar with any of those AVR boards. The AVR32 platform is not something I would design for at this stage, as it looks like Atmel is pushing ARM for 32-bit these days.
Post by talkingtoken
I don't know which of them would be best for you to start with, but I suspect they probably all work.
Post by apluscw
Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.
I am using OpenOCD with my STM32F4 development boards and can comment on this.
1. Think of OpenOCD as "interface software" to your board. It really just sits in the background and transforms gdb commands into JTAG commands. All the real work is done in gdb.
2. You need to configure OpenOCD to use the right configuration based on your board / processor (AVR in your case). I create an openocd.cfg file, and OpenOCD knnows to read this file from the current directory automatically, so once it's setup, you don't have to think about it any more. In the openocd.cfg file, you have to enable programming the flash from gdb, etc.
3. I use Eclipse to perform source level debugging using gdb. This is done by creating a debug configuration within Eclipse, telling it to use the right version of gdb (the ARM version in my case), and the OpenOCD port to communicate with (port 3333).
4. Eclipse will communicate with OpenOCD via gdb to download your code and start debugging. Then it will use the symbol information in the program binaries to locate your sources and provide full debugging capability, including setting breakpoints, single stepping, viewing variables / registers, etc.
Hope this helps some,
Ken
I would love a screenshot of someone single stepping through code. It would make me feel a lot better. :)

THX! :)
talkingtoken
2013-05-07 03:24:20 UTC
Permalink
Hi,
Post by apluscw
Thx. I am afraid I am not familiar with any of those AVR boards. The AVR32 platform is not something I would design for at this stage, as it looks like Atmel is pushing ARM for 32-bit these days.
I used to be big on Atmel ARM devices too, but is seems STM has much better parts these days. In fact, I still have an Atmel SAM7 board here with a not-that-great LCD on it. To each his own, in the end, it's all just code. :)
Post by apluscw
I would love a screenshot of someone single stepping through code. It would make me feel a lot better. :)
Sure, no problem. See the links below, but be warned, these are TIFF files for better clarity, not JPEG, so they are a little over 1MB each. No problem if you have broadband, but if you are on dial-up..... I even made a screenshot of my Eclipse debug configuration for communication with OpenOCD via gdb.

http://www.kenpettit.com/images/nuttx/nuttx_debug2.tiff
http://www.kenpettit.com/images/nuttx/nuttx_dbgcfg2.tiff

Ken
apluscw
2013-05-07 21:47:48 UTC
Permalink
Post by talkingtoken
http://www.kenpettit.com/images/nuttx/nuttx_debug2.tiff
http://www.kenpettit.com/images/nuttx/nuttx_dbgcfg2.tiff
Ken
Oh, VERY nice. :) Where do I sign? ;)

Will need to go the cygwin route, though. (If anyone thinks I am a dyed in the wool Windowsite I owned not one, but TWO, Amigas in my lifetime.)
Gregory N
2013-05-07 22:07:49 UTC
Permalink
Post by apluscw
Post by talkingtoken
http://www.kenpettit.com/images/nuttx/nuttx_debug2.tiff
http://www.kenpettit.com/images/nuttx/nuttx_dbgcfg2.tiff
Ken
Oh, VERY nice. :) Where do I sign? ;)
Will need to go the cygwin route, though. (If anyone thinks I am a dyed in the wool Windowsite I owned not one, but TWO, Amigas in my lifetime.)
There are a few options under Windows:

1) Cygwin is one good option. It is big and slow but otherwise really quit nice. The OpenOCD source tarball builds under Cygwin with no problems.

Cygwin supports X-11 so and graphical GDB frontends like ddd work quite well under Cygwin. Is Eclipse available under Cygwin? I don't think so.

2) MSYS is a little sparser option than Cygwin. I haven't used it, but other people in this list have and it apparently supports the NuttX build just fine.

I do not know if you can build OpenOCD under MSYS. MSYS's advantage over Cygwin is that it is a sparser environment and better integrated with Windows. But, as a result, it is also not as portable. Getting things to build under MSYS has been a problem.

The kconfig-frontends configuration tool is a good example of the difficulties building under MSYS. kconfig-fronteds works great under Linux and Cygwin, but is not available elsew

In the case of OpenOCD, you have the options of using a native Windows version. A Windows installer .exe is available from the OpenOCd website.

3) A final option is a pure native Windows build (using The GNUWin32 tools to fill in some missing applications).

I don't use Eclipse, but I suspect that Windows Eclipse with a Cygwin build might be difficult because of Cygwin PATH issues. MSYS might integrate easier with Eclipse; I don't really know. GNUWin32/native should be a drop-in.

No configuration tool in the native Windows build either.

Greg
Gregory N
2013-05-07 03:42:44 UTC
Permalink
Hi,
Post by apluscw
Post by talkingtoken
Post by apluscw
I see there is architecture support for the Atmel AVR, but I don't recognize a board in the config list. Can anyone name a specific board or controller with a working NuttX demo?
configs/amber/README.txt
configs/avr32dev1/README.txt
configs/micropendous3/README.txt
configs/teensy/README.txt
Thx. I am afraid I am not familiar with any of those AVR boards. The AVR32 platform is not something I would design for at this stage, as it looks like Atmel is pushing ARM for 32-bit these days.
Post by talkingtoken
I don't know which of them would be best for you to start with, but I suspect they probably all work.
The others are 8-bit AVRs, either ATMega128 (the Amber board) or AT90USB (Teensy and Micropendous3).

It has been awhile since I have used the any of the 8-bit AVRs. All of the above have only 4KB or 8KB of SRAM. I am keeping my eyes open for one of the ATMegas or, preferably, XMegas with more SRAM but haven't found a board that I like yet. Can you recommend one?

8KB actually works pretty well because the AVRs don't require enormous stacks like the 32-bit ARMs do (but 4KB is a bit pinched). I would like to have more SRAM for significant, modern C/C++ applications.

But the only real SRAM limitation that I run into with these parts has to do with the AVR's Harvard architecture: All .rodata has to lie in SRAM (or else be accessed from the instruction bus through special asm functions). Most of the NuttX example software is very console oriented, using serial output to interact with the software and for debug output. Tests like the NuttX OS test will use a lot of space for constant printf() strings and this all ends up in SRAM. Even 8KB is not enough memory for any significant .rodata storage.

You would like to keep the .rodata in FLASH as you would for ARMs. I do have some logic that will take printf() strings from the instruction space, but it is not foolproof. There is no way to make a standard, generic printf() function that works with strings in either SRAM or FLASH. Most AVR code uses special, non-portable versions for printf or else special printf formats to access strings in FLASH.
Post by apluscw
Post by talkingtoken
Post by apluscw
Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.
I am using OpenOCD with my STM32F4 development boards and can comment on this.
... [snip] ...
I have never used OpenOCD with the 8-bit AVRs. I don't know if that is possible or not; I would have to investigate that. I don't know if there is open source AVR JTAG hardware that would work with OpenOCD. I used the NuttX buildroot toolchain with either an AVRISP mkII or an AVRICE mkII and AVRStudio (just to control the debugger). There may be some discussion in the configs/<board>/README.txt file for any particular board.

Greg
apluscw
2013-05-07 22:04:15 UTC
Permalink
Post by Gregory N
Hi,
Post by apluscw
Post by talkingtoken
Post by apluscw
I see there is architecture support for the Atmel AVR, but I don't recognize a board in the config list. Can anyone name a specific board or controller with a working NuttX demo?
configs/amber/README.txt
configs/avr32dev1/README.txt
configs/micropendous3/README.txt
configs/teensy/README.txt
Thx. I am afraid I am not familiar with any of those AVR boards. The AVR32 platform is not something I would design for at this stage, as it looks like Atmel is pushing ARM for 32-bit these days.
Post by talkingtoken
I don't know which of them would be best for you to start with, but I suspect they probably all work.
The others are 8-bit AVRs, either ATMega128 (the Amber board) or AT90USB (Teensy and Micropendous3).
It has been awhile since I have used the any of the 8-bit AVRs. All of the above have only 4KB or 8KB of SRAM. I am keeping my eyes open for one of the ATMegas or, preferably, XMegas with more SRAM but haven't found a board that I like yet. Can you recommend one?
Well, for AVR the XMEGA line is well positioned and should be around for quite awhile. Atmel's XMEGA Xplain board are relatively cheap and fairly full featured. I bought an XMEGA board from Boston Android for a Halloween custom and general playing around but they stopped producing them. :(

For hobbyist, the Holy Grail is the ATMEGA328, which is available in 28-pin DIP and is programmable using a $50 AVR Dragon board and Atmel Studio is 100% free. Of course, you then get into the question of whether or not OpenOCD supports the tools. :(

BTW, for the Atmel fans out there, here is my view of where to put any development effort, from cheapest to most expensive:

ATMEGA328 -> XMEGA -> SAM4

For the money, the XMEGA's are pretty impressive. I would argue the Atmel tools are not as mature for the SAMs as for the AVRs (the tools was AVR Studio until fairly recently, not Atmel Studio.) However, if you are running NuttX, that may not be much of an issue.

BTW, Atmel has their own "Atmel Software Framework" which might be useful to set up any given microcontroller or just take advantage of things already written. How would that work with NuttX? Would the ASF code need to be pulled in? If it was modified, can it exist as part of the NuttX project? The ASF has it's own "ASF License", which I won't quote here.
Post by Gregory N
8KB actually works pretty well because the AVRs don't require enormous stacks like the 32-bit ARMs do (but 4KB is a bit pinched). I would like to have more SRAM for significant, modern C/C++ applications.
I noticed when I glanced through the POSIX calls a reference to loading an app and running it in RAM, which made we wonder if that would be a problem for AVR both from a RAM standpoint and from a Harvard architecture standpoint.
Post by Gregory N
But the only real SRAM limitation that I run into with these parts has to do with the AVR's Harvard architecture: All .rodata has to lie in SRAM (or else be accessed from the instruction bus through special asm functions). Most of the NuttX example software is very console oriented, using serial output to interact with the software and for debug output. Tests like the NuttX OS test will use a lot of space for constant printf() strings and this all ends up in SRAM. Even 8KB is not enough memory for any significant .rodata storage.
You would like to keep the .rodata in FLASH as you would for ARMs. I do have some logic that will take printf() strings from the instruction space, but it is not foolproof. There is no way to make a standard, generic printf() function that works with strings in either SRAM or FLASH. Most AVR code uses special, non-portable versions for printf or else special printf formats to access strings in FLASH.
You may have more detailed knowledge than I do but having worked with both the AVRS and the XMEGA AVRs they do have some special means of insuring data gets into Flash rather than instantiated in RAM.

I am more interested in making NuttX usable in a moderate, single chip embedded systems so Cortex-M4(F) platforms are more interesting to me right now, but I do have an interest in seeing how far down we can push NuttX into things like the AVR and I have lots of AVR goodies to work with. (I bought an STK500 back when having a development system for less than $100 was practically unheard of.)
Post by Gregory N
Post by apluscw
Post by talkingtoken
Post by apluscw
Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.
I am using OpenOCD with my STM32F4 development boards and can comment on this.
... [snip] ...
I have never used OpenOCD with the 8-bit AVRs. I don't know if that is possible or not; I would have to investigate that. I don't know if there is open source AVR JTAG hardware that would work with OpenOCD. I used the NuttX buildroot toolchain with either an AVRISP mkII or an AVRICE mkII and AVRStudio (just to control the debugger). There may be some discussion in the configs/<board>/README.txt file for any particular board.
Greg
For me, support for the SAM-ICE is probably more critical, though Atmel has the SAM4S Xplained board which has it's own built in debugger. I am thinking about making that a future project. They are only $29 and a bit more direct from DigiKey.
Gregory N
2013-05-07 23:10:40 UTC
Permalink
Post by apluscw
Well, for AVR the XMEGA line is well positioned and should be around for quite awhile. Atmel's XMEGA Xplain board are relatively cheap and fairly full featured. I bought an XMEGA board from Boston Android for a Halloween custom and general playing around but they stopped producing them. :(
I'll continue to keep my eyes open.
Post by apluscw
For hobbyist, the Holy Grail is the ATMEGA328, which is available in 28-pin DIP and is programmable using a $50 AVR Dragon board and Atmel Studio is 100% free. Of course, you then get into the question of whether or not OpenOCD supports the tools. :(
The ATMega328 is, indeed, a popular embedded MCU. But at 32KB FLASH and 2KB of RAM, it is not going to be hosting any significant multi-threaded applications. So it is not too interesting from my point of view as an RTOS guy.
Post by apluscw
ATMEGA328 -> XMEGA -> SAM4
For the money, the XMEGA's are pretty impressive. I would argue the Atmel tools are not as mature for the SAMs as for the AVRs (the tools was AVR Studio until fairly recently, not Atmel Studio.) However, if you are running NuttX, that may not be much of an issue.
BTW, Atmel has their own "Atmel Software Framework" which might be useful to set up any given microcontroller or just take advantage of things already written. How would that work with NuttX? Would the ASF code need to be pulled in? If it was modified, can it exist as part of the NuttX project? The ASF has it's own "ASF License", which I won't quote here.
Because of license uncertainties, I make an effort not to use any chip vendor software in NuttX. I might look at it as guidelines for writing my own, but every vendor software package has hidden licensing gotchas (besides tending to be awful code. Well, not awful, just wrongly purposed. Most vendor code is obviously intended to support testing, not sane application development).

<parody>
typedef enum ERROCODE_ENUM ERRORCODE_TYPE;

enum TRUE_FALSE_ENUM
{
FALSE_VALUE = 0,
TRUE_VALUE = 1,
NUMBER_OF_TRUE_FALSE_VALUES
};

typedef enum TRUE_FALSE_ENUM TRUE_FALSE_TYPE;

ERRCODE_TYPE BONHD_SetTrueFalseValue(TRUE_FALSE_TYPE TrueFalseValue)
{
CHECK_INPUT_PARAMETER(TRUE_FALSE_TYPE, TrueFalseValue, FALSE_VALUE, TRUE_VALUE);

if (TrueFalseValue == FALSE_VALUE)
{
BONHD_SetFalseValue();
return ERROCODE_SUCCESS;
}
else if (TrueFalseValue == TRUE_VALUE)
{
BONHD_SetTrueValue();
return ERROCODE_SUCCESS;
}
else
{
return ERROCDE_BAD_TRUE_FALSE_VALUE;
}
}
</parody>

I am sure that some people reading this probably think that is great code.
Post by apluscw
Post by Gregory N
8KB actually works pretty well because the AVRs don't require enormous stacks like the 32-bit ARMs do (but 4KB is a bit pinched). I would like to have more SRAM for significant, modern C/C++ applications.
I noticed when I glanced through the POSIX calls a reference to loading an app and running it in RAM, which made we wonder if that would be a problem for AVR both from a RAM standpoint and from a Harvard architecture standpoint.
Well, 8KB would be a problem in any case. But even so, yes, it would not work. The FLASH is connected to the instruction bus and supports only 16-bit addressing. That is why 128KB with a 16-bit address is such a popular AVR FLASH size (higher FLASH sizes require extended addressing).

So you can fetch instructions from FLASH, but you cannot access data in FLASH without some asm magic. Here is that asm magic for the AVR: http://sourceforge.net/p/nuttx/git/ci/master/tree/nuttx/arch/avr/src/avr/up_romgetc.c#l63 (Notice that despite my sarcasm above, this actually is using a AVR Studio function to read from FLASH -- pgm_read_byte_near()).

Conversely, the RAM is connected to the data bus (supporting a maximum of 64KB of RAM with 16-bit addressing). You can access data in RAM, but you cannot fetch instructions (and I don't think that there is any asm magic available in this case).
Post by apluscw
Post by Gregory N
But the only real SRAM limitation that I run into with these parts has to do with the AVR's Harvard architecture: All .rodata has to lie in SRAM (or else be accessed from the instruction bus through special asm functions). Most of the NuttX example software is very console oriented, using serial output to interact with the software and for debug output. Tests like the NuttX OS test will use a lot of space for constant printf() strings and this all ends up in SRAM. Even 8KB is not enough memory for any significant .rodata storage.
You would like to keep the .rodata in FLASH as you would for ARMs. I do have some logic that will take printf() strings from the instruction space, but it is not foolproof. There is no way to make a standard, generic printf() function that works with strings in either SRAM or FLASH. Most AVR code uses special, non-portable versions for printf or else special printf formats to access strings in FLASH.
You may have more detailed knowledge than I do but having worked with both the AVRS and the XMEGA AVRs they do have some special means of insuring data gets into Flash rather than instantiated in RAM.
Yes, with the linker script, you can force .rodata to lie in FLASH or in RAM. But even if you position it in FLASH, there is no transparent way to access it. How could printf() know whether the address lies in FLASH or RAM? This is the real heart of the issue.
Post by apluscw
I am more interested in making NuttX usable in a moderate, single chip embedded systems so Cortex-M4(F) platforms are more interesting to me right now, but I do have an interest in seeing how far down we can push NuttX into things like the AVR and I have lots of AVR goodies to work with. (I bought an STK500 back when having a development system for less than $100 was practically unheard of.)
Post by Gregory N
Post by talkingtoken
Post by apluscw
Also, I am having a hard time picturing how one actually develops using NuttX. I saw a reference to downloading using OpenOCD and some debugger. What I am not clear on is can you do traditional things like set breakpoints, single step through source code, etc? Is that all done with gdb? If yes, is it strictly text based? There is a LOT I really like about NuttX, but I can't wrap my head around how one develops and debugs with it.
I am using OpenOCD with my STM32F4 development boards and can comment on this.
... [snip] ...
I have never used OpenOCD with the 8-bit AVRs. I don't know if that is possible or not; I would have to investigate that. I don't know if there is open source AVR JTAG hardware that would work with OpenOCD. I used the NuttX buildroot toolchain with either an AVRISP mkII or an AVRICE mkII and AVRStudio (just to control the debugger). There may be some discussion in the configs/<board>/README.txt file for any particular board.
For me, support for the SAM-ICE is probably more critical, though Atmel has the SAM4S Xplained board which has it's own built in debugger. I am thinking about making that a future project. They are only $29 and a bit more direct from DigiKey.
I have a port for the SAM3U which should be a good start for the SAM4S family. It was at the point of maturing when a student bricked my SAM3U-EK. But the port is still in pretty good shape -- I believe.

I toyed with buying an Arduino Due but decided against it because I was not comfortable with the Arduino debug interface. I don't think there is really a place for NuttX in the Arduino ecosystem.

Greg
apluscw
2013-05-09 02:40:35 UTC
Permalink
Post by Gregory N
Because of license uncertainties, I make an effort not to use any chip vendor software in NuttX. I might look at it as guidelines for writing my own, but every vendor software package has hidden licensing gotchas (besides tending to be awful code. Well, not awful, just wrongly purposed. Most vendor code is obviously intended to support testing, not sane application development).
<parody>
typedef enum ERROCODE_ENUM ERRORCODE_TYPE;
enum TRUE_FALSE_ENUM
{
FALSE_VALUE = 0,
TRUE_VALUE = 1,
NUMBER_OF_TRUE_FALSE_VALUES
};
typedef enum TRUE_FALSE_ENUM TRUE_FALSE_TYPE;
ERRCODE_TYPE BONHD_SetTrueFalseValue(TRUE_FALSE_TYPE TrueFalseValue)
{
CHECK_INPUT_PARAMETER(TRUE_FALSE_TYPE, TrueFalseValue, FALSE_VALUE, TRUE_VALUE);
if (TrueFalseValue == FALSE_VALUE)
{
BONHD_SetFalseValue();
return ERROCODE_SUCCESS;
}
else if (TrueFalseValue == TRUE_VALUE)
{
BONHD_SetTrueValue();
return ERROCODE_SUCCESS;
}
else
{
return ERROCDE_BAD_TRUE_FALSE_VALUE;
}
}
</parody>
I am sure that some people reading this probably think that is great code.
Well, I will be honest and say I am not very impressed with what I have seen in the ASF, and they use the K&R curly brace style! :P ;)
Post by Gregory N
Post by apluscw
Post by Gregory N
8KB actually works pretty well because the AVRs don't require enormous stacks like the 32-bit ARMs do (but 4KB is a bit pinched). I would like to have more SRAM for significant, modern C/C++ applications.
I noticed when I glanced through the POSIX calls a reference to loading an app and running it in RAM, which made we wonder if that would be a problem for AVR both from a RAM standpoint and from a Harvard architecture standpoint.
Well, 8KB would be a problem in any case. But even so, yes, it would not work. The FLASH is connected to the instruction bus and supports only 16-bit addressing. That is why 128KB with a 16-bit address is such a popular AVR FLASH size (higher FLASH sizes require extended addressing).
So you can fetch instructions from FLASH, but you cannot access data in FLASH without some asm magic. Here is that asm magic for the AVR: http://sourceforge.net/p/nuttx/git/ci/master/tree/nuttx/arch/avr/src/avr/up_romgetc.c#l63 (Notice that despite my sarcasm above, this actually is using a AVR Studio function to read from FLASH -- pgm_read_byte_near()).
Conversely, the RAM is connected to the data bus (supporting a maximum of 64KB of RAM with 16-bit addressing). You can access data in RAM, but you cannot fetch instructions (and I don't think that there is any asm magic available in this case).
Post by apluscw
Post by Gregory N
But the only real SRAM limitation that I run into with these parts has to do with the AVR's Harvard architecture: All .rodata has to lie in SRAM (or else be accessed from the instruction bus through special asm functions). Most of the NuttX example software is very console oriented, using serial output to interact with the software and for debug output. Tests like the NuttX OS test will use a lot of space for constant printf() strings and this all ends up in SRAM. Even 8KB is not enough memory for any significant .rodata storage.
You would like to keep the .rodata in FLASH as you would for ARMs. I do have some logic that will take printf() strings from the instruction space, but it is not foolproof. There is no way to make a standard, generic printf() function that works with strings in either SRAM or FLASH. Most AVR code uses special, non-portable versions for printf or else special printf formats to access strings in FLASH.
You may have more detailed knowledge than I do but having worked with both the AVRS and the XMEGA AVRs they do have some special means of insuring data gets into Flash rather than instantiated in RAM.
Yes, with the linker script, you can force .rodata to lie in FLASH or in RAM. But even if you position it in FLASH, there is no transparent way to access it. How could printf() know whether the address lies in FLASH or RAM? This is the real heart of the issue.
Post by apluscw
I am more interested in making NuttX usable in a moderate, single chip embedded systems so Cortex-M4(F) platforms are more interesting to me right now, but I do have an interest in seeing how far down we can push NuttX into things like the AVR and I have lots of AVR goodies to work with. (I bought an STK500 back when having a development system for less than $100 was practically unheard of.)
So I do have some recent experience with a Cortex-M4 running out of RAM to execute bootloader functions to write to Flash, which I think is possible because the ARM is a "modified Harvard architecture", if I have that right, and I think it means that there are still two buses but that code and data can be in either one of them.

So is it absolutely required that NuttX processes execute their code in RAM? There are two reasons I ask:

1. Most single chip embedded microcontrollers have several times more Flash than RAM, as they are generally architected to execute their code out of Flash. If this is true it will greatly limit the amount of code that can be executed on most any microcontrollers.

2. Even on "modified" Harvard architectures, won't running code in RAM, and potentially also fetching data from RAM, defeat the advantages of the Harvard architecture since you may not be able to fetch code and data in the same instruction cycle?

Thanks! :)

"Applesauce"
Gregory N
2013-05-09 04:11:16 UTC
Permalink
Hi,
Post by apluscw
Post by Gregory N
<parody>
...[snip] ...
Post by apluscw
Post by Gregory N
</parody>
I am sure that some people reading this probably think that is great code.
Well, I will be honest and say I am not very impressed with what I have seen in the ASF, and they use the K&R curly brace style! :P ;)
I really should avoid being sarcastic. It is bad style.
Post by apluscw
So I do have some recent experience with a Cortex-M4 running out of RAM to execute bootloader functions to write to Flash, which I think is possible because the ARM is a "modified Harvard architecture", if I have that right, and I think it means that there are still two buses but that code and data can be in either one of them.
Code executes out of RAM on all of the Cortex parts that I have worked with. I am not sure what a "modified Harvard architecture" is. The data/instruction buses are not separate on Cortex implementations that support external memories. Perhaps there is an separation of buses for internal RAM and FLASH but if that is the case then there must also be a bridge to makes that separation transparent from the software point of view -- perhaps at a cost of some performance???

Most MCUs support single cycle accesses from SRAM, but FLASH is significant slower. For FLASH, most Cortex-M implementations have some substantial caching logic to improve FLASH performance (but not a traditional instruction cache. I believe that the Cortex-M caching is at the bus level, not the CPU level).
No, not at all. Code can execute in any random access memory that the CPU can fetch from. Code normally executes out of FLASH.

(I know of one exception to that rule: You can't execute code from STM32 F4's CCM memory).
Post by apluscw
1. Most single chip embedded microcontrollers have several times more Flash than RAM, as they are generally architected to execute their code out of Flash. If this is true it will greatly limit the amount of code that can be executed on most any microcontrollers.
In ARM Cortex-M, there is no problem with executing from FLASH or RAM. Nor is there any limitation in where the data may reside. .rodata can go in either FLASH or RAM. But most have so little RAM that it is desirable to use FLASH for read-only data and instruction storage as much as possible.
Post by apluscw
2. Even on "modified" Harvard architectures, won't running code in RAM, and potentially also fetching data from RAM, defeat the advantages of the Harvard architecture since you may not be able to fetch code and data in the same instruction cycle?
I'm not sure. My ARM expertise is too limited. I suppose there could be some performance degradation in the case???? If some kind of bridging is required, then some cycles could be lost. That would be an investigation topic and not something that I could answer off the top of my.

Remember that this discussion came up because we were talking about AVRs that are true Harvard architecture machines. For AVRs You cannot fetch data from FLASH without assembly language magic and you cannot execute code from RAM with any kind of magic. But from my experience, ARM Cortex-M has no such limitations (with the exception of the STM32 CCM memory that I mention above).

Greg
Richard Cochran
2013-05-13 07:01:41 UTC
Permalink
Post by Gregory N
Post by apluscw
Post by Gregory N
<parody>
...[snip] ...
Post by apluscw
Post by Gregory N
</parody>
I am sure that some people reading this probably think that is great code.
Well, I will be honest and say I am not very impressed with what I have seen in the ASF, and they use the K&R curly brace style! :P ;)
I really should avoid being sarcastic. It is bad style.
But your point is really important and valid: The code delivered by
MCU vendors is almost 100% pure garbage. If they would deliver POSIX
run time environments in the first place, then none of us would
have found our way onto the nuttx list.

BTW, although I like Atmel's mega/xmega very much (toolchain is gcc),
that framework thing is, IMHO, completely useless code. It certainly
will *not* help in porting nuttx to xmega.

Thanks,
Richard
Michael Smith
2013-05-13 08:10:49 UTC
Permalink
I'm not sure. My ARM expertise is too limited. I suppose there could be some performance degradation in the case???? If some kind of bridging is required, then some cycles could be lost. That would be an investigation topic and not something that I could answer off the top of my.
Remember that this discussion came up because we were talking about AVRs that are true Harvard architecture machines. For AVRs You cannot fetch data from FLASH without assembly language magic
I'm not sure I follow what you mean by "assembly language magic". All that's necessary is for the data to be appropriately decorated so that compiler emits the right instructions (think FAR vs. NEAR in other implementations). The need for assembly magic with the AVR has more to do with GCC's internal politics than anything else.
and you cannot execute code from RAM with any kind of magic. But from my experience, ARM Cortex-M has no such limitations (with the exception of the STM32 CCM memory that I mention above).
This is also largely a question of implementation. The M4 has Icode and Dcode ports (see e.g. section 2.2 in the TRM), and some of the older parts, as well as the Cortex-R devices support TCMs that can have limited reachability (e.g. instruction fetch only targets the ITCM, but data fetches can also go to the DTCM).

The challenge with all of these architectural decisions is working out what they were trying to achieve (so that you can adapt). Usually the decisions were made by intelligent people for reasons that seemed good at the time...

= Mike
Gregory N
2013-05-14 23:25:42 UTC
Permalink
Hi, Mike,
Post by Michael Smith
I'm not sure. My ARM expertise is too limited. I suppose there could be some performance degradation in the case???? If some kind of bridging is required, then some cycles could be lost. That would be an investigation topic and not something that I could answer off the top of my.
Remember that this discussion came up because we were talking about AVRs that are true Harvard architecture machines. For AVRs You cannot fetch data from FLASH without assembly language magic
I'm not sure I follow what you mean by "assembly language magic". All that's necessary is for the data to be appropriately decorated so that compiler emits the right instructions (think FAR vs. NEAR in other implementations). The need for assembly magic with the AVR has more to do with GCC's internal politics than anything else.
I don't do enough AVR programming to know the syntax on the declaring side of an interface. In most CPUs I have worked with FAR implies an addressing scheme with a larger number of bits (like 24 or 23) and NEAR implies a addressing a few bits (like 16).

In the traditional AVR architecture, instructions are addressed using a 16-bit word address (giving address-ability of 128KB); Data is also address with a 16-bit address, but this is a byte address giving address-ability of 64KB. Enhanced versions of the AVR have increased the address size to extend beyond these limits, but the principle is the same.

But that was not the issue here anyway. The issue here is "How do you implement a portable version of printf() than can handle strings that lie either in data memory or instruction memory on a Harvard architecture machine." We could of course broaden that to |"How do you handle any kind of qualified addressing in printf?"

The format string, for example is a const char *. But does that address lie in instruction space or data space? There is no way to know within printf(). If the data is known to like in instruction space, the data is traditionally accessed with some assembly magic, but as you point out perhaps there are other ways. (All of the examples that I have seen do use assembly magic and add extra logic to interpret bit 0 as the MS or LS byte of the 16 bit instruction space word).

But the real issue is that there is no portable way of knowing.

Same with the %s format. Does the string argument like in instruction or data space?

Greg

Continue reading on narkive:
Loading...