calling a function handler

Go To Last Post
26 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This hard to explain but I'll have a go.  When a interrupt occurs I save pending calls to a function to a struct{} with the function handler that I'm requesting.  Upon exiting the interrupt and after making a context switch when I eventually get round to calling the handler it fails.  It works if I call it there and then when in a interrupt but if I must pend calling the function it fails.

 

the function handler looks as follows:

 

void (*lsr_handler)(int);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Interrupt handlers must have very fast, short code. Minimal or no calls to other functions. Esp. do not call library code and code you didn't write. Don't do human interface things like display or print.

 

ISRs are supposed to run in a few microseconds.

 

What you want sounds like a finite state machine (FSM) is needed, at the application level. The ISR can set flag bits, values, etc. The FSM can detect what the ISR left behind.

Be sure you know why/when the C volatile type is used, and mutual exclusion for a dataum that's multiple bytes, e.g., 16 or 32 bit integer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Steve, he's writing rtos stuff.

Is the problem with the function call itself or the pointer to the function or the state of the stack? I think some single stepping in the simulator might shine some light on what is happening. My guess is stack issues.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Kartman, I'll get back to you the morrow, its late here in Ireland.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Before I go I'll leave with you.

 

I have a function prototype as such:

inline void ( * lsr_handler)(int);

I then assign lsr_handler to the address of a function that I want called as such:

lsr_handler = execute;

And then call it as such:

lsr_handler(arguments);

It works from within the interrupt context it was assigned but from say an application it calls the function perfectly but any calls within the function fail after a short period of time.  I hope someone can help me.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

How can you have a function pointer to an inline function?!?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did wonder about that one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, I've tried everything from inline to push and poping registers.  Still no joy. :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It calls the function handler perfectly, but the function calls within fail. Would anyone have insight to this problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It calls the function handler perfectly, but the function calls within fail. Would anyone have insight to this problem?

Perhaps the insight was  already posted?

 

How can you have a function pointer to an inline function?!?

Now,  you apparently have indeed gotten a function pointer to an inline function.  (Think about that might mean if you had multiple instances of that inline function.)

 

But when the function is inlined, it won't have a RET.  (ignoring for now stack frame building, parameter access, and stack frame unwind)  Won't that be a recipe for "fail"?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
you apparently have indeed gotten a function pointer to an inline function.

Or have you ... ?

 

I don't think the 'inline' specifier actually forces the compiler to make it so?

In particular, if the compiler sees you taking its address, I think it would take that as sufficient grounds to ignore the specifier?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys, forget about the inlining, it does not work either inlined or not.  I'm really at a lost here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

 I'm really at a lost here.

Why? Doesn't your UC3 debugger let you look at the Asm and what's in the machine registers then?

 

If there's one case that works and one that doesn't don't you simply compare one against the other and determine what's different? Knowing that should lead you back to identifying what needs to change in the C.

 

A function pointer on any CPU is not divine magic. The CPU likely has some indirect calling scheme (ICALL on the AVR8) and a call through a function pointer is simply putting the pointer value in the right place then making the ICALL or whatever it is. After that the only other difference can be in the ABI so again you can study the ABI registers and see (in the case of 8bit avr-gcc for example) does R25:R24 contain the expected first parameter, R23:R22 the next and so on? 

 

There has to be some difference at this level for one to work and one to fail - all you have to do is determine what.

 

If you are not comfortable with studying Asm opcodes and register contents are you sure you have the skillset to implement an RTOS - a lot of it is exactly about having the right data in the right place at the right time and then executing the right code at that time. It would be fairly unusual for the core of a context switch to not delve into a little Asm at some stage.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll have a look now.  But the system is very complicated.  But have to start somewhere

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
But have to start somewhere

Usually best to start from something simple, and move on to the complicated stuff as your skills & experience develop...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, the view from the Disassembler is as such:

 

 lsr_handler = execute;
80003DB6  ld.w R5, R11[12]   
80003DB8  mov R0, 0   
 lsr_handler(arguments);
80003DBA  mov R10, 1   
80003DBC  rjmp 0x80003e48   
80003DBE  ld.w R12, R5[4]  

Any of you freaks decode this?  wink

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How on earth are you writing an RTOS if you cannot decode the Asm?

 

Anyway Atmel have an "architecture manual" somewhere that has the UC3 opcodes.

 

Wait a mo....

 

ah yes:

 

http://www.atmel.com/images/doc3...

 

When I Ctrl-F that for "indirect" I actually hit an opcode on page 170 called ICALL. The same name as used for AVR8 in fact. It's used in the form "ICALL Rd" and results in PC being loaded with Rd (and the link return register set up - presumably, like ARM, AVR32 uses something like "MOV PC,LR" to action a "RET"?)

 

It is curious, therefore, that your code shows an RJMP apparently being used. That suggests the optimiser knows the call target already at compile time. I think we need to see some more context here. (like the scope of the function pointer).

 

EDIT: actually when I look at my Google results I see there's an AVR32 architecture manual specifically for UC3. Not sure how it differs from the generic manual but you might want to add this to your book collection too:

 

http://www.atmel.com/images/doc3...

 

EDIT2: ah I see - that second one is more specifically about UC3 specific instruction timing and so on.

Last Edited: Fri. Jul 3, 2015 - 04:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Shit reading, do I actually have to work?  cheeky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I should recap, calling the function handler works, its the body od code inside the function handler that is failing.  Any takers.

 

PS

The function handler body works when in the interrupt but outside of the interrupt it fails.  So a call from within interrupts works, but outside of which it fails.

 

 

Thanks for your patience guys.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You simply aren't giving enough detail.

 

My car was making a funny noise last week - what do you think it was?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

darn this, way for a drink.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
I have a function prototype as such:

inline void ( * lsr_handler)(int);

That actually compiled?  Not even a warning?
Quote:
I then assign lsr_handler to the address of a function that I want called as such:

lsr_handler = execute;

And then call it as such:

lsr_handler(arguments);

Is arguments an int?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I'd be cranking back the code to the simplest that demonstrates the problem, then read up on how the compiler passes parameters etc. Then sit down and use a simulator ( i gather the avr32 has this in AS?) and start debugging. You're going to be up close and friendly with stack frames. I'd say after an hour or so you're going the be either totally confused or slightly wiser. Nevertheless, you will have learnt something. I remember having to do much the same years ago when i was trying to optimise a banking scheme on a z180- drawing stack frames and checking the values step by step. Sure, it's labourious.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The function handler is being called okay, it is the body of code in the function being called that is failing.  Maybe if I try making it a supervisor call it may work. 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

 

Still not enough context/info for anyone to offer help.

Can't you construct a small test program that illustrates your issue? (often in doing so you realise what you are doing wrong anyway)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Found it Clawson, there was a race condition occurring.