call a c subroutine from an asm - program (ISR)

A catchall for PSoC Mixed-Signal Array (microcontroller) discussions not captured by the other forums.

Moderator: ericb

call a c subroutine from an asm - program (ISR)

Postby woifal01 on Mon Jun 19, 2006 4:24 am

I use a counter to create a 10ms interrupt. The generated ISR file is an asm - file, but I want to write my ISR routine in C, so I want to call a c-function from the asm ISP program.

Unfortunately I cant do this call and I cant include the headerfile and so I have no idea how to call the c subroutine!

Could somebody give me a hint, how to do that call? Do I have to create an *.inc file?
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby graaja on Mon Jun 19, 2006 5:51 am

You can call the C function with an underscore. For example, if you have a C function called MyFunction, then in the assembly file, you need to write

lcall _MyFunction

But remember, when you call a C function from within an ISR, you need to save the A and X registers and all the virtual registers and restore them after the call as you do not know which registers the called function is going to modify. Also, if you are working with LMM, then you need to set the paging mode to native paging and also save all the paging registers and restore them after the call to the external function.
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

Postby woifal01 on Tue Jun 20, 2006 11:07 pm

thanks,

that works!
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby lpoma on Wed Jun 21, 2006 7:13 am

I don't know if anyone would agree with me but the use of virtual registers by the compiler 'sucks' when it comes to elegant and fast code.

The fact that you need to 'push' and 'pop' each of the virtual registers when doing a 'C' ISR is horrendous. It's bad enough that in LMM we need to store the paging regs on the stack.

Why didn't ImageCraft give us the option to compile the code WITHOUT virtual registers? Therefore local vars could have been stored in a stack frame.
Len Poma
Consultron
Sr Hardware and Software Design Engr
lpoma
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 17
Joined: Tue Feb 01, 2005 4:50 am
Location: Consultron

Postby woifal01 on Wed Jun 21, 2006 8:19 am

I just saved the A and X register (push, pop) in my ISR asm routine.

I am a total beginner in programming µCs and so I have no idea what these "virtual registers" are and which of them I should save!

Could anyone explain what these registers are used for and where I can find them.
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby graaja on Wed Jun 21, 2006 8:20 am

I agree with Len. Sometimes, there are too many virtual registers.
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

ISR subroutine problem

Postby woifal01 on Thu Jun 22, 2006 12:19 am

I already implemented my ISR.
If I call my subroutine control in the main loop (while loop) it works correct.
If I call the same subroutine from the ISR (counter16_int) it does not work - I dont get the correct signal at the output.

I have no idea what the problem is. I hope somebody can help me with that.
Attachments
controlsystem_forum.zip
Counter16 is used to create an Interrupt. The subroutine Control works correct when it is called in the while loop. If it is called from the ISR it does not work properly!
(311.33 KiB) Downloaded 235 times
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby graaja on Thu Jun 22, 2006 12:53 am

Hello Wolfgang,

Please not my earlier post. When you want to call a C function from inside an ISR, you need to save all the virtual registers, paging registers etc before calling the function and again restoring all of them after the call. The best you can do is to just set a flag inside the ISR and execute the function in main if the flag is set. Or just declare the Control function as an ISR using #pragma interrupt_handler and directly place an ljmp instruction to this function in boot.tpl int he counter's interrupt vector.
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

Postby graaja on Thu Jun 22, 2006 12:55 am

One more thing to note is the paging mode. The compiler assumes that whenever a C functionis called, the paging mode will be in native paging. But when the program enters the ISR, the flag register gets cleared and hence, the paging mode becomes 0. So, you also need to set the paging mode to native paging before calling this function (also mentioned in my earlier post).
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

Postby woifal01 on Thu Jun 22, 2006 3:04 am

Hi Ganesh,

thanks for your help. The problem is that I am a total PSoC beginner and so I have no idea about most of the registers.

I found something about the paging registers in the technical reference and will read that.

Anyway I still have troubles with the bascics:

1.) I tried to set a bit in the ISR and call my c program from the main program but I could not check the bit in main:

definition of the byte in ISR counter_int

export chISRoccured1
AREA bss
chISRoccured1:
BLK 1

(export should make the byte global!)
What do I have to do to be able to check the bit in the main prog. (make it global)?
chISRoccured1 is not available in main.


2.) Unfortunately I did not find anything about virtual registers in the reference manual. Where can I find these registers?

Thanks again for your help.
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby graaja on Thu Jun 22, 2006 4:37 am

Hello Wolfgang,

For Solution 1:

In counter's isr file, add the following code (make sure to add them inside the user code marker area)

Code: Select all
export _FlagsIsrOccured

area InterruptRAM(ram)
_FlagIsrOccured:    BLK  1


In the ISR,

Code: Select all
mov [_FlagIsrOccured],1


As we have declared the variable in the area InterruptRAM, the compiler will automatically place this variable in page0. When the ISR is entered, the flag register is cleared and the page mode is 0. In this mode, all memory operations take place on page0. So, you do not have to update the CUR_PP register. Either create a header file or include this in the main.c file

Code: Select all
extern BYTE FlagIsrOccured


Now, in C, you can check the flag and call the Control function.

Code: Select all
void main()
{
   // Other code
   if(FlagIsrOccured != 0)
   {
      Control();
      FlagIsrOccured = 0;
   }
}


For Solution2:

Declare the Control function as interrupt handler in main.c and declare its function prototype.

Code: Select all
#pragma interrupt_handler Control
void Control(void);

void Control(void)
{
   // Code goes here
}



Then open the boot.tpl and in the interrupt vector for Counter16 (you can find this by opening the boot.asm and see where the ljmp Counter16_ISR is placed) and comment out the existing template and add this

Code: Select all
ljmp _Control


Now, the compiler will automatically take care of saving all virtual registers, A, X and paging registers and also it will terminate the Control function with a reti.

The first solution is faster as it does not have the overhead of pushing and popping umpteen registers. The second method is easy to code. Regarding virtual registers, I am not sure if this is there in any document. If you open the .lst file and see below the Control function, you will know what are the virtual registers the compiler uses. The virtual registers are in the form __r0, __r1, __r2 etc.
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

Postby woifal01 on Thu Jun 22, 2006 5:45 am

Hi Ganesh,

I tried the solutions.
Solution 2 works perfect - thanks a lot!

With solution 1, I have a problem:
I added your code into my counter16_ISR:

AREA InterruptRAM (RAM,REL,CON)

export _FlagsIsrOccured
area InterruptRAM(ram)
_FlagIsrOccured: BLK 1

but I always get the message:
Exportet symbol _FlagIsrOccured does not have a definition!

If I skip //export _FlagsIsrOccured, then there is no failure.
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Postby graaja on Thu Jun 22, 2006 5:56 am

Sorry, there was a typo in my post. The exported symbol is _FlagsIsrOccured and the actual symbol is _FlagIsrOccured. Correct this and you should be through.
User avatar
graaja
PSoC Master
PSoC Master
 
Posts: 3084
Joined: Thu Dec 18, 2003 4:35 pm
Location: India

Postby woifal01 on Thu Jun 22, 2006 6:29 am

Hi Ganesh,

now it all works perfect - thanks a lot!!
The PSoC world becomes a bit clearer to me now.
Wolfgang Weidinger
8. Semester Automation Engineering
University of Applied Sciences
woifal01
Bite-Size Cheese
Bite-Size Cheese
 
Posts: 15
Joined: Mon May 29, 2006 1:28 am

Over riding ISR

Postby blinari on Fri Jun 23, 2006 9:22 am

To make a interrupt in C.

1) Open up boot.asm
2) Find the interrupt in that file and remember that address
example:
(org xxh ;PSoC Block DBB21 Interrupt Vector 3) Open up boot.tpl

4) Comment out //`@INTERRUPT_##` and put in your own function
example:
org 44h ;PSoC Block DBB21 Interrupt Vector
ljmp _mSecInt_ISR //`@INTERRUPT_17`
reti

5) Go to your main.h file or the top of your main.c file and put in:

#pragma interrupt_handler mSecInt_ISR

6) in you .c file

void mSecInt_ISR()
{
//Code Here
}

7) Push Generate application and rebuild!
User avatar
blinari
Cheese Wheel
Cheese Wheel
 
Posts: 73
Joined: Tue Feb 28, 2006 3:59 pm
Location: Wa


Return to PSoC1 General

Who is online

Users browsing this forum: No registered users and 2 guests