How do I get my AWU ISR into the interrupt vector table? [SOLVED — RTFM!]

Jimmus
Wed Jan 10, 2018 8:03 pm
Trying to get Auto Wake Up to work. I have tried everything I could find, and I eventually got it to work but not in a way that I should have to. Long story short, I ended up pretty much talking to the controller registers directly.
// Tests AutoWakeup so we can use it for power saving mode.

#define ledPin PB5

void setup() {
pinMode(ledPin, OUTPUT_FAST);
digitalWrite(ledPin, HIGH); // Turn off the LED
AWU->APR = 62; // Set up to wake up in 0.5 seconds
AWU->TBR = 11;
}

void loop() {
digitalWrite(ledPin, LOW); // Turn on the LED
delay(1000);
digitalWrite(ledPin, HIGH); // Turn off the LED
AWU->CSR = 0x10;
halt();
digitalWrite(ledPin, HIGH); // Turn off the LED
for (;;); // Loop here forever
}

volatile unsigned char reg;

INTERRUPT_HANDLER(AWU_IRQHandler, ITC_IRQ_AWU)
{
reg = AWU->CSR; // Reading AWU_CSR1 register clears the interrupt flag.
}


Pito
Wed Jan 10, 2018 9:41 pm
Afaik the vector table is copied (upon reset) from flash (0x08000000 region) into sram (starting 0x200000XX).
There is the SCB_BASE->VTOR reg which points to the start of the vector table in sram.
So you can write there what you want, I think.

PS: long time back I was setting the new vector table origin like this
//SCB_BASE->VTOR = (volatile uint32_t) 0x2000FC00;
*(int volatile*)0xE000ED08 = (volatile uint32_t) 0x2000FC00;


Jimmus
Thu Jan 11, 2018 1:04 am
@Pito I’m not sure we’re using the same hardware platform. I don’t seem to have memory at those addresses. I can’t find any mention of SCB anything or VTOR either. Grep doesn’t show any matches in the entire package.

mrburnette
Thu Jan 11, 2018 3:42 am
A recent discussion of changing the vector table:
http://stm32duino.com/viewtopic.php?f=3&t=1848

ahull
Thu Jan 11, 2018 4:47 am
[Jimmus – Thu Jan 11, 2018 1:04 am] –
@Pito I’m not sure we’re using the same hardware platform. I don’t seem to have memory at those addresses. I can’t find any mention of SCB anything or VTOR either. Grep doesn’t show any matches in the entire package.

@Jimmus – You could well be correct, what hardware platform are you using, and which arduino core are you using (maple or …) ?


Jimmus
Thu Jan 11, 2018 5:28 am
Oh. Sorry. I thought posting in the STM8 sub-forum would indicate which hardware I’m using.

It’s a STM8S003F3P6 minimum system development board. I’m using the sduino core, STM8S103F3 breakout board option in the IDE. The sdcc compiler.


dannyf
Thu Jan 11, 2018 1:43 pm
You are asking two questions.

1. How to put your it into the vector table? That is compiler specific. You will have to look into your compiler manual for the right syntax.

2. How to get your code to work? It is likely your is is working but the rest of your code isn’t. I would keep the main loop clean of all but half() and flip a led in the isr.


edogaldo
Thu Jan 11, 2018 2:09 pm
[Jimmus – Wed Jan 10, 2018 8:03 pm] –
The problem is that after it wakes up it isn’t executing the code that it’s supposed to be running.

Are you saying that the sketch doesn’t run the neverending empty loop?
Can it be that resuming from halt or something else (i.e. a watchdog) triggers a system reset?


Jimmus
Thu Jan 11, 2018 5:26 pm
@edogaldo Yes I’m saying the sketch doesn’t run the neverending empty loop. Or any of the code right after the halt() instruction. Notice that code is supposed to turn the LED *OFF* and then enter the forever loop. Behavior is that the LED turns ON after 0.5 seconds. I’m pretty sure it isn’t running my ISR because I have put other code in there to test, and it didn’t execute. But it doesn’t reset either — then it would blink the LED again like it did the first time. It just turns the LED on. And then nothing else.

@dannyf Yes, I want to know how to put the address of my ISR into the interrupt vector table. I’m pretty sure the rest of my code is working. When I modify the .hex file with my editor and insert the address of my ISR into the interrupt vector table, it works perfectly. I want to know how to get the compiler to do that.

There are other ISRs in the interrupt vector table. Specifically, External Interrupts, and UART TX and RX. As far as I can tell, I did it the same way they did. I grepped every occurrence of anything that had to do with vector, interrupt, or IRQ, and tried them all.

But that’s a really good suggestion about reading the manual. I will go do that right now.


Jimmus
Thu Jan 11, 2018 5:40 pm
Well, RTFM!
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a prototype of the isr MUST be present in the file that contains the function ‘main’.
From main.c:#include <Arduino.h>

// make sure to define prototypes for all used interrupts
//#include "stm8s_it.h"


dannyf
Thu Jan 11, 2018 7:05 pm
Time and again, reading the manual has been the most effective way of understanding how a compiler works.

Btw, that requirement of declaring the ISRs in the main.c is a weird one. In my book it makes the compiler not workable.


zmemw16
Thu Jan 11, 2018 8:18 pm
totally random thought, in a way isn’t it a forward declaration so maybe main.h or is it explicitly stated as being in main.c
or it’s being used much earlier than you think, maybein the startup code ?
srp

Jimmus
Thu Jan 11, 2018 8:57 pm
Yeah, it is a pretty strange requirement. Not at all intuitive.

@zmemw16 well, that’s what the manual said — “a prototype of the isr MUST be present in the file that contains the function ‘main’.” Main.c included <Arduino.h>, which included “stm8s_it.h”, which is where I ultimately uncommented the prototype. I tried putting the prototype into main.c instead, and that worked as well.

Another thing that worked was creating my own main() function in my .ino file. I did have to go comment out all the stuff in main.c so it didn’t complain about that, but it did work.


dannyf
Sat Jan 13, 2018 12:19 am
I haven’t had much luck with sdcc. last time i tried it (a few years back), i couldn’t get it to trim off unused code. as i develop my code modularly, each project contains all sorts of pieces that may not be used for a given project. the inability to cut out unused code produces gigantic hex files.

this notion of having to declare your isrs in main.c is equally idiotic, in my view.

IAR or Cosmic is my choice on STM8.


mrburnette
Sat Jan 13, 2018 3:41 am
[Jimmus – Thu Jan 11, 2018 8:57 pm] –
Yeah, it is a pretty strange requirement. Not at all intuitive.

@zmemw16 well, that’s what the manual said — “a prototype of the isr MUST be present in the file that contains the function ‘main’.” Main.c included <Arduino.h>, which included “stm8s_it.h”, which is where I ultimately uncommented the prototype. I tried putting the prototype into main.c instead, and that worked as well.

Another thing that worked was creating my own main() function in my .ino file. I did have to go comment out all the stuff in main.c so it didn’t complain about that, but it did work.

Guess I discovered the weirdness so long ago that I now believe it is intuitive :lol:

It’s the way the IDE works that makes this a requirement; ArduinoIDE generally tries to build the prototyping for you… all of the files in the Arduino sketch directory are concatenated and then that temp file is sent to the compiler as one file. In my projects, I generally put library files into the sketch folder (so I can ZIP everything needed and snapshot the version), so the prototyping (forward declaration) must appear in the sketch.ino before the setup() section.

Ray


Jimmus
Mon Jan 15, 2018 6:59 am
So I have a question about this, Ray. It wasn’t just in my .ino file that I had to make the declaration. I had already tried that. I actually had to go find the stm8_it.h file and modify that. I don’t have a major problem with that, because it’s my system and I can do it any way I want as long as it works. That’s the beauty of open source. But it would be nice if I could kinda compartmentalize things and keep them in their nice little places and only modify things in my little branch of the directory structure. Is there an include file in my project directory that Arduino.h would include if it were there?

Because I’m seeing a little bit of what dannyf mentioned about trimming out unused code. The UART is great for debugging and certain kinds of projects, but my little standalone mailbox detector doesn’t need serial communication. The AVR platform automatically trims all that stuff out if you don’t use it. I can see that there are some things in the STM8 code to do the same thing, but some of them still have issues. For example, if I don’t do any pinMode() or digitalWrite() kinds of calls, it saves me about 580 bytes of program space. But it still links in the UART stuff, even if I never call serial_begin() or any serial calls. If I just go in and #define NO_SERIAL somewhere, it saves me 775 bytes of program space and 42 bytes of RAM. But where is the generally accepted place to do that? I have been doing it in HardwareSerial.h, but again, that’s not a file I wrote, so I would prefer to do it in one of my own files. How is it supposed to be done?

I still haven’t figured out how to get it to not link in all the timer stuff. millis() and micros(). Even if I don’t use it at all.


dannyf
Tue Jan 16, 2018 12:06 pm


still haven’t figured out how to get it to not link in all the timer stuff. millis() and micros(). Even if I don’t use it at all

Check the manual to see if the compiler can put each function into it’s own section and then if the linker can discard unused code. Enable both and you are done.

If not, you are out of luck, unless you want to change the code to support conditional compilation – where you would manually specify if a function is used or not.


tenbaht
Tue Jan 16, 2018 3:13 pm
[Jimmus – Mon Jan 15, 2018 6:59 am] –
Because I’m seeing a little bit of what dannyf mentioned about trimming out unused code. The UART is great for debugging and certain kinds of projects, but my little standalone mailbox detector doesn’t need serial communication. The AVR platform automatically trims all that stuff out if you don’t use it. I can see that there are some things in the STM8 code to do the same thing, but some of them still have issues. For example, if I don’t do any pinMode() or digitalWrite() kinds of calls, it saves me about 580 bytes of program space. But it still links in the UART stuff, even if I never call serial_begin() or any serial calls. If I just go in and #define NO_SERIAL somewhere, it saves me 775 bytes of program space and 42 bytes of RAM. But where is the generally accepted place to do that? I have been doing it in HardwareSerial.h, but again, that’s not a file I wrote, so I would prefer to do it in one of my own files. How is it supposed to be done?

Best would be to define a compiler option: -DNO_SERIAL

It would be great to leave it out automatically if no Serial_begin() is present in the sources. Right now that does not happen, because HardwareSerial.c is only one file containing all serial function, including the initialization code. And the SDCC linker follows an all-or-nothing approach: It can leave out complete .rel files, but not individual functions. So if only one label (function or variable) is referenced from the outside, the whole module gets pulled in.

This is why I split the SPL into many single function files when compiling. Something similar would be possible for the Arduino core files. The initialization code would still be there, but at least the rest if left out.

I have this in mind, but it will influence the complete source structure, so I didn’t do it yet. Hopefully someday later…

Michael


Leave a Reply

Your email address will not be published. Required fields are marked *