sunnuntai 28. tammikuuta 2018

Everything's fine.


You know, there's something oddly familiar sounding with the windows defender notifications...



Oh, wait, I figured it out!



'Nuff said.






keskiviikko 24. tammikuuta 2018

Write it again, Tony.


Has Windows ever crashed on you when working? Oh, don't bother lying, we both know damn well it has. Numerous times. Less, lately, but still. There is a reason I mostly kept away from Windows 3 and 9x series, and only started taking it more seriously when Windows 2000 hit the market.

But has it crashed on you so bad it wiped out your project too? Well, Windows 10, with its newest feature update installed just did that to me.

I was playing around with new features of C++Builder 10.2, trying to figure out how to write an program that runs on Windows and Phones.Well, on Android, at least.

And then suddenly Windows froze completely. This isn't anything new (to me), so after few seconds of waiting - if it just were nice enough to come around by itself (don't look at me like that, it has happened. Not often, but few times...) - I just killed power and started over. (well, I tried common three-finger salutes first, of course, with no effect)

Only to find that just about all of the files I had open when Windows froze were ... corrupted. Half a dozen project files, gone. Thanks, Windows, great service.

Not a major loss, this being mostly things I was playing with, figuring out how they work together, but nevertheless, writing it all over again would be annoying at best. Granted, this doesn't happen too often, not these days, but whenever it happens, it's still a real PITA.

Oh, as I found out just few moments later, Builder keeps backups. So loss wasn't as bad as I expected first, just latest few dozen lines or so, but it's still always annoying to re-write everything.

And to be fair, Windows doesn't crash even close as often as it used to, these days.


torstai 18. tammikuuta 2018

Dirty C explained

For veterans this is easy, but this is the code I posted last time:

if ( ((unsigned int (*)(void))val)() )
   return;
 
Simply put, this takes a variable 'val', casts it to function pointer (of a function returning unsigned int and taking no parameters, or 'unsigned int fn(void)'), calls it, and if return value is nonzero, returns immediately from this function.

Specifically, cast and calling of function are done in this part:

((unsigned int (*)(void))val)()

Now, this seems very dirty indeed, and function pointers in C often seem to get a lot of bad rap for being dangerous and unsafe. I give you the first part; syntax for function pointers in C is nasty and complex, and can be source of huge compiler angst while you struggle to get the syntax just right. This is why you typically would use a typedef to make the syntax more easier to write - and read.

But dangerous? Not really, not any more than any other feature of C anyway. Aside the syntax already covered, the usage of function pointers is no more complex or dangerous than using any normal pointers. And sometimes they can be extremely useful, for example allowing you to write kind of pseudo-object oriented code with polymorphism and other fun stuff that occasionally can make life so much easier when dealing with complex structures. And in a project you want to hide these complexities behind somewhat simpler API anyway, further hiding the nasty parts from view.

So don't fear function pointers in C, or pointers in general. They just look scary, but they really aren't. As long as you keep the usual security rules in mind.





lauantai 13. tammikuuta 2018

Dirty C


Sometimes C can make me feel ... dirty ... for writing code that should be relatively straightforward.

Case in point:

if ( ((unsigned int (*)(void))val)() )
   return;

I actually had to look up the syntax for that since this was the first time I actually have done this kind of operation, ever. Guess there is first time for everything...

(what? What this does, you want to know? I'll explain that in the next post ...)


maanantai 8. tammikuuta 2018

Interesting bug tracking session.


Recently I was testing a new a board I was working on. I already knew that I need to make some minor changes here and there before committing to next iteration I wanted to check the remaining parts of the board. So far there was nothing major, few component changes, few tweaks here and there.

So I was going through thing quickly. Write small software stub to test a piece of hardware, upload, run, seems to be working, next... Until I got to a certain radio module. And it just crashed the software. Based on software traces (see this post about that) it seemed to crash in middle of short delay loop. Same loop that is used everywhere in same code.

...what?

This just didn't make any sense. I have said it before, I am not fan of embedded debuggers, but once again I had to dive in. So I traced the offending code and whenever software hit this one specific instruction it crashed.

The instruction: (ARM assembly, exact format IIRC)

str r3,[r0, #20]

Store contents of register r3 to memory, address (r0+20).

...what?

Everything about this instruction is correct. Register being stored, address where it is to be put to, no errors there. And still it just crashes. Every single time. Mind you, at this point I had fiddled with the code somewhat, so in the meantime the timings had changed slightly - yet it was crashing on this same instruction every time.

At this point I went back to my earlier hunch I had dismissed once already (after quick measurement that turned up nothing then.)  As this is a radio module we're talking about, it's a bit power-hungry. Especially at startup. And there are some large-ish (relatively speaking) capacitors there too. And part of the code that crashed was controlling the FET that fed power to the module...

Aaand yes, that was the issue, after a bit more careful measurement attempt. When power was enabled to the FET, there is a very short - few hundred microseconds long - drop in 3.3v rail. Not even a large drop - 300mV or so - but just enough to trigger external voltage monitor/reset circuit of the main MCU. Causing "crash". Not the kind of crash I was expecting but anyway.

So, is this board pulling that much current during startup that it actually makes power rail sag that badly? Doesn't sound likely but it seemed so. So I added some caps to supply side of mentioned FET. Then some more caps. And more. No change.

Feed the chip power directly. It takes 200mA, 500mA, 1A? No, this can't be right anymore. So on another hunch, take out multimeter and do some resistance measurements... Aaaand right. Supply of this module is shorted to ground.

This is professionally assembled board, by the way, with machine pick-and-place and reflow soldering. Should be all good, but guess not.

This module comes in QFN-type package, meaning that contacts are underneath it, completely inaccessible. Pitch isn't exactly tiny - 1.25mm, but the contacts have just 0.25mm of space between them. Very very close to each other. As it (obviously) had to be, this board I was testing happened to have mis-placed module, approximately 0.5mm away from where it should be. Just great.

Annoying this with these QFNs is that they're extremely hard to desolder, at least without destroying them in the process with excessive heat. Essentially impossible with my tools, unless I wanted to destroy most of the board too - and I do have relatively good hot air soldering station.

So I am kinda out of good options here. If this were production run, I'd be having a hard discussion with manufacturer (about 40% of the boards made had this issue), but as this is just prototype, it might be easier to just junk bad boards and try to figure out how to improve footprint of this part to be easier to solder. Not an easy job, there.