News for hackers. Stuff that matters.
Re:The descent to C by ChuckMcM on Monday January 27, 2014 @09:44PM (#7134974)
Shhhhhh! If you let them know how fun it is then everyone will want to be C programmers :-)

I got to use my crufty C knowledge to useful effect when I discovered that there is no standard system reset on Cortex M chips. That lead me to trying to call "reset_handler" (basically the function that kicks off things at startup) which I couldn't do inside an ISR because lo and behold there is "magic" in isrs, they are done in "Handler" mode versus "Thread" mode and jumping to thread mode code is just wrong apparently. C hackery to the rescue, hey the stack frame is standard, make a pointer to the first variable in the function walk backwards on the stack to return address, change it to be the function that should run next, and return. Voila, system reset.

The whole time I am going "Really? I have to look under your covers just to make you do something anyone might want to do?" As a respondent to one of my questions put it "ARM is a mixture of clever ideas intermixed with a healthy dose of WTF?"

Re:The descent to C by eckzow on Monday January 27, 2014 @11:36PM (#7135337)
I don't mean to be a party pooper since I've done my fair share of hacky workarounds in v7-M processors and it is always exhilarating when it works...

But since I'm a Cortex M fanboy I have to defend its reset capabilities :)

For your specific case, try something like

  volatile uint32_t *AIRCR = (volatile uint32_t*)0xE000ED0C;
  const uint32_t VECTKEY = 0x05FA << 16;
  const uint32_t SYSRESETREQ = 1 << 2;

  void take_reset()
  {
    *AIRCR = VECTKEY | SYSRESETREQ;
    __dsb();
    while(1);
  }
It's technically dependent on external hardware in your processor subsystem, but it should work if your implementer has half a brain (or, at least cares enough to read the integration manual). If it doesn't work, please flog your implementer publicly so that I can know to avoid them in the future...

Incidentally, even that tiny code snippet is uses a C extension (the __dsb intrinsic) which is either a great example of how C can be wielded to great power (I can generate raw instructions!) or how C is terribly handicapped (I need a special compiler extension or all my system code is horribly broken!). All depends on point of view, I guess...

Anyway, more info @ page 498, http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readi...

Re:The descent to C by ChuckMcM on Tuesday January 28, 2014 @01:53AM (#7135749)
I too had already been through that particular part of the ARM7-M manual, after coming up through the data sheet to the technical reference guide, to the Cortex M architecture manual, and yes to the base ARM7-M architecture specification.

There is "should" and "does" :-) I had followed the exact same sequence and discovered on my system it didn't cause a system reset. I escalated it a bit (in this case ST Micro) and the caveats came out, "Well if you system is correctly designed, if the actual reset pin isn't connected to something that is interfering, if the core is in a state where it can actually take a reset, ..." This being unlike pretty much every processor I've worked on, from PDP-8's, 11's, 10's, VAXen, IBM 360/370, Sun 1, 2, 3, 4, Motorola 6800, 68K, 68K, Z80, 8080, 806, Pentium *, the list goes on. Most actually have a reset instruction, usually privileged, to force a system reset. But the difference is that the reset sequence was guaranteed to force a system reset if it executed, all of those previous processors had a company that made the processor as opposed to simply licensed the processor to a third party. Since it is completely reproducible on my system I've got an action item to create a small test case for errata analysis.

Yes, that is the code they suggest, with assurances that it will work in pretty much any case. Except when it might not. It was a bit stunning for me, I still marvel at the notion. Like an add statement that will 99.999% of the time add its operands together[1] unless it doesn't.

[1] No there isn't such a thing in ARM it is just the way I hear "It will almost always reset the system."

Re:The descent to C by eckzow on Tuesday January 28, 2014 @03:49AM (#7136092)
Fair enough. The Cortex-M's that I've dealt with have generally been homed inside some larger chip, and so the "reset pin" notion was a bit more vague, and in such an environment ARM's stance makes a bit more sense as you really want the reset to reset the "subsystem" (including whatever other random hardware you glued to yourself today).

It's also true that ARM has heard some of these complaints, which is why there were steps toward standardizing some things--like, the SYSTICK interface--in v7-M. It's really been a step up since the ARM7TDMI, and I hope that it will continue with v8-M or whatever the next revision ends up being.

Personally, when I'm dealing with a discrete chip and I need to reset it I've found that the most reliable methods that don't set off the hack-o-meter too badly are to wait for or directly invoke watchdog hardware... but yes, that's essentially always device specific.

Re:The descent to C by ChuckMcM on Tuesday January 28, 2014 @11:46AM (#7138104)
That is a very good point! If you are building some SoC and the CPU is just some small part of it, "system reset" can in fact be a very vague notion. I hadn't really been thinking that way and in that context the ARM position does make sense. As another person pointed out offline there is the watchdog timer, if you wanted you could set it and halt. Then it would kick you with a reset.
Re:The descent to C by userbinator on Tuesday January 28, 2014 @07:36AM (#7136688)
From memory, the Z80 and x86 don't have a reset instruction. On a 286+ you can fake one by triple-faulting.
Re:The descent to C by stusmall on Tuesday January 28, 2014 @01:04AM (#7135631)
For anyone else curious on the __dsb() call, from ARM's docs:

The Data Synchronization Barrier (DSB) acts as a special kind of memory barrier. The DSB operation will complete when all explicit memory accesses before this instruction have completed. No instructions after the DSB will be executed until the DSB instruction has completed, that is, when all of the pending accesses have completed.

Re:The descent to C by diydsp on Monday January 27, 2014 @10:28PM (#7135139)
Exactly! Fortunately, the article didn't point out one of C's great advantages is that it's so lightweight it can fit into and run on all kinds of interesting systems where other languages are infeasible economically. Cortices rule!
Re:The descent to C by pjmlp on Tuesday January 28, 2014 @01:52AM (#7135748)
Except there are other safer languages to choose from, like Pascal and Basic compilers.

http://www.mikroe.com/mikropascal/

http://www.mikroe.com/mikrobasic/

Re:The descent to C by exDM69 on Tuesday January 28, 2014 @03:39AM (#7136062)
> Except there are other safer languages to choose from, like Pascal and Basic compilers.

I'm curious, why do you say "safer"? These are languages for microcontroller programming. The things you do there are bound to be "unsafe", like peeking and poking memory for memory mapped i/o and disabling/enabling interrupts.

Unless, of course, all the possible things (i/o, timers, interrupts, etc) are wrapped in some kind of "safe" api so you essentially don't have access to low level facilities any more. The Arduino programming environment is kinda like this but you can still cause bad things to happen and if all else fails, hang the device with an infinite loop.

Is there any backing for such claims of "safety"?

Re:The descent to C by weland on Tuesday January 28, 2014 @03:47AM (#7136082)
> I'm curious, why do you say "safer"? These are languages for microcontroller programming. The things you do there are bound to be "unsafe", like peeking and poking memory for memory mapped i/o and disabling/enabling interrupts.

There are things which are inherently safe by design in languages like Pascal -- e.g. in a naively-written program you can't write past the boundary of the UART RX buffer and thrash some other array in your program -- but your observation is fair.

Re:The descent to C by exDM69 on Tuesday January 28, 2014 @04:36AM (#7136223)
> There are things which are inherently safe by design in languages like Pascal -- e.g. in a naively-written program you can't write past the boundary of the UART RX buffer and thrash some other array in your program -- but your observation is fair.

Which, of course, you can accomplish in C by wrapping your UART buffer handling code in functions that do bounds checking. And I assume that a micro controller Pascal or Basic dialect will have some kind of peek/poke from/to arbitrary memory addresses that can be misused just as a pointer access in C.

Safety is hard to quantify and measure and calling one language safer than another sounds more like an opinion than a factual claim, especially in this context.

Re:The descent to C by acqq on Tuesday January 28, 2014 @05:32AM (#7136340)
The "out of the box" defaults of Pascals are something you have to explicitly develop, test and maintain in your C. Which means that even during the maintenance cycle, long after it's originally implemented, it can still break in your C.
Re:The descent to C by exDM69 on Tuesday January 28, 2014 @07:56AM (#7136756)
> The "out of the box" defaults of Pascals are something you have to explicitly develop, test and maintain in your C. Which means that even during the maintenance cycle, long after it's originally implemented, it can still break in your C.

Let's not confuse languages and libraries/apis here (that may or may not be shipped with the compiler). There are libraries for C and related languages (e.g. Arduino) that actually do give you a "safe" way to deal with the hardware on microcontrollers.

It's still easy to shoot yourself in the foot in C with a bad pointer access (esp. because there are no helpers to work with strings) but I don't really see how a Pascal dialect with peek/poke would be inherently better.

I do agree that buying one of these Pascal/Basic software products that come with a fancy standard library that does safe access to the hw may help writing safer software but I don't see how that is an inherent quality of the language.

Re:The descent to C by waps on Tuesday January 28, 2014 @09:03AM (#7137076)
Don't you think that pascal's standard safeties will prevent mistakes ?

1) array bounds checking (which can be used for safe hardware access instead of peek/poke)

2) pascal-style strings (with actual support for them, both in the language and in the standard library) (meaning a missing \0 doesn't erase the entire memory)

3) type-safe pointers

4) no pointer arithmetic

5) no preprocessor

...

Re:The descent to C by weland on Tuesday January 28, 2014 @10:08AM (#7137435)
> 1) array bounds checking (which can be used for safe hardware access instead of peek/poke)

How? Peek/poke at the wrong address will generate an error in any case, and any MMU-less platform worth using will have the memory-mapped peripherals into a lower region, where it doesn't get thrashed by writing past the end of a buffer. I have seen bugs occurring because of data located past a buffer getting thrashed, but I don't remember seeing one in the context of hardware access.

> 2) pascal-style strings (with actual support for them, both in the language and in the standard library) (meaning a missing \0 doesn't erase the entire memory)

That shouldn't happen in C, i.e. there are library routines you should use so that it doesn't happen. Not that string processing isn't a pain :-).

> 3) type-safe pointers

No complaints here :-)

> 4) no pointer arithmetic

That's not always good, but it does decrease the likelihood of certain types of bugs, so yep!

> 5) no preprocessor

Also yep :)

Re:The descent to C by acqq on Tuesday January 28, 2014 @05:29PM (#7140254)
2) "That shouldn't happen in C"

It happens every day and it will as long as there's C. Zero-terminated strings are part of the standard library and almost infinite number of other libraries. You can't pretend it doesn't exist as the most common convention.

For 1) see waps' comment with byte absolute.

One complete program from that time which uses that feature: http://kd5col.info/swag/INTERRUP/0019.PAS.html

Re:The descent to C by pjmlp on Tuesday January 28, 2014 @09:56AM (#7137367)
Additionally all those safety mechanisms can be turned off for performance, but only on the exact spot where it really matters, instead of being scattered all around the code.
Re:The descent to C by waps on Tuesday January 28, 2014 @10:26AM (#7137563)
Example of absolute array:

var EGAVGAScreen : Array[0..41360] of Byte absolute $A000:0000;

Et voila : bounds-checked memory mapped hardware access.

(note: the very well known "Crt" unit uses a memory mapped video buffer like this. So if you programmed a turbo pascal program, chances were good it was using this trick for screen output. Advantage : the speed is unbeatable)

Re:The descent to C by weland on Tuesday January 28, 2014 @06:42AM (#7136522)
> Which, of course, you can accomplish in C by wrapping your UART buffer handling code in functions that do bounds checking.

Of course, and you pay other hefty prices in Pascal or Basic for getting this sort of stuff "out of the box". Pascal isn't my favourite systems programming language, either :-).

Re:The descent to C by pjmlp on Tuesday January 28, 2014 @12:15PM (#7138267)
What hefty price?

There are zero features in C that Pascal and Basic dialects for system programming don't support. The only difference is that you need to turn safety off explicitly.

I was doing low level coding in Turbo Pascal before I even cared about C.

Re:The descent to C by weland on Tuesday January 28, 2014 @01:11PM (#7138645)
In terms of performance? None, assuming a well-written compiler. Depending on dialect you run into other issues though, such as the array size being part of the type signature, which is definitely not nice. The lack of adequate tooling and portability is another issue. Not strictly a problem of the language itself, but a problem you end up facing if you write low-level code in Pascal.

Don't get me wrong, I wrote low-level code in Pascal, too. It's nice and I probably wouldn't grumble too much if I had to do it again, but there's a bunch of stuff that comes in the same package with using something other than a language widely considered adequate for systems programming.

Re:The descent to C by pjmlp on Tuesday January 28, 2014 @02:35PM (#7139170)
Faire enough.

I do conceed that even though bashing C is a pasttime of mine, I would use it if it is the best option for a given project, depending on the set of factors to be considered for the said project.

In real life projects, there should be no place for tooling religion anyway,

Re:The descent to C by pjmlp on Tuesday January 28, 2014 @05:25AM (#7136326)
Languages that don't require MISRA for example, because many of those requirements are supported out of the box.
Re:The descent to C by csmithuk on Tuesday January 28, 2014 @03:46AM (#7136078)
In some cases we don't want safety. C can be safe or unsafe depending on how you approach a problem.
Re:The descent to C by userbinator on Tuesday January 28, 2014 @07:29AM (#7136662)
In some cases, we want freedom... and that's something that has been neglected a bit too much with new programming languages IMHO. Safety/security feels like it's the latest of the dumbing-down "let's treat programmers like idiots" fad.
Re:The descent to C by scott_s on Tuesday January 28, 2014 @10:08AM (#7137434)
I think the approach of languages like Rust, which enforce strict safety by default, but allow "unsafe" regions of code, is the correct way to go.

See http://static.rust-lang.org/doc/master/rust.html#unsafety

Re:The descent to C by Allan_Smithee on Wednesday January 29, 2014 @02:14AM (#7142466)
Or if you have any sense of history, languages like Modula-2/2+/3. (And undoubtedly a few (dozen?) others I'm unaware of.)

Nothing new in software development. All the "new" shinies are decades (!) old.

Re:The descent to C by pjmlp on Wednesday January 29, 2014 @02:30AM (#7142508)
Somehow young developers seem to think only C and C++ offer native features.

I wonder how we got sidetracked like that.

Re:The descent to C by Allan_Smithee on Tuesday January 28, 2014 @09:51AM (#7137331)
I submit as evidence 99.44% of software that has been released that programmers are, in fact, idiots.
Re:The descent to C by deletes on Tuesday January 28, 2014 @06:06AM (#7136418)
Can you give an example where you don't want safety and you aren't trying to hack? //curious
Re:The descent to C by csmithuk on Tuesday January 28, 2014 @07:10AM (#7136602)
Few of the top of my head:

1. Performance reasons. For example: zero copy data structures, mutable data structures, controlling data locality.

2. Direct memory mapped hardware access. For example: device drivers, kernel, embedded systems, microcontrollers.

3. Bitwise and machine specific conversions. For example: endianess conversions.

4. Structure type coercion. For example: object systems, tagged data structures etc.

Re:The descent to C by fanf2 on Tuesday January 28, 2014 @03:49PM (#7139606)
If you are doing unsafe or machine-dependent endurance conversion code, you are almost certainly doing it wrong. http://commandcenter.blogspot.co.uk/2012/04/byte-order-falla...
Re:The descent to C by deletes on Tuesday January 28, 2014 @05:02PM (#7140079)
Thank you for that link.

#leaves to check some old code

.

.

.

#comes back

Apparently my younger self knew what he was doing. ( The conversion is done correctly :shocked: )

Re:The descent to C by mcguire on Wednesday January 29, 2014 @11:38AM (#7144930)
Sometimes I wonder about Rob.

"In fact, C may be part of the problem: in C it's easy to make byte order look like an issue. If instead you try to write byte-order-dependent code in a type-safe language, you'll find it's very hard. In a sense, byte order only bites you when you cheat."

Re:The descent to C by csmithuk on Wednesday January 29, 2014 @04:55AM (#7142989)
That's a great article - thanks for posting.
Re:The descent to C by fanf2 on Wednesday January 29, 2014 @06:05PM (#7147779)
"endurance"?! Damn you, autocorrect.
Re:The descent to C by pjmlp on Tuesday January 28, 2014 @08:18AM (#7136842)
All of those examples are possible in safe systems programming languages like Modula-2 and Ada, with the difference that only the tiny spot where it matters is marked explicitly unsafe.

Whereas in C there is no way to distinguish between unsafe and safe code.

Re:The descent to C by numeromancer on Tuesday January 28, 2014 @10:08AM (#7137432)
2. Direct memory mapped hardware access. For example: device drivers, kernel, embedded systems, microcontrollers.

Of course doing this usually means your code isn't portable, sometimes not even to other versions of the same compiler. I often wish C had a defined order for bitfields, for example.

One of the things I do to help debug & test embedded code is to factor out code which isn't dependent on the hardware platform (eg communication protocols) into a library, and compile it for, and write test programs to test them on, the host. So even embedded code is often best written to be as portable as possible.

Re:The descent to C by mcguire on Wednesday January 29, 2014 @11:47AM (#7144989)
Oddly enough, I've spent the last week playing around with type-agnostic garbage collection.
Re:The descent to C by coldtea on Tuesday January 28, 2014 @02:19PM (#7139075)
Hehe, as soon as I read the comment, I knew who it would be!
Re:The descent to C by brokenparser on Tuesday January 28, 2014 @02:06AM (#7135793)
And they're all way too slow for what I'm doing.
Re:The descent to C by pjmlp on Tuesday January 28, 2014 @02:15AM (#7135822)
Why are they slow?

If you are going to invoke the usual C FUD about bounds checking and such, you can disable them on parts where performance REALLY matters.

Plus all compilers share the same backend.

Re:The descent to C by weland on Tuesday January 28, 2014 @03:44AM (#7136071)
However, they are far more wanting on the tooling side.
Re:The descent to C by pjmlp on Tuesday January 28, 2014 @05:27AM (#7136333)
Not when buying a commercial version of such tools.
Re:The descent to C by FigBug on Tuesday January 28, 2014 @10:47AM (#7137712)
Yuk. I'd rather program in assembly than ever use those buggy compilers again.
Re:The descent to C by timthorn on Tuesday January 28, 2014 @04:25AM (#7136193)
Re: your ARM comment - had you noticed who wrote the article?
Re:The descent to C by ChuckMcM on Tuesday January 28, 2014 @01:18PM (#7138688)
Who Simon Tatham? I've been a fan ever since I modified the PuTTY code to work in an embedded system. I did not realize he was at ARM these days, gives me hope.
Re:The descent to C by Svip on Monday January 27, 2014 @11:50PM (#7135387)
I want to be a C programmer now! (I am actually serious, this article has inspired me to try some more C; which I have been seriously neglecting.)
Re:The descent to C by csmithuk on Tuesday January 28, 2014 @03:48AM (#7136088)
Do it; you will never regret it.

I primarily write C# (for cash reasons) but my heart will always be with C.

Re:The descent to C by lmm on Tuesday January 28, 2014 @05:45AM (#7136370)
> Do it; you will never regret it.

Citation needed. I hate hate hated C and am very glad to have seen the back of it.

Re:The descent to C by csmithuk on Tuesday January 28, 2014 @07:17AM (#7136623)
I too hated C once to the point I actually kicked a PC over on its side out of anger. I never understood pointers, structures and string manipulation. I genuinely hated it and wanted it to go away. I deleted all the code I'd written then went for a walk.

Then suddenly... click.

Suddenly, in my mind appeared an abstract model for it. It was complete and possible for one person to understand.

Since then I understand what I'm doing rather than know how to drive the compiler.

That has never happened for any other language I've written and that includes Z80+6502+X86 ASM, C++, C#, VB3-6, PDS7, ksh, Python, Perl and PHP to name a few. Assembly is close but not abstract enough.

Enlightenment is probably the best word to describe it.

Re:The descent to C by dsuth on Thursday January 30, 2014 @05:36AM (#7149946)
I never had the click about pointers, I guess the way they were introduced to me just made them feel intuitive.

I'll never forget the time when programming changed from mechanically entering statements, to controlling the flow of data through a program though (also in C). Definitely a brain-expanding experience :)

Re:The descent to C by mikkom on Tuesday January 28, 2014 @02:19PM (#7139074)
Read this book then. It's the best book about any programming language that I have read.

http://cm.bell-labs.com/cm/cs/cbook/

The following is a link to some university course page that has the book as pdf

http://www.cs.ucsb.edu/~buoni/cs16/The_C_Programming_Languag...

Re:The descent to C by adobriyan on Tuesday January 28, 2014 @07:09AM (#7136595)
> I want to be a C programmer now!

Don't hold your breath.

Re:The descent to C by d4rti on Tuesday January 28, 2014 @05:14PM (#7140169)
I've been enjoying Zed Shaw's Learn C the Hard Way http://c.learncodethehardway.org/book/
Re:The descent to C by nevvvermind on Tuesday January 28, 2014 @03:36AM (#7136050)
Ha. Me too. I always felt a little intimidated by it, but I can't pass the chance to actually make my own structures.
Re:The descent to C by deletes on Tuesday January 28, 2014 @06:09AM (#7136432)
Do it. With modern C and a huge number of libraries you can be as productive as in any other language.
Re:The descent to C by couchand on Monday January 27, 2014 @10:13PM (#7135081)
Cortex as in Cortex Semi?
Re:The descent to C by ChuckMcM on Monday January 27, 2014 @10:37PM (#7135158)
Cortex M series, it's the "controller" variant on the ARM architecture (in my case the M4F)
Re:The descent to C by couchand on Monday January 27, 2014 @10:39PM (#7135166)
Sorry, lame Primer reference. Note to self: make a more complete joke next time.
Re:The descent to C by wfn on Tuesday January 28, 2014 @01:43AM (#7135719)
I hope you're not implying that any day is unimportant at Cortex Semi.