🚀 Introduction #
In the previous blog Writing a Simple Device Driver in VxWorks, we wrote a simple character driver.
Now, let’s take it one step further: handling hardware interrupts.
Interrupts are essential in embedded systems because they let devices signal the CPU immediately when something happens.
In this tutorial, you’ll learn:
- How to write an Interrupt Service Routine (ISR) in VxWorks.
- How to connect the ISR to an interrupt line.
- How to handle interrupt events safely with a driver.
🧩 How Interrupts Work in VxWorks #
- ISR (Interrupt Service Routine): runs in interrupt context (fast, no blocking).
- Deferred Work: heavy processing is usually done in a task, not in the ISR.
- VxWorks provides APIs:
intConnect()
→ attach ISR to interrupt vector.intEnable()
/intDisable()
→ enable/disable interrupts.
💻 Example: Interrupt-Driven Device Driver #
We’ll simulate a hardware device that generates interrupts.
Our driver will:
- Install an ISR.
- ISR will signal an event.
- A driver task will process the event.
Code Example #
#include <vxWorks.h>
#include <intLib.h>
#include <taskLib.h>
#include <semLib.h>
#include <stdio.h>
#define MY_INT_VEC 0x40 // Example interrupt vector
#define MY_INT_LVL 5 // Example interrupt level
SEM_ID isrSem; // Semaphore for ISR-to-task signaling
// ISR (Interrupt Service Routine)
void myIsrHandler(int arg)
{
printf("ISR: Interrupt occurred!\n");
// Signal the driver task
semGive(isrSem);
}
// Driver task to handle deferred work
void myDriverTask()
{
while (1)
{
// Wait for ISR to signal
semTake(isrSem, WAIT_FOREVER);
printf("Driver Task: Handling interrupt event\n");
// Simulate processing device data
taskDelay(50); // ~0.5 sec
}
}
void myDriverInit()
{
// Create binary semaphore
isrSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
// Connect ISR to interrupt vector
if (intConnect(INUM_TO_IVEC(MY_INT_VEC), (VOIDFUNCPTR)myIsrHandler, 0) == OK)
{
printf("ISR connected to vector 0x%x\n", MY_INT_VEC);
// Enable the interrupt
intEnable(MY_INT_LVL);
}
else
{
printf("Failed to connect ISR\n");
}
// Start driver task
taskSpawn("tDriver", 100, 0, 2000, (FUNCPTR)myDriverTask,
0,0,0,0,0,0,0,0,0,0);
}
📝 Explanation of the Code #
-
ISR (
myIsrHandler
)- Runs when the interrupt occurs.
- Signals a semaphore instead of doing heavy work.
-
Driver Task (
myDriverTask
)- Waits on the semaphore with
semTake()
. - Processes the interrupt event in task context.
- Waits on the semaphore with
-
intConnect()
- Connects the ISR to the interrupt vector.
MY_INT_VEC
andMY_INT_LVL
would normally be defined in your BSP.
-
intEnable()
- Enables the interrupt so the ISR can trigger.
⚡ What You’ll See #
When the interrupt occurs (either simulated or from hardware), you’ll see:
ISR: Interrupt occurred!
Driver Task: Handling interrupt event
Repeating as the device generates interrupts.
🔍 Key Takeaways #
- ISRs must be lightweight — avoid blocking, printing, or heavy computation.
- Use semaphores or message queues to notify a task for deferred work.
- Always connect the ISR with
intConnect()
and enable it withintEnable()
.
✅ Wrap-Up #
In this tutorial, you learned:
- How to implement an ISR in VxWorks.
- How to connect interrupts to drivers.
- How to offload work from ISR to a driver task.
In the next blog, we’ll look at network programming in VxWorks — sending and receiving data using sockets.
👉 Stay tuned for Blog 7: “Networking with VxWorks: Socket Programming Basics.”