Random thoughts about software, hardware and electronics. And other things too...
lauantai 24. helmikuuta 2018
Loop forever
I ran onto an interesting bug just now. I've this entire debug module (as in C source), highly configurable, that can be used with many of my projects. Since I don't really like to dive into JTAG debuggers unless I really have to, I like that debug module a lot. Over time I've build quite a few features in it that help me to get things done.
Just now I took a very simple piece of a branch from one project and moved it to another one. Simple copy-paste of already proven code, no problems whatsoever, right?
Not so. When I loaded this program to the MCU, it just hung immediately.
Since the only changes I had made were to this single module, approximate location of problem was immediately evident - those new changes. Just about 20 copied lines of code. Should be simple.
Yeah, not so. Cursory review of changes revealed nothing. Nothing wrong here. So, eventually I went with JTAG debugger route - which in this case means openOCD and GDB. Both of these are extremely powerful tools, but highly hampered by lack of usable (or maybe I should say, easily usable) GUI or IDEs for my purposes (I have mentioned that I'm kinda old-fashioned, preferring text editors and makefiles?) Wait, let me paraphrase that last: I haven't managed to find a GUI for them that I'd find usable enough, as there actually might be one I haven't seen or tried yet.
But anyway, after some debugging, these revealed that program had inserted it into infinite loop within this new code. I don't have the generated assembly handy here, but it essentially boiled down to:
<compare something with something>
<if not equal, jump to this same instruction again>
...what?
I readily admit, I am not familiar enough with ARM assembly to read it fluently. And I couldn't write my way out of wet paper bag [in assembly] either. No reason to, really, except these occasional cases when my expectations don't meet reality. And crashes, of course, as having pointer to offensive instruction is makes debugging so much easier.
The problem here was, the C code read something like this:
if (debug_string_array[0])
printDebug(debug_string_array);
debug_string_array[0] = 0;
No loops here. Yet program somehow entered infinite loop anyway. So what is going on here?
I dug a bit deeper then.
printDebug(char *str)
{
#ifdef NO_SYNCHRONOUS_DEBUG
printDebug(str);
#else
printDebugS(str);
#endif
}
Oh, right, there's the problem. Silly copy paste issue elsewhere in the code which just happened to be realized now, and compiler helpfully optimized the recursive part out, leaving just the infinite loop.
Although irrelevant here, synchronous debug, in this context, means that debug output is sent out immediately, before returning from function, as opposed to "asynchronous" where it's buffered and sent out via serial transmit interrupt. Both of these have their uses but I won't go there in depth right now, as it isn't the topic here.
Code above isn't the actual source, mind you, but quick, cleaned-up rewrite of it.
perjantai 16. helmikuuta 2018
Renewable fuels
At the moment I'm drooling to get a Kia Optima PHEV to replace our aging Skoda Octavia TDI. I'm looking at that model because that is just about the only similar car that has tow mount and relatively large cargo space. We've got two large dogs, after all. The car ain't cheap (and our government's lack of tax breaks worth a crap for hybrids certainly isn't helping), and if I were to do the strict cost/benefit math alone, I'd never, ever choose this car. But this isn't that simple.
But for a moment here, let's go back to current car, Skoda Octavia TDI 1.6, model year 2011. This is one of the "emission cheat" vehicles, and since it was pretty much necessary, I had it emission-fixed. In this case, this meant software update, along with installing of some kind of intake air flow filter that smoothes air flow or something.
The usual expectations were that there would be major loss of power of efficiency. As far as I can tell, neither happened. On the contrary, I haven't noticed any loss of power, and my recent road trip (work-related) actually had my best consumption ever; 3,3l/100km, or about 71-ish US-MPG on return half of the journey. Not too bad. Then again, whenever it's mostly short trips, like typical city driving, mileage seems lower than before; hovering around 6l/100km, so that might have been affected.
But back to the actual topic here;
These days there are news about renewable energy just about everywhere. Biofuel was used to fuel a car, or a plane, or whatever. And it always, with absolutely no exceptions, end up with someone commenting how much land area was used or energy was spent to refine that fuel. Obviously the idea is to compare this about oil-based fuels, where far less energy and/or land area is used.
This comparation is of course completely false. Oil-based fuels have had the energy spent already, millions of years ago. The energy that was spent back then is not renewable, nor is it re-usable, and it will also release lots of carbon now (in a very short period, as opposed to millions of years it took to "refine" it) causing serious damage here and now. Yet, somehow, this apparently doesn't count when comparing against biofuels. Curious, that.
Yes, biofuels do (at this moment) use lots of energy, and take lots of land to produce. But here is the thing; we are even now - when renewable energy is just starting to, well, get started - producing massive amounts of excessive energy with other them - namely solar and wind power. For running the electric grid alone, as it is now, these two types of power are ridiculously bad. They provide the most power then it is needed the least, or essentially at random times, thus needing huge backup supplies - which, at the moment, are mostly coal or LNG, with some hydro thrown in. Aside hydro (which is pretty much at its maximum at the moment anyway), these will just make our situation worse in the long run. So not good.
However, this excess power could be used directly for other purposes - like battery storage (which is seriously expensive), pumped hydro (likewise expensive up front and seriously limited by geography), or -- and I seriously like this idea - refining biomass for fuels whenever there is excess power.
Yes, it will still use a lots of land, but the thing is, there is lots of land that can't produce food suitable for human consumption, for whatever reason, but can still produce biomass. In the past these areas have been used for cattle or grazing, but now we could have a better use for that; biomass for fuels.
That, in my vision, is the future.
It doesn't mean that we get to live like this - wasting energy everywhere like there's no tomorrow - but at least we get to keep on living, with fairly comfortable lives.
Our western way is using way too much energy, in many forms. Each and every joule we can transfer from harmful fossils to renewables will be net win, in the long run. And that is the reason I want that plug-in hybrid. That'll allow me to reduce my fossil fuel usage (for moving around) by half or so, just by using electricity for those short 10km trips. And if I could get a personal biofuel refinery to go along with my array of solar panels -- well, even better!
perjantai 9. helmikuuta 2018
sizeof(wchar_t)
Buffer overflows aren't fun. This is why I always (when not using some more advanced interface) use something like this;
...
char buff[32]; snprintf(buff, sizeof(buff), "a=%d b=%s", a,b); ...
Unfortunately this doesn't work too well when you transition to wide chars;
...
wchar_t buff[32]; _snwprintf(buff, sizeof(buff), ...) ...
Note the second parameter. It should be number of characters, and not bytes as returned by sizeof. So that previously good old habit is now causing potential buffer overflow, not preventing it ...
perjantai 2. helmikuuta 2018
AD converter, try 1
Just recently I ran for the first time in a situation where I actually needed pretty high-precision AD converter for a specific measurement. Previously I had only used 10- or 12-bit converters, and even those were generally situated in less than optimal location on the boards (read: in middle of digital circuitry), and those designs weren't... great, so to say, so I was kinda nervous about this thing.
But nevertheless, it needed to be done, and so I took every single tidbit of information I had read from anywhere and applied it to this one board. Ground planes? Check. Low-noise power supply and reference? Check. Separate power supply for digital logic? Check. Truckload of ground vias? Check. And so on and so on. In the end I ended up with 4-layer board had scarcely more stuff on it than power supplies, AD converter chip itself , connectors and some passives. I might've gotten away with just two layers, but why push it too much.
And what I got out of it?
20 bits. 20 bits of clear, noise-free signal. This uses 3,3v reference, so this means about 3,15 microvolts per bit. And of course further averaging could bring noise down even further, but in this case, this result is a great success, but for my application this was easily enough. And board didn't even need second design round, it worked perfectly the very first time.
For a first attempt, I really think this was pretty nice result.
Tilaa:
Blogitekstit (Atom)