#avr | Logs for 2016-04-22

Back
[00:48:20] <dsal> If I want to do an ISR that just sets a boolean to true, what's the easiest approach? I see it's clobbering r24 when I make it naked. How do I prevent this from messing stuff up? i.e. will it always be r24? Is there A Better Way?
[00:48:40] <dsal> Er, I'd like it to be naked. I missed that part of the question.
[00:50:38] <Xark> dsal: If it is naked then it is up to *you* to save/restore any regs disturbed.
[00:51:12] <dsal> Yeah, I get that bit. I'm just not entirely sure how my assignment is getting done. The compiler chose r24. How do I take care of that register?
[00:51:46] <dsal> Sorry, communicating poorly. How do I take care of whatever register it chooses, assuming it won't always be r24.
[00:52:04] <Xark> dsal: Generally you either need compiler magic to force certain C locals into registers (or be very very fragile on compiler version and options) or use inline asm and have compiler select registers - which you save/restore.
[00:52:28] <Xark> dsal: Do you need C at all in ISR?
[00:52:50] <Xark> dsal: Are you going to call any functions (if so, you have a large list of regs that need to be saved)?
[00:52:53] <dsal> I guess not. I don't *need* it to be naked. I'm just learning junk and not sure how to handle this situation should it matter.
[00:53:06] <dsal> I have two ISRs that look approximately like this:
[00:53:09] <dsal> ISR(WDT_vect, ISR_NAKED) {
[00:53:09] <dsal> wdt_reset();
[00:53:09] <dsal> failsafe = true;
[00:53:09] <dsal> reti();
[00:53:09] <dsal> }
[00:53:22] <dsal> So, wdr isn't a big deal. it's the "failsafe = true" that seems dangerous.
[00:53:38] <Xark> Is that a memory location (global)?
[00:53:42] <dsal> yeah
[00:54:13] <Xark> What does wdt_reset turn into?
[00:54:31] <dsal> just the "wdr" op
[00:54:36] <Xark> Okay.
[00:54:37] <dsal> That seems particularly safe.
[00:54:48] <Xark> And reti is just reti, I assume?
[00:54:52] <dsal> right
[00:55:06] <dsal> The other part looks like this:
[00:55:07] <dsal> ldi r24,lo8(1)
[00:55:08] <dsal> sts failsafe,r24
[00:55:19] <Xark> So compiler is trashing r25 to load a true
[00:55:21] <Xark> r24
[00:55:23] <dsal> Yeah
[00:55:56] <dsal> I could clearly do this in asm, but it'd be kind of neat if there were a way to do this safely in C.
[00:56:22] <Xark> I think the clean thing to do is just have some inline asm that saves a register, does the store then restores the register.
[00:56:32] <dsal> OK. That's not unreasonable.
[00:56:40] <Xark> IOW, a tiny bit of inline asm just for the store.
[00:56:42] <dsal> This is completely unnecessary. heh
[00:57:06] <dsal> I'm mostly just playing golf.
[00:57:53] <Xark> No worries, just giving caddyshack advise here. :)
[00:58:08] <dsal> Thanks for the help.
[00:58:42] <Xark> The other option is to remove naked, but the compiler will save a slew of regs that don't really need to be saved.
[00:58:54] <Xark> (Conservative/paranoid)
[00:59:22] <dsal> Yeah. That's where I started. Like I said, this is completely unnecessary. :)
[00:59:23] <Xark> Although, might be semi-smart if you call no other functions (leaf fucntion).
[00:59:37] <dsal> Yeah. Since it's just an assignment, I thought it'd be cool.
[00:59:44] <Xark> It will still set zero and stuff I think.
[01:00:04] <dsal> I was doing this in another little thing I wrote which just set a bit in a port, so that ended up having no other side effects.
[01:00:18] <dsal> Bah: "Error: register number above 15 required"
[01:00:34] <Xark> If you code in asm, might as well try and be optimal (when possible/feasible). Otherwise get back to Javascript (or whatever). :)
[01:00:39] <dsal> ha
[01:00:42] <Xark> or for MCU rather
[01:00:57] <dsal> My day job is big databases. Like, TBs of RAM and PBs of disk.
[01:01:04] <Xark> Fun.
[01:01:04] <dsal> I'm saving scores of bits here.
[01:01:54] <Xark> I started my career with 128 bytes of RAM and 8-bits. Current game consoles are ~8GB and 64-bit (and monster GPUs etc.). :)
[01:02:13] <dsal> Some of the games are even better.
[01:02:24] <Xark> A few. :)
[01:03:57] <Xark> Would have killed for an AVR back in the day. :)
[01:04:27] <Xark> 16 Mhz and 32-registers - wow! :D
[01:04:43] <inflex> I remember the horrors of hand mapping/burning PLAs
[01:05:15] <inflex> I'm *very* comfortable now with things like AVRs, though I spend most of my time working with the T10 and 13 more than anything else.
[01:05:35] <Xark> inflex: Ouch. I was involved just a bit with that (most as guinea pig testing an accelerator card for an Apple ][).
[01:06:11] <Xark> T10 and T13 being ATTIny?
[01:06:24] <inflex> The most popular uC at the time was the 68HC11, I remember PICs coming on to the market but not finding myself drawn to them, toolchain was a pita
[01:06:33] <inflex> Xark, yes, Tiny10 & 13
[01:06:54] <inflex> I'd use more of the Tiny5 except that the 10 is cheaper anyhow.
[01:07:33] <Xark> I did a bit of 6809, and a ton of 68000 but not really 6800, 6801 or 6811 etc.
[01:07:54] <dsal> This looks weird to me: subi r24,lo8(-(1))
[01:08:54] <inflex> Xark, ja, I stepped out from the early 90's and didn't come back until about 2006, just as AVRs were starting to really kick in
[01:09:10] <dsal> I haven't done anything with asm since like, sometime in the 90s on my HP48.
[01:09:28] <inflex> Was a revelation for me to be able to program them with Linux tools, including gcc with C and use a 3 resistor programmer on a parallel port :)
[01:09:36] <Xark> dsal: That is a bit odd... I think that is just subtract -1 (i.e., add 1).
[01:09:49] <dsal> Yeah. I see there's no addi type thing.
[01:10:11] <dsal> I'm assuming I'm not cheating too much if I'm taking the compiler generated asm and shoving it into my files.
[01:10:34] <Xark> dsal: This is why humans can always win. :D
[01:10:54] <dsal> heh
[01:11:10] <inflex> Go and Chess say "nay"
[01:11:39] <Xark> Even if the compiler is really smart, you just need to tweaks its output to save a cycle to win. :)
[01:12:15] <Xark> Well, this is one of those "win if you move second" things. :)
[01:12:51] <dsal> It's coming with a bunch of junk I don't need. I'm not sure if it's really all that much, though... Just a few instructions. It's probably too much for my golf program. I want to keep it readable, and that's kind of cheating.
[01:13:11] <dsal> I ported it from arduino. It was like, 1300 bytes or so. Now it's 270.
[01:13:54] <inflex> oh well... arduino... that'll explain that
[01:14:33] <dsal> Heh. Yeah. It's quite different in implementation, too. The main loop is basically sleep_mode();
[01:14:44] <inflex> O_o
[01:14:54] <dsal> (it's all interrupts)
[01:15:37] <dsal> In arduino, it was loop and then pulseIn and maybe timeout on that and then read a pin to see if a button's being pressed and then write stuff out when things happen.
[01:15:39] <inflex> not my favourite way of doing things
[01:16:15] <dsal> The program's job is to turn up a pin if signal stops on another pin (i.e. RC failsafe). Then there's a button you can hold down for ~a second to disable it.
[01:16:23] <inflex> I just prefer to stay with straight C... sometimes some inline ASM for timing, or rather sequence critical items (like resetting the watchdog).
[01:16:35] <dsal> So its job is to feed the watchdog with pin changes and if the watchdog fires, turn up the output.
[01:16:50] <dsal> More concretely: https://github.com/dustin/snippets/blob/master/c/avr/failsafe/failsafe.c
[01:18:09] <inflex> don't know why, but _BV() has always narked me
[01:18:12] <dsal> I've got a few nice ws2812 things I've done, but FastLED does not seem to like not being in arduino at all. I guess I could write my own.
[01:18:23] <inflex> something about underscore prefixes that drive me nuts
[01:18:26] <dsal> _BV is silly, but I'm going to mess it up less than 1<<
[01:18:37] <dsal> Yeah, there are weird underscore prefixes about.
[01:19:11] <inflex> Throwback perhaps from the old UNIX/C days where underscore prefixes were usually "You've entered in to hell"
[01:19:25] <dsal> The worst part of that is that PORTX |= (1 << 3); translates into sbi PORTX, 3
[01:20:01] <dsal> Yeah. it's all foreign to me. I'm not fighting with stuff yet.
[01:20:29] <Xark> I heard that originally _BV was there due to a compiler bug...
[01:20:49] <Xark> The sbi thing is an optimization "feature". :)
[01:20:52] <inflex> interesting, always wondered why it picked up that name
[01:21:15] <inflex> though "why not just BV()" if they're going to try 'simplify' stuff
[01:21:32] <inflex> for now though, the fingers do the (1<<x) faster than I can tell them to do _BV()
[01:21:33] <dsal> I think it's fine. I just wish they gave me the stupid sbi directly instead of that weird port write |= that looks like it's doing something else.
[01:22:11] <dsal> So, some of the asm code says eor rx,rx and some says clr rx
[01:22:28] <dsal> clr is documented to be eor rx,rx. "risc" I guess.
[01:22:46] <inflex> ja, I've often wondered what the decision tree is like to opt between clr vs eor rx,rx etc
[01:23:58] <Xark> dsal: It is worse than that, AVR asm manual lists the pseudo ops, but often doesn't mention it is just an alias (so you have to compare hex codes to know). :)
[01:25:45] <Xark> (or disassemble)
[01:35:26] <WormFood> https://en.wikipedia.org/wiki/Atmel_AVR <-- they mention some of the pseudo opcodes
[01:35:48] <WormFood> CLR is pseudo-op for EOR R, R; and SER is short for LDI R,$FF.
[01:41:28] <Xark> Hmm, COM I think too (EOR #0xff)?
[01:44:52] <dsal> subi r24,lo8(-(-1))
[01:44:53] <dsal> lol
[01:47:06] <Xark> Okay, that is funny. :)
[01:47:22] <dsal> That's like, a triple negative.
[01:47:44] <Xark> Back-end might be missing a bit of constant sub-expression elimination. :)
[01:48:30] <dsal> I tried turning a ++ thingy into a -- thingy and my program got bigger.
[01:48:49] <WormFood> By how much? 2 bytes?
[01:48:57] <WormFood> avr-gcc is pretty fuckin' impressive.
[01:49:28] <dsal> Yeah. It grew two bytes. I'm not entirely sure where, but that's my golf program, so I'll just not do it.
[01:49:57] <dsal> I thought there was a jump-if-zero or something.
[01:56:54] <dsal> What does "implicit declaration of function 'asm'" mean I did wrong?
[02:07:30] <Xark> dsal: Not using funky gcc inline assemble syntax?
[02:07:43] <Xark> assembler*
[02:07:45] <dsal> It worked in one program, but not this one. c++ vs. c
[02:08:08] <dsal> The C stuff is kind of weird. I'm trying to figure out how to pass in args and stuff.
[02:08:49] <Xark> I usually use: __asm__ __volatile__ ("...");
[02:09:06] <dsal> Yeah, that's working OK here.
[02:09:12] <dsal> But getting variables in and out is kind of sucking.
[02:09:24] <Xark> You may find http://www.nongnu.org/avr-libc/user-manual/inline_asm.html helpful.
[02:09:26] <dsal> Not even variables, really -- just like, the ports and registers I'm trying to use.
[02:09:36] <dsal> Sort of. I don't know what "I" means, and I can't seem to pass in a port that way.
[02:09:39] <Xark> Yes, it is a big PITA. :)
[02:10:03] <Xark> That link has some clues, but it is still a bit of a crappily documented area.
[02:10:23] <dsal> Maybe I should just try a .S file.
[02:10:31] <dsal> For the next round of golf.
[02:10:44] <dsal> I know which particular instructions will serve me better here. Just don't know how to type them into the machine. heh
[02:10:48] <Xark> dsal: In some ways a lot easier. This is why I was asking earlier if you *needed* C. :)
[02:11:19] <dsal> Maybe I'll try when I've got a nearby computer.
[02:11:23] <dsal> I'm trying to redo this one: https://github.com/dustin/snippets/blob/master/c/avr/failsafe/failsafe.c#L58-L72
[02:11:55] <dsal> It's doing some weird stuff with subi and junk. I could just use inc and immediately compare. I don't need to store the value since if it's > 30, I'm just going to shut down all the things.