EmbeddedRelated.com
Forums
Memfault State of IoT Report

TI's Code Composer does not clear bss data

Started by David Brown January 27, 2011
On 28/01/2011 00:48, Simon Clubley wrote:
> On 2011-01-27, Hans-Bernhard Br&#4294967295;ker<HBBroeker@t-online.de> wrote: >> On 27.01.2011 22:47, Grant Edwards wrote: >> >>> A compliant compiler should never warn about a static variable being >>> "uninitialized" since according to the C standards all static >>> variables are, by definition, initialized. >> >> Close, but not quite correct. Compliancy has nothing to do with that. >> Now, sanity, or quality of implementation, that's a totally different >> kettle of fish. >> >> A compliant compiler is entitled to warn ("emit diagnostics") about >> whatever it bloody well pleases. A diagnostic like >> >> Oh, puleeze! Come on, mon, you know perfectly well that 13-letter >> variable names are not allowed in line 5 of a source file! >> >> can be emitted without in any way risking your compiler's compliancy level. > > Indeed. :-) > > The gcc Ada front end has successfully compiled a number of my Ada programs > while still telling me _exactly_ why they were going to then fail at runtime. > > I was sure I had seen this uninitialised warning in the distant past, but > I just compiled a test C program (which didn't explictly initialise a static > variable before using it) with a gcc 4.x compiler and I didn't get a warning. >
You need to enable the appropriate warnings (I can't remember the exact flag off-hand - but it is included in "-Wall -Wextra").
> However, my main reason for initialising zero valued variables in the code > is that I don't like implictly assigned variables. > > Simon. >
On 28/01/2011 02:38, larwe wrote:
> On Jan 27, 3:14 pm, Simon Clubley<clubley@remove_me.eisner.decus.org- > Earth.UFP> wrote: > >> However, I have a policy that I always initialise at startup _all_ variables >> whose first use within the code is something other than to be assigned a >> value, even when I am just initialising that variable to it's implictly > > I could not agree with your post more completely. Today I might be > writing code on an elegant, well-tested compiler fully compliant with > the standards of the day. Tomorrow I might want to import that > sourcecode into a hellhole of a broken, buggy compiler (Microchip > targets come to mind), and my best defense is to make sure that my > code assumes as little as possible about the quality of the compiler. >
I don't see it that way. In fact, I strongly disagree. I expect my tools to perform basically according to specifications. I can understand a certain amount of deviation from standards in certain areas, or inconvenient limitations, and I can cope with their being bugs in obscure or complicated features. But I will not willingly waste my time and effort writing code in a way that it will still work with a fundamentally broken tool. That is a waste of my time and my customers' money, and cannot possibly work anyway. This CCS flaw seems to be peculiar to CCS - maybe another compiler has an equally fundamental and equally inconvenient flaw. Supposing for example that Microchip's compiler is unable to generate correct code for nested switches. Does that mean I should never use nested switches, in case I want to compile the code for a Microchip processor? No, it means that I will not choose to use Microchip's flawed compiler - if I am using those devices, I will use a different compiler for them. And if there are no alternative compilers, I will prefer not to use the chip. And if I have to use that chip and that compiler, then it will cost the customer extra for the extra time it takes to work around the flaw. But I won't pass on that cost to other customers. For a concrete example of such a fundamental flaw in the tools, I have a compiler that I used on a particular target some 15 years ago. The flaw is partly the fault of the compiler, and partly the fault of the board arrangement, but the result is that this 16-bit processor can only access main ram as 8-bit - if the compiler generates 16-bit load or store instructions to main memory, half the data is lost. Data on the stack can be 16-bit without problems. This is clearly a major flaw, and takes a lot of effort to work around. But although I rarely use these tools, I will in fact be using them again sometime in the very near future. So should I make sure that the code I write for other projects uses the same workarounds, just so that I can share that code? Most of the work I do is compiled using modern gcc versions, for different target processors. But sometimes I have to use older or more limited compilers. Should I go back to old-fashioned #define's for all my constants and macro functions, rather than using type-safe "static const" and "static inline" alternatives, just because of the limitations of other tools? Should I avoid using gcc's "typeof" operator even when if makes the code clearer and safer? Sometimes I write code that I know will have to work on a range of tools, but mostly I write code to make the best use of the tools I have, with the assumption that future tools will be at least as good.
> Yeah, I know .bss ought to be zero. When I write startup code, I zero > it. I have absolutely no faith in RandomCRTLibraryProviderXYZ to obey > any kind of laws or best practices, so I don't rely on anyone else's > implementation for this. Anyone who has ever tried to use an Atmel app > note will realize that even code that comes direct from chip > manufacturers is frequently of hideous quality.
Appnote code and example code is a different matter, and is (I hope!) written by different people than compilers and their libraries. Appnote code and examples are written to give you an idea of how it is possible to use a certain feature of the device - it should be clear and easy to follow, but it only needs basic functionality and doesn't need to be optimal, and often isn't heavily tested. Of course, it often isn't clear - but that's just bad examples. Compiler code and low-level libraries need to be correct and well-tested, and preferably small and fast. Clarity of code is low down on the priority list (except so that the developers know that it is correct).
On 2011-01-28, David Brown <david@westcontrol.removethisbit.com> wrote:
> > Good C compilers warn about using uninitialised data. But statically > allocated data /is/ initialised - to zero. A complier that warns about > global data being uninitialised has a broken warning system (or, like > CCS, it is a broken compiler/toolchain). It is a different matter for > non-static locals - they must be explicitly initialised, and it is good > for the compiler to warn you about them. And in such cases, you are > typically not "actively eliminating compiler warnings", you are > "actively eliminating code bugs" ! >
As I mentioned in another post, I thought I had seen compilers in the past warning about static variables not been explicitly assigned to before use.
> Generally, I agree with you about explicit being better than implicit. > I would never write code that uses the implicit "int" that exists in > many places in C - to me, "long" is a description and "long int" is the > type (actually, I would prefer the more explicit int32_t). >
In addition to doing this as well, I also go one further and declare all my integers as unsigned unless I actually need to store signed data into them. However, I still cannot get over your toolkit vendor spending more time writing a note about not clearing .bss instead of actually just doing it. I wonder if someone forgot to do it and your vendor wrote up a note afterwards justifying it's current behaviour rather than admitting they made a embarrassing mistake and just fixing the problem in the first place. :-) Seriously however, it would be interesting to know why they do this. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
On 2011-01-28, David Brown <david@westcontrol.removethisbit.com> wrote:
> > I don't know the details in this case (I haven't looked at the low-level > workings of the msp430 jtag interface). But ultimately, jtag is a silly > choice of interface for debugging - it's got a /huge/ overhead if you > want to follow all the rules correctly. Most chips that have a jtag > debugger interface have some sort of non-standard shortcut to put their > jtag interface into "debug" mode rather than testpin mode. Some of > these play well with other jtag devices, others only work well if they > are the only device on the jtag bus. While the best idea is to have a > shortcut technique that works along with other devices on the board, > it's usually only the big chips that bother. When you have an FPGA or a > processor in a 400 pin bga package, it is conceivable that you will also > have a jtag chain for testing pin connections between that package and a > bga package memory device. But I expect it is a negligible proportion > of msp430 users who will want other jtag devices on the same chain. >
Interesting and I had not considered this. [snip other equally interesting comments] Thank you for spending the time writing a detailed writeup and covering issues I had not considered. As I have mentioned in the past, I am a professional programmer, but a hobbyist when it comes to electronics work, so issues like this are ones I am not likely to encounter and hence don't consider unless made aware of them. Thanks, Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
On 28/01/2011 13:39, Simon Clubley wrote:
> On 2011-01-28, David Brown<david@westcontrol.removethisbit.com> wrote: >> >> I don't know the details in this case (I haven't looked at the low-level >> workings of the msp430 jtag interface). But ultimately, jtag is a silly >> choice of interface for debugging - it's got a /huge/ overhead if you >> want to follow all the rules correctly. Most chips that have a jtag >> debugger interface have some sort of non-standard shortcut to put their >> jtag interface into "debug" mode rather than testpin mode. Some of >> these play well with other jtag devices, others only work well if they >> are the only device on the jtag bus. While the best idea is to have a >> shortcut technique that works along with other devices on the board, >> it's usually only the big chips that bother. When you have an FPGA or a >> processor in a 400 pin bga package, it is conceivable that you will also >> have a jtag chain for testing pin connections between that package and a >> bga package memory device. But I expect it is a negligible proportion >> of msp430 users who will want other jtag devices on the same chain. >> > > Interesting and I had not considered this. > > [snip other equally interesting comments] > > Thank you for spending the time writing a detailed writeup and covering > issues I had not considered. > > As I have mentioned in the past, I am a professional programmer, but a > hobbyist when it comes to electronics work, so issues like this are ones > I am not likely to encounter and hence don't consider unless made aware of > them. > > Thanks, > > Simon. >
A lot of people who are used to microcontrollers think of jtag as just an interface for programming and debugging microcontrollers. But in fact it is designed as a board test interface, and a jtag bus is fundamentally a huge shift register. Different devices such as memory chips, processors, fpgas, etc., are all attached to the bus in serial. Then jtag commands are clocked along the bus. Initially, you use commands that are designed to identify the devices and you have commands to put different devices in active or passive states. Then when you have picked one (or more) devices to communicate with, you clock data into their test registers and read out the results of the last test. Early jtag-based debug interfaces used precisely this method, with all the relevant debug registers attached in the chain. But if that is, for example, 10 registers with 32 bits each, then you need to clock in 320 (plus more for the command) bits even if you just want to set a single register, and you then need to clock through another 320 (plus command) bits to read the results. This very quickly gets extremely slow, and you need intelligent debugger interface hardware (rather than a simple USB-to-spi converter, or PC parallel port interface as used to be common). So chip designers started cheating - they added new commands to the jtag interface that are not covered by any standard (though they are allowed and ignored by other devices), to allow more efficient communication.
On 28/01/2011 13:28, Simon Clubley wrote:
> On 2011-01-28, David Brown<david@westcontrol.removethisbit.com> wrote: >> >> Good C compilers warn about using uninitialised data. But statically >> allocated data /is/ initialised - to zero. A complier that warns about >> global data being uninitialised has a broken warning system (or, like >> CCS, it is a broken compiler/toolchain). It is a different matter for >> non-static locals - they must be explicitly initialised, and it is good >> for the compiler to warn you about them. And in such cases, you are >> typically not "actively eliminating compiler warnings", you are >> "actively eliminating code bugs" ! >> > > As I mentioned in another post, I thought I had seen compilers in the past > warning about static variables not been explicitly assigned to before use. > >> Generally, I agree with you about explicit being better than implicit. >> I would never write code that uses the implicit "int" that exists in >> many places in C - to me, "long" is a description and "long int" is the >> type (actually, I would prefer the more explicit int32_t). >> > > In addition to doing this as well, I also go one further and declare all my > integers as unsigned unless I actually need to store signed data into them. >
On some small micros, unsigned comparisons are smaller and faster than signed comparisons - so unsigned helps here. It can make an even bigger difference with multiplication and division. But what is more important, is to ensure the sizes of your data are correct. Use #include <stdint.h>, and use types like uint16_t and int8_t instead of plain "int". (For 8-bit processors, using int8_t and uint8_t makes a very big difference.) It can also make sense to use types like int_fast16_t when you are writing portable code - typically that will give you a 16-bit value on an 8-bit or 16-bit processor, but often a 32-bit value on a 32-bit processor.
> However, I still cannot get over your toolkit vendor spending more time > writing a note about not clearing .bss instead of actually just doing it. > > I wonder if someone forgot to do it and your vendor wrote up a note > afterwards justifying it's current behaviour rather than admitting they > made a embarrassing mistake and just fixing the problem in the first > place. :-) > > Seriously however, it would be interesting to know why they do this. > > Simon. >
On 2011-01-27, Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
> On 2011-01-27, Grant Edwards <invalid@invalid.invalid> wrote: >> On 2011-01-27, David Brown <david.brown@removethis.hesbynett.no> wrote: >> >>> But this is something different - it is a concious decision to make the >>> tool incompatible and non-standard in a surprising way that must surely >>> have caused developers a great deal of wasted time and effort, >> >> TI did the same thing with the JTAG interface. They made a conscious >> decision to violate the spec in ways that make it impossible to use in >> a JTAG chain. I was never too crazy about the AVR architecture when >> compared with the MSP430, but at least the AVR JTAG interface worked >> right. > > That's just crazy. :-( > > Was this some attempt at vendor lock in (ie: was there a need to buy a > TI approved JTAG interface device) or was there another reason ?
I'd have to go back and look at the documentation, but IIRC they use one of the JTAG lines in a non-standard way as some sort of CPU clock or something. -- Grant Edwards grant.b.edwards Yow! I own seven-eighths of at all the artists in downtown gmail.com Burbank!
On 28 Jan, 13:28, Simon Clubley <clubley@remove_me.eisner.decus.org-
Earth.UFP> wrote:
> On 2011-01-28, David Brown <da...@westcontrol.removethisbit.com> wrote: > > > > > Good C compilers warn about using uninitialised data. =A0But statically > > allocated data /is/ initialised - to zero. =A0A complier that warns abo=
ut
> > global data being uninitialised has a broken warning system (or, like > > CCS, it is a broken compiler/toolchain). =A0It is a different matter fo=
r
> > non-static locals - they must be explicitly initialised, and it is good > > for the compiler to warn you about them. =A0And in such cases, you are > > typically not "actively eliminating compiler warnings", you are > > "actively eliminating code bugs" ! > > As I mentioned in another post, I thought I had seen compilers in the pas=
t
> warning about static variables not been explicitly assigned to before use=
.
> > > Generally, I agree with you about explicit being better than implicit. > > I would never write code that uses the implicit "int" that exists in > > many places in C - to me, "long" is a description and "long int" is the > > type (actually, I would prefer the more explicit int32_t). > > In addition to doing this as well, I also go one further and declare all =
my
> integers as unsigned unless I actually need to store signed data into the=
m.
> > However, I still cannot get over your toolkit vendor spending more time > writing a note about not clearing .bss instead of actually just doing it. > > I wonder if someone forgot to do it and your vendor wrote up a note > afterwards justifying it's current behaviour rather than admitting they > made a embarrassing mistake and just fixing the problem in the first > place. :-) > > Seriously however, it would be interesting to know why they do this. > > Simon. > > -- > Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP > Microsoft: Bringing you 1980s technology to a 21st century world
So tell me how you would write a simple bss-init routine for TI TMS320C3x/c4x? These are floating point DSPs where binary 0 equals 1.0.
On Fri, 28 Jan 2011 11:14:14 -0800, wicore wrote:

> So tell me how you would write a simple bss-init routine for TI > TMS320C3x/c4x? These are floating point DSPs where binary 0 equals 1.0.
That needs help from the compiler. Either the compiler needs to put uninitialized floats in the DATA section, with proper 0.0 initialization, or it needs to put them in a special BSS_FLOAT section where the start up code can loop through all variables, assigning them 0.0
On 2011-01-28, Arlet Ottens <usenet+5@c-scape.nl> wrote:
> On Fri, 28 Jan 2011 11:14:14 -0800, wicore wrote: > >> So tell me how you would write a simple bss-init routine for TI >> TMS320C3x/c4x? These are floating point DSPs where binary 0 equals 1.0. > > That needs help from the compiler. Either the compiler needs to put > uninitialized floats in the DATA section, with proper 0.0 initialization, > or it needs to put them in a special BSS_FLOAT section where the start up > code can loop through all variables, assigning them 0.0 >
Since wicore's posting was directed to me, I would also say that personally I am much more tolerant of implementation issues when a language is ported to a new architecture type which contains architectural specific issues which were probably not considered when the language was designed. However, the OP is using a more traditional architecture on which this kind of initialisation is clearly expected as standard. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world

Memfault State of IoT Report