2008-10-27 13:29:38     Interrupts on the BF561 - a straightforward example required

Document created by Aaronwu Employee on Aug 8, 2013
Version 1Show Document
  • View in full screen mode

2008-10-27 13:29:38     Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64238   

 

Hi, I have spent almost a week trying to implement interrupts in my code which runs on uClinux. I have had no luck whatsoever

 

Unfortunately I have very little experience with embedded C, and indeed the Blackfin. (As you probably have already guessed!)

 

The wiki page on interrupts goes over my head and I cannot make much sense of the related forum posts either.

 

What I require is a simple example of an interrupt which I can compile using the bfin-uclinux compiler from the toolchain to run on uClinux. It is to run on the BF561 on corea(uClinux). All it needs to do is print a message to the screen when the PF5 push button (Switch6) causes an interrupt.

 

Here is what I expect the general pseudocode template to look like and if there is anybody who can possibly fill in the missing useful bits I would greatly appreciate it:

 

int main (void)

{

    setup_isr();

    while(true);

    return 0;

}

 

__attribute__ ((interrupt_handler))

void ISR(void)

{

    printf("ISR\n");

}

 

void setup_isr(void)

{

    ..... //Something here to setup PF5 to run ISR()

}

 

This needs to compile using the bfin-uclinux-gcc. I hope I have given enough information and thanks in advance for any help!

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-27 13:40:34     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64240   

 

the code you wrote is for bare metal.  it makes no sense at all under Linux.  the interrupt wiki page already provides a short example.  shows you exactly how at the bottom.

QuoteReplyEditDelete

 

 

2008-10-27 13:52:16     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64242   

 

Ok, well incidentally.. I will eventually need to implement interrupts on bare metal (running on coreb) so will have to compile that with the elf compiler.

 

As for the small example at the bottom of the wiki, I don't really understand how I can make use of it... That's what I meant by it has gone over my head. This is the first time I have dealt with interrupts.

 

You probably think I'm just being dumb and annoying, but is there any chance you could just show me the example code needed for PF5 (Switch6) on the BF561 to interrupt main() and print something to screen? Unfortunately I don't know what to add to the 'short example'

 

Thanks in advance,

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-27 14:00:14     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64243   

 

there is no quick and dirty way to say "when i push a button, have main() in some random program wake up".  that is what the device driver framework is for.

 

if you want to use GPIOs like push buttons, then use the gpio-keys driver:

http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-keys

QuoteReplyEditDelete

 

 

2008-10-28 12:17:56     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64288   

 

Ok fair enough, but that still doesn't help me very much :/

 

Here I'll ask my question in a slightly different way:

 

How do I, 1) check or set the state of PF5 from uClinux and 2) check or set the state of PF5 from bare metal? In fact, any programmable flag. All I want to be able to do is signal between the two cores in order to achieve message passing.

 

I know this is a trivial task for you, and I'm almost certain you know exactly what I am requesting.. please can you just give a small example because the wiki just isn't doing the trick!

 

Thanks in advance,

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-28 12:20:05     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64289   

 

I should just add that the reason I brought up the push buttons was simlpy to use them to test any interrupts. Ultimately I just need to use the programmable flags.

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-28 16:50:28     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64296   

 

the gpio-keys driver provides using pf's like push buttons

 

but if you actually want to do inter-core communication, that is not how it should be done ... look at the SYSCR registers in the BF561 HRM

QuoteReplyEditDelete

 

 

2008-10-29 05:34:00     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64326   

 

Hi, I'm pretty sure that the SYSCR registers aren't going to help me at all. They are system reset configuration registers right? I don't want core b to be reset once the app is started.

 

The app on coreb will be used to fill a portion of SDRAM with data; lets refer to it as a buffer. Coreb must signal to core a that the buffer is filled and ready to be read/processed. Core a then empties the buffer, signals to coreb that the buffer is ready to be filled again and the cycle continues.

 

My opinion is that using a PF to cause an interrupt to the program running on core a is the best method of achieving this. Hence needing an simple example of how to use interrupts in this way.

 

As I have already said, I have spent much time reading docs on the wiki and reading the HRM but I am still not understanding how to use interrupts. Please can you just give me a straightforward example which I can make use of? Lets leave the inter-core communication for now, I just want to be able to interrupt a linux app running on core a, from a bare metal app running on core b.

 

I hope that clears things up,

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 05:42:42     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64329   

 

please read the HRM instead of assuming what SYSCR can do

QuoteReplyEditDelete

 

 

2008-10-29 08:28:11     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64333   

 

Ok fair enough, what I thought was the HRM was in fact just the ezkit manual. Now that I have seen the HRM its starting to make more sense. I have successfully written a bare metal app which causes an interrupt on SICB_SYSCR. However I still don't know how to handle that interrupt from a linux app.

 

#include <asm/irq.h>

 

#define CONFIG_YOURDRIVERS_IRQ_PFX IRQ_PF5

static irqreturn_t your_irq_handler (int irq, void *dev_id)

{

  prinkt(KERN_INFO"your_irq_handler \n");

  return IRQ_HANDLED;

}

static int __init your_drivers_init_function(void)

{

   if (request_irq(CONFIG_YOURDRIVERS_IRQ_PFX, your_irq_handler, IRQF_TRIGGER_LOW, "Your IRQ",

        your_pointer_passed_to_the_irq_handler)) {

 

          printk (KERN_WARNING "IRQ %d is not free.\n", CONFIG_YOURDRIVERS_IRQ_PFX);

          return -EBUSY;

   }

 

  disable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

 

  ... some code ...

 

  enable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);

 

}

void __exit your_drivers_exit_function(void)

{

  free_irq (CONFIG_YOURDRIVERS_IRQ_PFX, your_pointer_passed_to_the_irq_handler);

}

 

Is that a good starting point? or am I looking at the wrong thing. Can you please help me with some code for interrupts on uClinux, rather than just a one or two line answer confirming the fact that I don't know what to do!

QuoteReplyEditDelete

 

 

2008-10-29 09:41:06     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64334   

 

yes, the example in the wiki is there because you're supposed to use it as a starting point for arbitrary interrupts

QuoteReplyEditDelete

 

 

2008-10-29 09:59:49     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64335   

 

Ok thanks.

 

I have two problems when trying that example:

 

1) What is 'your_pointer_passed_to_the_irq_handler' supposed to be? Pointer to what? I have told it what irq to use and how to handle the interrupt - I don't have any pointers to pass! (I have used 'null' in my example)

 

2) I get the compile error shown in the attached file. I have included my hello.c too.

 

Now that I have shown you that I have tried to make sense of the example, please can you show me how to get this thing working?

 

One last thing. I think I am right in using IRQ_SUPPLE1 for SICB_SYSCR. Is that true?

 

Thanks in advance,

 

John Redford.

 

compile error

hello.c

QuoteReplyEditDelete

 

 

2008-10-29 10:01:51     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64336   

 

Ok thanks.

 

I have two problems when trying that example:

 

1) What is 'your_pointer_passed_to_the_irq_handler' supposed to be? Pointer to what? I have told it what irq to use and how to handle the interrupt - I don't have any pointers to pass! (I have used 'null' in my example)

 

2) I get the compile error shown in the attached file. I have included my hello.c too.

 

Now that I have shown you that I have tried to make sense of the example, please can you show me how to get this thing working?

 

One last thing. I think I am right in using IRQ_SUPPLE1 for SICB_SYSCR. Is that true?

 

Thanks in advance,

 

John Redford.

 

PS. I Don't think the attachments worked on the last post, so here they are:

 

#include <string.h>

#include <asm/irq.h>

 

//unsigned char buf1[1024];

 

#define IRQ_ID = IRQ_SUPPLE_1

 

//__attribute__((interrupt_handler))

static irqreturn_t my_irq_handler (int irq, void *dev_id)

{

printk(KERN INFO"my_irq_handler \n");

printf("irq handler");

return IRQ_HANDLED;

}

 

static int __init my_drivers_init_function(void)

{

if (request_irq( IRQ_ID, my_irq_handler, IRQF_TRIGGER_LOW, "My IRQ", null)) {

  printk(KERN_WARNING "IRQ %d is not free.\n", IRQ_ID);

  return -EBUSY;

}

}

 

void __exit my_drivers_exit_function(void)

{

free_irq (IRQ_ID, null);

}

 

int main() {

   

while(1) {

}

 

        return 0;

}

 

 

 

 

 

compile error:

 

[root@localhost hello-interrupt]# /opt/uClinux/bfin-uclinux/bfin-uclinux/bin/gcc -mcpu=bf561 -Wl,-elf2flt hello.c -o hello -I/home/JJRE/Desktop/uclinux/uClinux-dist-2008R1.5-RC3/linux-2.6.x/include/

hello.c:13: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘my_irq_handler’

hello.c:20: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘my_drivers_init_function’

hello.c:28: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘my_drivers_exit_function’

QuoteReplyEditDelete

 

 

2008-10-29 10:13:37     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64337   

 

do not compile things by hand.  either build it straight into the kernel or build it as a module.  any other method is not supported and you're on your own.

 

your #define line isnt valid C

 

a main() function makes no sense whatsoever in kernel space

 

the pointer you pass to request_irq() is not optional.  NULL is an invalid value.  this can be whatever you want, but most of the time it's a pointer to driver data so that the irq handler knows what to operate on.

QuoteReplyEditDelete

 

 

2008-10-29 10:23:38     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64340   

 

my bad with the #define.

 

That is the problem... I need this to work in userspace. I said from the beginning all I want is an app running on uClinux (in userspace?!) which reacts to interrupts. Surely I don't need to build it into the kernel or build it as a module?

 

As far as 'examples on the wiki' go, there isn't actually an example of interrupt usage, just small snippets.

 

You must have realised by now that not only do I have no idea how to do this, but I am pretty confused with this whole process! Why can't you please just help me out with some code, send me on my way and I wont have to keep adding to this thread and going round in circles?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 10:32:04     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64342   

 

you cant handle interrupts from userspace, end of story.  there needs to be a kernel driver in place.  that is what the linux-kernel:* namespace in the wiki is generally for -- kernel code, not userspace.

 

said driver will listen for the interrupt and can put userspace applications to sleep (via a char device) to be woken up when the interrupt notification occurs

 

throwing code at this wont help you.  you need to read a book on basic Linux design principles.  you can find many (including free ones) here:

http://docs.blackfin.uclinux.org/doku.php?id=references_and_pointers

QuoteReplyEditDelete

 

 

2008-10-29 10:34:07     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64343   

 

I have just spotted this on the wiki:

Standalone Interrupt Handlers

 

For people writing small test applications, you may want to write your own IRQ handler. The gcc toolchain provides an easy way to do just that via the interrupt_handler attribute.

 

__attribute__ ((interrupt_handler))

void my_irq_handler(void)

{

    /* do the stuff needed to handle the IRQ properly */

}

 

Then just make sure you register the handler by updating all the relevant registers and masks.

 

 

 

I guess this is what I'm after, but there isn't enough material there to warrant a working example. How exactly could I register the handler by updating all the relevant registers and masks please?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 10:38:16     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64344   

 

except that there's an explicit note right below the text you quoted that that is *only for bare metal code*.  it does not apply to Linux in any way (kernel or user).

QuoteReplyEditDelete

 

 

2008-10-29 10:41:38     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64345   

 

I disagree, I think throwing code at this will help considerably so I can move on to something else I'm used to learning by example so I guess that's why I'm getting stuck in a rut.

 

I think I understand what you mean now, however, about having the irq handler in kernel space. The next question would be, how do you actually make use of that and have an app running in userspace wake up upon interrupt?

 

To be honest now I come to think of it, I don't understand why there is so little docu. on message passing between the cores, because surely people who are running uClinux on corea and bare metal app on coreb need message passing or else it's pointless having that setup :/

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 10:47:08     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64347   

 

yes, there is documentation lacking on doing communication with bare metal applications running on coreb.  we show you how to load up an application, but everything after that is up to you.  there is a tracker item to develop more documentation, but it's low priority at this point.

 

the books i referred to already have plenty of code examples.  for exampling, writing a char device driver with blocking I/O which is what you probably want.

QuoteReplyEditDelete

 

 

2008-10-29 10:49:26     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64348   

 

also, the reason for the dearth of bare metal documentation is pretty logical ... our target has been Linux users, not bare metal.  comparatively, Linux users make up a significantly larger base.

QuoteReplyEditDelete

 

 

2008-10-29 11:00:42     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64349   

 

Hmm. Thankyou for the references but I don't think I'll have enough time to get anything useful from them.

 

Just say I finish off the 'example interrupt driver' without the main() and build it into the kernel please can you answer the following questinos:

 

1) what should I use as the 'your_pointer_passed_to_the_irq_handler'

 

2) how do I then use the driver in a userspace app? Is there a simple code example you could reply with, which makes use of the 'example interrupt driver'

 

I think you have plenty of examples you could help me out with, but you're just holding them back

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 11:02:30     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64350   

 

I am not asking for help with the bare metal. I am asking for help with interrupts in a linux app. Surely it can't be that much trouble to just tell me how to wait for SICB_SYSCR to interrupt an app running in userspace?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 11:04:44     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64351   

 

I don't understand why we are getting nowhere. Surely you've had enough of my questioning by now and you'd rather just have me finish up and move on!

QuoteReplyEditDelete

 

 

2008-10-29 11:15:35     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64352   

 

the references you refuse to read contain examples doing exactly what ive described (like Linux Device Drivers).  i dont have any simple examples, just real drivers.  they're all in the tree already.

 

as i said about the pointer to request_irq()/free_irq(), it's a unique pointer to driver state.  drivers tend to maintain state about their device in a structure and so people use that.

 

a char device is how you commonly interface with userspace.  your driver creates a char device which userspace opens and communication happens via that.  but again, this is documented in the references i pointed you to.

QuoteReplyEditDelete

 

 

2008-10-29 11:32:17     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64356   

 

Ok, well what about these real drivers? I'm not sure what the 'tree' is, I'm assuming that's the uClinux distribution. Can I not just make use of a driver which has already been written? I am very reluctant to sit down and spend ages reading references, then reinvent the wheel. Surely somebody has used SICB_SYSCR for an interrupt before, otherwise why does it exist?!

 

Mike, I really do appreciate all the time you have spent in trying to guide me, but is there not a more straightforward way to do this? Ultimately, do you understand what it is I am trying to achieve? If so, is there any code easily available which fulfils that?

 

Cheers,

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 11:59:48     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64361   

 

Pleeeeeeease :-p

QuoteReplyEditDelete

 

 

2008-10-29 13:28:31     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64367   

 

Unfortunately the reference material is not freely available, so I haven't had a chance to read around the subject. Is there anything else you can suggest? I'm getting nowhere :/

 

Would you mind talking me through getting a simple driver module installed and a test program which runs on linux which can respond to interrupts?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-29 13:40:24     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64368   

 

there is no code that exists for the BF561 coreb.  you need to write it.

 

if you downloaded the uClinux distribution, then you have the full source code to the Linux kernel already

QuoteReplyEditDelete

 

 

2008-10-29 13:41:15     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64369   

 

i dont know why you think the material is not freely available when it clearly is ... you can download the entire LDD3 book for free

QuoteReplyEditDelete

 

 

2008-10-29 13:45:05     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64371   

 

Sorry, I have just realised that. I was trying to look at all the O'Reilly books earlier. I'm gona take a good long look at the section on interrupts this evening and hopefully at work tomorrow I will have more success.

 

Thanks again for your persistence, I can imagine how boring I am

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-30 08:34:53     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64438   

 

I have made some progress. I filled in the gaps of the driver example on the wiki and managed to compile it as a module.

 

insmod hello.ko   seems works, but there is a message: 'no IRQF_TRIGGER set_type function for IRQ 70 (<NULL>)

 

However it seems to work anyway... when i load coreb-toggle into coreb and execute, immediately the screen is filled with by the printk() messages, despite coreb only updating the register SICB_SYSCR every few seconds.

 

Now that I have 'something' to work with, please could you give me some more pointers?

 

John Redford.

 

coreb-toggle.c

hello.c

QuoteReplyEditDelete

 

 

2008-10-30 08:54:01     Re: Interrupts on the BF561 - a straightforward example required

Michael Hennerich (GERMANY)

Message: 64440   

 

IRQ_SUPPL1 and any below (Core and System Interrupts) don’t know anything about IRQF_TRIGGER_XXX.

This is only for GPIO interrupts.

I would only give the IRQF_DISABLED flag.

 

QuoteReplyEditDelete

 

 

2008-10-31 06:36:33     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64513   

 

Thanks for that Michael, that helped.

 

However I still don't have control over the interrupts... as soon as I launch my app which triggers the interrupts, the interrupt handler goes crazy and constantly gets interrupted - printk()-ing until the kernel crashes.

 

Also when I try to setup the interrupts for the push buttons, I always get the message saying that they are already in use by the kernel.

 

Please can anybody help me? Mike?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-31 06:52:31     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64516   

 

did you actually clear the interrupt like the HRM says ?

QuoteReplyEditDelete

 

 

2008-10-31 10:59:59     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64541   

 

No I hadn't and indeed that was the problem. I wasn't setting the interrupt reset bit so it was as if the interrupt was constantly happening. Great we've finally got somewhere thanks for your help.

 

My next stage is having a userspace app react to the interrupt which is now being processed by the kernel.

 

Any thoughts?

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-31 13:07:50     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64547   

 

Hi again, this is where I require help:

 

For people writing small test applications, you may want to write your own IRQ handler. The gcc toolchain provides an easy way to do just that via the interrupt_handler attribute.

 

__attribute__ ((interrupt_handler))

void my_irq_handler(void)

{

    /* do the stuff needed to handle the IRQ properly */

}

 

Then just make sure you register the handler by updating all the relevant registers and masks.

 

How exactly do I register the handler by updating all the relevant registers and masks? Please point me in the right direction because I am so close to getting this working and there isn't much documentation on it at all anywhere

 

John Redford.

QuoteReplyEditDelete

 

 

2008-10-31 18:12:59     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64556   

 

as ive told you multiple times in this thread, stop looking at that.  the Linux framework handles everything for you.

QuoteReplyEditDelete

 

 

2008-10-31 18:13:35     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64557   

 

you need to write a character device driver which manages the userspace <-> interrupt notification

QuoteReplyEditDelete

 

 

2008-11-04 09:32:38     Re: Interrupts on the BF561 - a straightforward example required

John Redford (UNITED KINGDOM)

Message: 64663   

 

Hi, sorry I forgot to mention in my last post that I meant bare metal interrupt code. But its ok, I've managed to sort that out and I currently have linux kernel on corea interrupting core b bare metal and vice versa, so thats good.

 

My next question was going to be how to manage kernelspace <-> user space notification. But you have already mentioned it, so I will take a look now.

 

Preliminary investigation leads me to believe mmap() will be useful? Do you think this task going to be straightfoward or is it very complicated?

 

 

 

Thanks in advance,

 

John Redford.

QuoteReplyEditDelete

 

 

2008-11-04 14:37:29     Re: Interrupts on the BF561 - a straightforward example required

Mike Frysinger (UNITED STATES)

Message: 64668   

 

mmap() is for passing memory buffers straight to userspace.  i dont think that's what you need to do at all.

Attachments

Outcomes