![]() |
How do I use interrupts?
Hello,
For the past few days I have been searching the web for an explanation how to use interrupts. I didn't find anything useful. All the code bits I have seen untill now talked about a timed loop. Is it possible to use interrupts to execute a certain VI the second a microswitch is clicked? If so, please tell me how. :) Many thanks, Itamar. |
Re: How do I use interrupts?
Quote:
You want to let the RTOS (vxworks) handle asynchronous events that require non-trivial amounts of processing. Can you describe in more detail what you are trying to accomplish, and why it can't wait 20ms for the next teleop iteration? |
Re: How do I use interrupts?
1 Attachment(s)
Quote:
If you open the Periodic Timing VI, there is a loop that defaults to run once every 100ms and another that defaults to run every 10ms. You can add more loops or change those to run faster, if that is what you need. As a way to bound the problem, calculate how far the thing your are measuring will move in a millisecond. Use that to scale your timing needs. As for actually using interrupts, I didn't see an example, but it looks like you'd bundle together the Digital info for the digital channel monitoring the switch, then loop handling the interrupts as they are returned, then cleanup at the end. Determin if this is the correct transition for your digital line, or if you want to interrupt on both open and close and update the Booleans on Open accordingly. Note that the attached image doesn't have the rest of the framework or the watchdog in place and assumes that you will incorporate this into the framework. |
Re: How do I use interrupts?
Quote:
Is the 2011 FRC LabVIEW Framework still under development? If so, would it be possible to add support for event handlers? That way, folks who ask about interrupts could be directed to the event-handler feature of the Framework instead, where the OS could provide the proper priority and concurrency management. |
Re: How do I use interrupts?
Since you had already mentioned the teleop timing, I didn't cover it. I listed ways to get other timing values that aren't driven by the FRC protocol and how to connect to the interrupts raised by the FPGA.
Can you give more info as to what OS event handling or Framework event handling means to you? Do you want to use the LV event structure? Registered callbacks? Asynchronous VIs that wait for a condition? What is the concurrency management that you refer to? Basically, can you give more info on what you have in mind. Greg McKaskle |
Re: How do I use interrupts?
An event handler, as I was using the phrase, is application-level code that gets executed when an external asynchronous hardware event occurs. The execution of this code is "managed" by LabVIEW/vxworks in the sense that resources are allocated to the handler based on time-sharing and priority of other tasks concurrently competing for resources.
The 2010 FRC LabVIEW Framework had explicit support for periodic tasks. These periodic tasks are time-based, not event-based. You could put code in there to poll for an external event of interest. You could even change the default 10ms task to 1ms, although that would waste CPU resources if the event you're polling for occurs much less frequently than that. I don't know what "Asynchronous VIs that wait for a condition" are, but that sure sounds like what I have in mind when I use the phrase "event handler". Perhaps the 2011 Framework could include a shell or template for something like that, as was done for the periodic tasks, to make it more accessible. I make a distinction between "interrupt service" code and "event handler" code. To me, "interrupt service" is what happens from the time the interrupt occurs until the code ACKs the interrupt (if required by the hardware) and re-enables global interrupts. During this period everything else is locked out: There is no concurrency management (time sharing) because there is no concurrency. I'll go out on a limb here and say that for the purposes of FRC programming, interrupts should be serviced ONLY by LabVIEW/vxworks/FPGA: There should be NO need for teams to be writing their own interrupt service code. So when I see a poster asking "how to use interrupts" two thoughts come to mind: 1) what is this team doing that is so time-critical that it cannot properly be handled in a fast periodic task, and 2) do they really mean they want to write an interrupt service routine, or do they want to write an event handler. |
Re: How do I use interrupts?
Would the LabVIEW Event Structure fit what you're looking for? It's available on the Programming->Structures palette and would use robot-side events rather than front panel events.
|
Re: How do I use interrupts?
Quote:
This part sounds good: Quote:
Quote:
|
Re: How do I use interrupts?
To tell you the truth, I'm a bit lost with all of your comments... After reading Ether's comment, I'm pretty sure that what I need is an event handler.
So... is there an option to use events for a microswitch? |
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Quote:
If so, back to my original suggestion: the 2010 Framework had "placeholders" for periodic tasks. Perhaps doing the same in the 2011 Framework for event handlers would be helpful. Users asking about "interrupts" could then be directed to the Framework's support for event handlers. |
Re: How do I use interrupts?
Quote:
Using LabVIEW, you can set up the circuitry connected to the microswitch to generate an interrupt http://en.wikipedia.org/wiki/Interrupts when the switch closes (or opens, or both). When the interrupt occurs, the operating system immediately responds and queues up your event handler for execution. The 2010 Framework doesn't contain any template or example code for event handlers. See Greg's and Mark's earlier posts for suggestions how to do this. Before you do that though, if you tell us what you are trying to accomplish http://www.chiefdelphi.com/forums/sh...0&postcount=10 there might be a better way to handle it. |
Re: How do I use interrupts?
1 Attachment(s)
There are some dangers to beware of when using the Interrupt palette.
P.S. Since this is for use with a mechanical switch, it can be done, but you'll get pretty erratic results until you learn how to debounce a switch. What will happen is you'll get multiple interrupts all within a fraction of a second, as the switch makes and breaks contact several times before settling down to a firm contact. In the example attached, throwing a delay into "React" will effectively debounce the switch, but releasing the switch will probably cause the action all over again. Mechanical switches also operate slowly enough for polling to be a possibly more effective alternative. Quote:
on the other hand... Quote:
I've attached a variation of Greg's interrupt example that puts it in terms of the 2010 framework. You can use an Analog Trigger instead of a Digital Input if you'd rather. |
Re: How do I use interrupts?
Mark, if you handle the interrupt with the Event Case inside the While Loop, doesn't the Interrupt Wait vi handle the interrupt reset for you while you do whatever you want in the Event Case? I would think you would just want to write to a FGV or Global to allow a parallel process actually DO something.
|
Re: How do I use interrupts?
Quote:
In a traditional Interrupt Service Handler (ISR) what you say is very true. You do want to get out of it just as fast as possible, usually by simply setting a flag or incrementing a counter, and then leaving further processing up to some independent polling task or triggered process. A traditional example would be an encoder where interrupts come fast and furious and you must make sure they are all captured and counted. In this case the reset/repeat elapsed time is much too fast to waste time process when you could be missing subsequent interrupts. I may be reading too much between the lines here... but this doesn't sound like a rapid-fire response ISR though. This sounds like an event trigger. This application, what little we know of it, is a micro-switch which is quite a slow (& noisy) device, especially when you take into account the debouncing delay that will probably be required (and that you have to add). An interrupt is not usually a good solution for a mechanical switch, because of all the false interrupts that get generated when a switch makes contact just once. Your code will probably run several times in a row on a single switch press. It probably won't matter which edge you chose as you'll most likely get both rising and falling edges at the same time, whether the switch is being pushed or released. So, I'm imagining that they just want to react to the switch getting hit just as fast as computerly possible, with a relatively long (for the cRIO) delay afterwards to do whatever it is they plan to do. Say the switch is just intended to trigger an event like "kick a ball" when it hits the switch, then that's a slow process that could do all it's processing in the interrupt handler. Primarily because you don't want it to happen again until the mechanism has recycled/reloaded. Code has to be added to delay long enough to debounce the switch anyway. When designing your code you need to take into account how fast you need to be able to repeat the process, whether the process is locked until recycled, etc. P.S. I don't think this Interrupt function stores events. I think it will only "hear" interrupts that occur while Interrupt Wait is active. So the entire time spent in the React case will be deaf to further interrupts. |
Re: How do I use interrupts?
To answer some, hopefully all of the questions. The Wait for Interrupt is a somewhat high level, but relatively low jitter way to respond to an FRC specific interrupt raised by the FPGA.
Notice that Interrupt Open lets you specify specific FRC related I/O triggers. In the general FPGA tool, you write the FPGA to poll, calculate, or do whatever you want at 40MHz or less. The FPGA code you write can raise the one of N interrupts on the PPC (32 interrupts I believe, but it could be less). The lower level library let you determine whether the acknowledge will take place after your code or before. For FRC, it is hidden and set to ack first. To be honest, I haven't used the interrupt stuff a ton, but unlike many other libraries where close is pretty foolproof, you may want to ensure that you close resources or you may find some odd behaviors. If so, reboot the cRIO. Another comment on the interrupt stuff, keep in mind that the heavy protection and isolation you associate with OSes is far thinner and sometimes nonexistent on RT systems such as VXWorks. Newer versions of VXWorks have different configurations which support more user protection and isolation, but the version on the cRIO has high I/O throughput, but less isolation, in fact very little. I don't believe that the event structure works on RT, at least much of it doesn't work there since the event structure is primarily for UI operations. It is certainly not setup to handle interrupts. The event structure also deals with user events which can be used much like queues. If you need to set priorities, and I highly doubt that you do, you can set different subVI priorities and put each of them to wait on different interrupts. Greg McKaskle |
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Quote:
At the end of Autonomous mode the vi gets killed no matter what it is doing at the moment. I think the more standard approach will be to do what we do now and design checks like limit switches into our code or use the CAN Jaguar limit switches. |
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Quote:
Quote:
If so, you could use the example Mark provided here and put your "event handler" code (to depower the motor) where the "react" note is in the diagram. You could also set a flag (like a global variable) that your state machine could read, to keep it from un-doing the motor depower. One possible way would be to test this flag after every motor command in the state machine, and depower the motor if the flag is set. You could experiment with putting a small capacitor across the microswitch to help de-bounce it. |
Re: How do I use interrupts?
Adding to Ether's idea, you might encapsulate the Motor speed command in a subvi all by itself that everyone calls to set that motor speed. With an optional input for the emergency stop flag.
Then the interrupt handler calls it to set the emergency stop flag (& speed to zero), while the state machine calls it for normal operation. The subvi only allows one caller at a time, so you avoid the race condition of setting the speed in two different places near-simultaneously. In the subvi if the emergency stop flag is set, only an explicit reset allows non-zero motor speeds. |
Re: How do I use interrupts?
Quote:
|
Re: How do I use interrupts?
Perhaps the previous robot architecture is influencing the thinking process.
The teleop code is indeed limited to 20ms start gaps, but that limit need not leak into the rest of the robot code. You can have loops running at the rate appropriate to the sensors or mechanism. Often that just means to build a loop and place a Wait or Wait ms Multiple inside. If you find that a loop is running quite fast, you may choose to switch to the timed loop. It has multiple clocks you can choose from, and you can choose very small delays and different delay and scheduling policies. The timed loop is rich in possibilities, which also means it can be confusing if you dive in and then wonder why your app behaves the way it does. I'd encourage you to look at examples and read up on it a bit and perhaps even experiment with it first. And I'll state again that priorities are a tricky tool, and don't be too careless with them or you will starve out other tasks, perhaps even starving the teleop itself. If your app's loops need to coordinate, but not be placed into the same loop, look at using the RTFIFO to send notifications/events between them. You can even use the timeout to combine a periodic and event driven response. If you are interested in going to the next level in LV RT, I'd encourage you to look at examples based on those two concepts, RT FIFOs and Timed loops and think about how your scheduling for sensor loops and state machines is built from those. The cool thing is that rather than having one event mechanism that is interleaved, you can have as many as you like with much finer grained multitasking. Greg McKaskle |
Re: How do I use interrupts?
Greg, thank you for that explanation and suggested directions.
|
| All times are GMT -5. The time now is 21:13. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi