On 2015-09-23, Luke A Guest <laguest@archeia.com> wrote:> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote: > >> The FSF version of gcc doesn't have this problem but this compiler >> situation with Ada is a real mess. > > Yup. > > I've built fsf gnat for various targets: MIPS, ARM, x86, MSP430. No runtime > though. > > What target are you wanting? >Currently PIC32 and ARM bare metal. If some things I am currently doing with the PIC32 work out, then I am going to forget about the PIC18 and drop it from the list of MCUs I am interested in. The last time I looked at your work however, you were having real problems with things being fragile or simply breaking from gcc version to gcc version. I know about Brian's work with the MSP430 stuff and I've used AVR-Ada in the past. Given that RTEMS supports Ada, I've been toying with the idea of doing a RTEMS port for PIC32 in the future and seeing if Ada will be usable on it. It doesn't address the bare metal issue but it might be worth exploring. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
Fundamental C question about "if" statements
Started by ●September 20, 2015
Reply by ●September 23, 20152015-09-23
Reply by ●September 23, 20152015-09-23
Wouter van Ooijen <wouter@voti.nl> writes:> Op 22-Sep-15 om 8:39 PM schreef John Devereux: >> Wouter van Ooijen <wouter@voti.nl> writes: >> >>>> Oh come on, it is time we stop commenting on wanting to use a DIP >>>> processor. I have not used one since the 6809 days, i.e. since the 80-s. >>>> There is no sensible reason to use one in whatever design. >>> >>> That depends on your purpose. I like the ability to wiggle a fried >>> LPC1114 out of my students boards and insert a fresh one for a few >>> $. And to have them put an LPC810 in a solderless breadboard and >>> connect all the wires themselves. >>> >>> Wouter >> >> Hi Wouter >> >> There are also any number of SMT:DIP adapters that can be used, cost is >> ~$1. >> >> <http://www.ebay.co.uk/sch/i.html?_odkw=dip+adapter+-socket&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xdip+adapter+-socket+-sockets+-sop8.TRS0&_nkw=dip+adapter+-socket+-sockets+-sop8&_sacat=0> > > I know, I sell such PCBs myself :) > > But the right comparison (at least for my case of students using > solderless breadboards) is > > 1) DIP chip > > 2) SMD chip + PCB + pins strips + solder it together > > I still stringly prefer 1), especially due to the last part (soldering > it together)Sure, all other things being equal - but you are severely restricted as to your choice of MCU. I gather Simon was particularly interested in 32bit (cortex) parts so there the choice narrows from thousands to about 2. -- John Devereux
Reply by ●September 23, 20152015-09-23
On 23/09/2015 1:55 PM, Simon Clubley wrote:> On 2015-09-22, Tim Wescott <seemywebsite@myfooter.really> wrote: >> On Tue, 22 Sep 2015 23:01:14 +0200, David Brown wrote: >>> There is one good, clear justification for claiming that Ada leads to >>> fewer bugs and higher quality code - there are no amateur Ada >>> programmers. People learn and use Ada because they care about code >>> quality and correctness. > > A related example that gets quoted in Ada circles is an article from > about 15 years ago when a university course used C and then Ada to > complete a train modeling project: > > http://archive.adaic.com/projects/atwork/trains.html > > The interesting bit is towards the end in the "Software" section. > When the code was written in C, no team successfully implemented > the minimum project requirements. When the code was written in Ada, > about 50% of them did.Ada and similar languages tend to both be easier to optimize and produce shorter faster code because they are better defined than C. The problem is historical. C as a language can't be cleaned up as tight as languages like Ada are defined. Optimization for Ada can be very aggressive because in general it lacks ambiguous definitions and "conventional wisdoms". w..
Reply by ●September 23, 20152015-09-23
On Wed, 23 Sep 2015 18:36:43 +0000, Simon Clubley wrote:> On 2015-09-23, Tim Wescott <seemywebsite@myfooter.really> wrote: >> >> I believe the original paper is here: >> >> http://static1.1.sqspcdn.com/static/f/702523/9458053/1290008042427/200008->> McCormick.pdf >> >> (Thanks Jacob) >> >> > Yes, I missed Jacob's original posting until I saw it quoted by you > after I posted. :-( > >> At least one of the points he noted about C makes me wonder if it isn't >> a biased instructor, rather than a bias between the languages, that was >> the primary cause of the problem. The point was in a section of why >> Ada was better than C, and reads: >> >> "Representation clauses for device registers (record field selection >> rather than bit masks)" >> >> But, unless you're using a horribly obsolete version of C, you can use >> bit fields in structures. And while this is, to some extent, excuse- >> making, even with horribly obsolete versions of C you can damned well >> hide all of your bit mask ugliness inside of nice tidy macros. >> >> > Good luck doing that in a reliable way on ARM with gcc when you are > accessing device registers. > > If you access a bitfield in the lower 8 bits of a register, the gcc > optimiser can turn that into 8-bit ldrb/strb opcodes instead of 32-bit > ldr/str opcodes and thereby causing the program to break if you need to > access your registers in units of greater than 8 bits.That's a very interesting comment, because that's basically How It Is Done here, and I've had several years worth of success on both ST and TI/ Luminary devices. I'm not sure if that's because of the way I define my bitfields (absolutely everything is defined as a struct of bitfields, then a union of that struct and a 32-bit integer), or if I've been lucky, or what. So it looks like: struct SPeriphRegisterBits { unsigned int bit0 : 1; unsigned int bits1_10 : 10; unsigned int bit11 : 1; unsigned int : 16; unsigned int bits28_31 : 4; }; union UPerihRegister { struct SPeriphRegisterBits bits; unsigned int all; } All of the various register definitions then get collected into a structure for the peripheral, which gets declared as "extern const", and defined in the linker command file.> Ada's not immune as well if you try accessing the registers directly > using bitfields; I helped someone out in comp.lang.ada a few weeks ago > with a similar issue. > > BTW, I've got a couple of Ada Issues open which talk about this and the > related issue of directly updating multiple bitfields as one > Read/Modify/Write operation instead of as multiple RMW operations. > > It would be nice to be able to do that in C as well instead of having to > use an intermediate variable (as you currently have to do with Ada as > well).It would probably require another built-in optimizer directive, like "volatile". For that matter, unless you define your intermediate variable as volatile, I could easily see a read/modify/write cycle that only modifies the lower 8 bits come through as an 8-bit access. Come to think of it (sorry for rambling, I'm just letting this stuff dribble out my brain as it comes to me) that may be what I'm doing with my elaborate struct -> union -> const struct construction. Whatever I'm doing, it works... -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Reply by ●September 23, 20152015-09-23
Am 23.09.2015 um 20:08 schrieb Tim Wescott:> "Representation clauses for device registers (record field selection > rather than bit masks)" > > But, unless you're using a horribly obsolete version of C, you can use > bit fields in structures.Yes, you can. But unless you're also in charge of configuring or designing the C compiler for them to be used on, you can't rely on any particular mapping between the bit fields in a C struct and their physical address layout. That's because just about every single aspect of that mapping is implementation-defined (or worse). I.e. they're close to 100% unportable from one platform to the next. Even just flipping a single switch on the same compiler can completely jumble the entire, carefully tuned data layout. Now that's not too bad for a micro controller's internal registers, because data structure definitions for those will most likely be supplied by the compiler makers themselves, anyway. Or if they're supplied by the chip maker, there'll be some ABI specification they enforce, which ties down all the loose ends. But it is indeed quite bad concerning predefined data structures external to the CPU. Even some relatively experienced C programmers will believe they should use C structs and bit fields to write a driver module for an external device or, even more commonly, implement a communication protocol. Well, that won't work. And by the time they realize it, they will be so convinced of their original decision's correctness by "proof in the field", that they won't even be able to _see_ their error.> And while this is, to some extent, excuse- making, even with horribly > obsolete versions of C you can damned well hide all of your bit mask > ugliness inside of nice tidy macros.Absolutely.
Reply by ●September 23, 20152015-09-23
On 2015-09-23, Tim Wescott <seemywebsite@myfooter.really> wrote:> On Wed, 23 Sep 2015 18:36:43 +0000, Simon Clubley wrote: >> Good luck doing that in a reliable way on ARM with gcc when you are >> accessing device registers. >> >> If you access a bitfield in the lower 8 bits of a register, the gcc >> optimiser can turn that into 8-bit ldrb/strb opcodes instead of 32-bit >> ldr/str opcodes and thereby causing the program to break if you need to >> access your registers in units of greater than 8 bits. > > That's a very interesting comment, because that's basically How It Is > Done here, and I've had several years worth of success on both ST and TI/ > Luminary devices. I'm not sure if that's because of the way I define my > bitfields (absolutely everything is defined as a struct of bitfields, > then a union of that struct and a 32-bit integer), or if I've been lucky, > or what. >Do your MCUs _require_ register access in units of 16/32 bits ? If so, you may be doing something which works for now, but may not work in the future. It might be worth having a quick look with objdump just to be sure. I have personally had this happen to me and it broke my code due to the register access size constraints no longer been true.> So it looks like: > > struct SPeriphRegisterBits > { > unsigned int bit0 : 1; > unsigned int bits1_10 : 10; > unsigned int bit11 : 1; > unsigned int : 16; > unsigned int bits28_31 : 4; > }; > > union UPerihRegister > { > struct SPeriphRegisterBits bits; > unsigned int all; > } > > All of the various register definitions then get collected into a > structure for the peripheral, which gets declared as "extern const", and > defined in the linker command file. >This is a bit more involved than what I was doing. I wonder if this is what is saving you for now. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
Reply by ●September 23, 20152015-09-23
On 15-09-23 00:38 , Tim Wescott wrote:> Latterly, on USENET, I have run into, and even drawn, quite a few > comments along the lines of "well, if you'd programmed that in Ada you > wouldn't have that bug" -- which might be true: maybe you wouldn't have > any bugs, or maybe you'd have other bugs, instead.For sure it's possible write buggy Ada code. But also, some errors that can be made in C are detected as compile-time errors in Ada. A good static checker for C, or a good C compiler, could also detect many of those errors. Perhaps these errors are of a kind that good and experienced C programmers have learned to avoid, so the benefit will vary. For best results, the programmer must adopt an Ada mindset, which means lots of application- and subject-specific types. A program that uses Standard.Integer for all integer variables will not benefit from strong typing. The Zeigler/Rational paper, which was referenced in other posts, shows lower bug densities for Ada code than C code, in that environment, in that application.> I suspect that the most vocal proponents of Ada as being not just > technically better, but the be-all, end-all are not representative of the > entire Ada community -- but they certainly seem to be the loudest, and > hence, like right-wing "Christian" nuts vs. quiet and devout church- > goers, end up representing the entire community in the eyes of the public.A good analogy :-)> When Ada came out it was touted as being almost magically self-correcting > and naturally platform independent. It was the platform independence, in > fact, which was a large part of the reason that the DoD started insisting > on it. Then, about a decade later, it came out that nearly all of the > installed Ada code base was, in fact, highly dependent on the hardware > for which it was written,Isn't that natural for embedded systems interacting with specific hardware and peripherals? Even for non-embedded systems on mainframes, at that time the more advanced OS services were often system-specific and easily made applications non-portable. I believe that Ada supports portability better than C (assuming compilers exist...), but it is also easy to write unportable Ada. Portability takes an effort, less in Ada than in C, but still.> and that -- astonishingly enough -- at times it > seemed that the software designers had gone out of their way to make the > code that they were writing only work on the hardware that their company > was selling."Customer capture"... not limited to Ada, nor even to software...> It was a prime example of my argument with the more simple-minded members > of the "Ada is better" camp -- Ada may make it marginally _easier_ to > write better code. However, if you want good, robust, portable code you > have to make it happen. There is no magic language that'll make it > happen -- only language-independent diligence and hard work.Agreed, except that to me the difference is more than marginal. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .
Reply by ●September 23, 20152015-09-23
On 15-09-23 10:11 , David Brown wrote:> Here's a couple of "shoot yourself in the foot" jokes:Here I go again, ruining a funny story by taking a factual view. I enjoy satirical jokes about programming languages, but they must have some underlying truth in them. For example, I remember a comparison of programming langages with car models (sorry -- can't find a reference, I think it was in ACM SIGPLAN Notices long ago), in which Ada was compared to an army-green Mercedes, with no options as to colour or features, with the comment "if it is good enough for the generals, it is good enough for you". APL was compared to a bus, where lots of passengers can travel at once, organized into rows and columns (of seats). Both comparisons are founded in true points: the fact that Ada was very standardized (even trademarked), and had its roots in the military; and the fact that APL works on matrix data. But the shoot-in-foot joke that you quote has no factual basis, or the factual basis cannot be turned into a joke that satirizes Ada.> Ada > > If you are dumb enough to actually use this language, the United > States Department of Defense will kidnap you, stand you up in front of a > firing squad, and tell the soldiers, "Shoot at his feet."The US DoD was happy to have people use Ada -- they even tried to mandate it. So, no basis in fact.> After correctly packaging your foot, you attempt to concurrently > load the gun, pull the trigger, scream, and shoot yourself in the foot.Yes, Ada provides packages and concurrency. So?> When you try, however, you discover that your foot is of the wrong type.That is a good, no? So where is the joke?> You scour all 156e54 pages of the manuals, looking for references to > foot, leg, or toe; then you get hopelessly confused and give up.The Ada 2012 Reference Manual is 961 pages. The C11 Standard (N1570) is 701 pages. Not much difference, considering that Ada has many more features than C11 -- for one thing, a standard container library, which consumes about 100 pages of the Ada 2012 RM. Perhaps the joke stems from the days when one would compare the Ada 83 Reference Manual with the K&R C book. That is a bit stale...> You sneak in when the boss isn't around and finally write the damn thing in > C. You turn in 7,689 pages of source code to the review committee, > knowing they'll never look at it, and when the program needs > maintenance, you quit.What is the point here? That C is less maintainable than Ada, as indeed suggested by the Zeigler/Rational study? But then it is not making a joke about Ada, is it? It seems to me that this joke needs a bit of work :-) -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .
Reply by ●September 23, 20152015-09-23
On 15-09-23 10:11 , David Brown wrote:> Here's a couple of "shoot yourself in the foot" jokes:Here I go again, ruining a funny story by taking a factual view. I enjoy satirical jokes about programming languages, but they must have some underlying truth in them. For example, I remember a comparison of programming langages with car models (sorry -- can't find a reference, I think it was in ACM SIGPLAN Notices long ago), in which Ada was compared to an army-green Mercedes, with no options as to colour or features, with the comment "if it is good enough for the generals, it is good enough for you". APL was compared to a bus, where lots of passengers can travel at once, organized into rows and columns (of seats). Both comparisons are founded in true points: the fact that Ada was very standardized (even trademarked), and had its roots in the military; and the fact that APL works on matrix data. But the shoot-in-foot joke that you quote has no factual basis, or the factual basis cannot be turned into a joke that satirizes Ada.> Ada > > If you are dumb enough to actually use this language, the United > States Department of Defense will kidnap you, stand you up in front of a > firing squad, and tell the soldiers, "Shoot at his feet."The US DoD was happy to have people use Ada -- they even tried to mandate it. So, no basis in fact -- really contradictory to fact.> After correctly packaging your foot, you attempt to concurrently > load the gun, pull the trigger, scream, and shoot yourself in the foot.Yes, Ada provides packages and concurrency. So?> When you try, however, you discover that your foot is of the wrong type.That is a good, no? So where is the joke?> You scour all 156e54 pages of the manuals, looking for references to > foot, leg, or toe; then you get hopelessly confused and give up.The Ada 2012 Reference Manual is 961 pages. The C11 Standard (N1570) is 701 pages. Not much difference, considering that Ada has many more features than C11 -- for one thing, a standard container library, which consumes about 100 pages of the Ada 2012 RM. Perhaps the joke stems from the days when one would compare the Ada 83 Reference Manual with the K&R C book. That is a bit stale...> You sneak in when the boss isn't around and finally write the damn thing in > C. You turn in 7,689 pages of source code to the review committee, > knowing they'll never look at it, and when the program needs > maintenance, you quit.What is the point here? That C is less maintainable than Ada, as indeed suggested by the Zeigler/Rational study? But then it is not making a joke about Ada, is it? It seems to me that this joke needs a bit of work :-) -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .
Reply by ●September 23, 20152015-09-23
Hans-Bernhard Bröker wrote:> Am 23.09.2015 um 20:08 schrieb Tim Wescott: >> "Representation clauses for device registers (record field selection >> rather than bit masks)" >> >> But, unless you're using a horribly obsolete version of C, you can use >> bit fields in structures. > > Yes, you can. But unless you're also in charge of configuring or > designing the C compiler for them to be used on, you can't rely on any > particular mapping between the bit fields in a C struct and their > physical address layout. That's because just about every single aspect > of that mapping is implementation-defined (or worse).And that is just fine - you'll have* to adapt to an implementation dependent mapping in most cases using macros anyway. Within processor families - read endianness and what word sizes can be reliably read/written - the macros have to change too, so that's another mess :) *although most support 32 or 8 bit access in all cases, leaving only endianness. And some FPGAs are more or less lenient about this. In the past, I've built tools to manage all this for me, invoked as part of the make process. This for macro approaches as well as bitfields. I.e. they're> close to 100% unportable from one platform to the next. Even just > flipping a single switch on the same compiler can completely jumble the > entire, carefully tuned data layout. >No doubt. SO you have already committed to a nonportable thing - a register set - so a little more won't hurt too bad. IMO the readability is worth it. I just like: FPGA.reset = 1; better than SET_FPGA_RESET(1);> Now that's not too bad for a micro controller's internal registers, > because data structure definitions for those will most likely be > supplied by the compiler makers themselves, anyway. Or if they're > supplied by the chip maker, there'll be some ABI specification they > enforce, which ties down all the loose ends. > > But it is indeed quite bad concerning predefined data structures > external to the CPU. Even some relatively experienced C programmers > will believe they should use C structs and bit fields to write a driver > module for an external device or, even more commonly, implement a > communication protocol. Well, that won't work. And by the time they > realize it, they will be so convinced of their original decision's > correctness by "proof in the field", that they won't even be able to > _see_ their error. >:) You can very nearly *always* use bitfields, but it takes a bit of care. Assuming you're talking about an FPGA register set as "external to the CPU", there's always an additional parcel of risk. but it's not hard to write a test driver that tests all the fields with the struct mapped to just-memory, with a dump of that memory after each set. Then write a host machine script that connects to the target, executes this test, captures the output and verifies it for you. I say this because the usual "use macros" approach has produced old and hard to find bugs that were left to me to find - although the use of a scripting language to write the macros and round-trip test them might be just as good. TO wit: #if _ARCH_ARM_7_ #include <arm7/regmap.h> #endif #if _ARCH_ARM_9_ #include <arm9/regmap.h> #endif etc etc.>> And while this is, to some extent, excuse- making, even with horribly >> obsolete versions of C you can damned well hide all of your bit mask >> ugliness inside of nice tidy macros. > > Absolutely. >-- Les Cargill







