interrupt handling

bridged with qnx.rtos
Post Reply
dadji

interrupt handling

Post by dadji » Wed Jul 25, 2007 5:41 pm

Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used the
function InterruptAttach to connect the handler to the Interrupt line. As i
notice that the handler didn't notice one particular interrupt, i decided no
to unmask the interrupt line. I also deceided to use a ring buffer to store
the contain of the interrupt register each time it is read from the the HW
within the Interrupt Service Routine (ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by the
system!?
I thank you in advance.
Yannick D.


begin 666 NewsGroupRequest.jpg
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
MM`'PE_P!^?CQ_]$A2_P##A7]D?_H`^$_^_'QX_7_C)#_&
MOMS0?VQO#_AOXY?';X7_`!=\2VMJFC_&3P'\-?@IX?\`#7A2_P!7\37UIK/P
MKTWQUXMU77K?0H[Z^/AGPU)<SZKXE\<:I;V>@^$=%*2ZM=V]L%D-S2_^"CO[
M)FKKXSFMO%7Q#MM/\$Z'<>*)=;U7X,_$K2= \;>%[35;72+WQ-\(M:O=!BL/
MBWX?L9KZROKW5_ DNL65KH5W:Z]-*FES)<$]MF3A2FJLW&KA:6,34I)*C44)
M)RU25M$TMI75BG2@KWIQCRU94KN*2=2.K2;2NFE=?W7IHSX7_P"'"O[(_P#T
M`?"?_?CX\?\`T2%'_#A7]D?_`* /A/\`[\?'C_Z)"OV(T;XJ^ O$/Q#UWX6:
M)KAU/QKX9\%^%OB)K5E:V5W+IEIX1\9WNIZ?X:OUU]8CI%U=:E<:/?M_9<%T
MU]!;)!=3Q);W=N[^B=?;V]*PGCL?2?+.K5C)6O%N=U\-KJ_DOQ)C"A*SBJ<D
MU&2:2:M)1:::6NC7S=NI^&?_``X5_9'_`.@#X3_[\?'C_P"B0H_X<*_LC_\`
M0!\)_P#?CX\?_1(5^YE%0LRQF_MZGSE+R6U_)?F5[*G_`"0_\!7?T_K;8_ [
M6?\`@AM^R3I.O>"]%'A;PA<+XMU+6=/DN6'QZC>P&DZ'<:RLL<2_M&LLYG:W
M^S,KO&(U<R LP"GI?^'"O[(W_0!\)_3R/CQT^O\`PTAC]<^U?L'XP./'7P;]
M_$7C#_U"=1_R3VKRWXPZ-\6O%?Q T3P_\,_B(W@6WT[P-<>(];2:ZN+>SU!?
M^$C-@KEK6TNG2>*!65I7")'#\P^84WF&,LK5ZBO:_OSONM=WV6VROV0O94_Y
M(_\`@*\O+R_%]S\SO^'"O[(__0!\)_\`?CX\?_1(4?\`#A7]D?\`Z /A/_OQ
M\>/_`*)"OT-UZ'QAX7T>V\0:]\3K.RTB\A6;3KD?%[QC<-K>5B<1Z';V_A62
M?5YY4E1XK?3TGE=7!C5A@FAXJ^(_Q^\)_LI:W\2_A'H_PV^(/Q*\'S^--<U'
M3/CSXH\=>&O#U[X.\*7OB*XU: :UX2\/:GXI_P"$FM[/3[*ST.UU#1[:VF+3
M?VM+:/&@-4\=C:DXQ6(DGS)7E4DELK7;>WNK>S'[*F]%3B^FD5V?E^/?TT^
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
MU%%I2NKPE!^=WW(I^QG/V<81<N5/X8OJH]K%=W:NC\-?^'"O[(_\`T ?"
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
M_$A\)]L'R/CQQ_YLA_\`JK]S*,@=?\*7]HXU;5ZCV^W+^[_>\A>RI_R1_P#
M5Y>7E^+[GX&Z-_P0V_9)U;7_`!IHA\+>$+=?".HZ-8)<J/CU(VH#5M#M]9:6
M2-OVC56W-NTYME5&<2*HE)!.*Z;_`(<*_LC_`/0!\)_]^/CQ_P#1(5^PW@H!
MO'_QA!P0?$O@P$'OGP7I^0?3@_E7SEHWASXXZ_KNL^*F^+21>#M2\9>+/#V@
M>%;[Q3JOARZ2[L];O=.TZRMK[3](O"TB?8IC:6$/F-<0C#E3&:?]H8Q.WUB:
MT3UG+M%]_)?EV'[*G_)#_P`!7^1\#?\`#A7]D?\`Z /A/_OQ\>/_`*)"C_AP
MK^R/_P! 'PG_`-^/CQ_]$A7W1XUUKQGX,NHM+F^(T\OB1+W3'ET?1_B'XL\3
M:A86HU;2$NI-9TR3PS%8Z?:36E\B"36KFRM9UN/W<IEV*<O]KCXY?MD_"/XL
M?!CPA^S_`/"_]E/QMX,^-?C#3_AGI&K_`!K^(_Q?\(^*]$\?SZ1XH\0ZA-?Z
M9X#\'>(-%E\%PZ5H$$-A=P7KZW-J%U,MQ8QV\4<C:4L9CJLE".):=OM5'%:<
MN[;2Z+KM?MI,J5-1;5.+Y4VTHJ]EJWM?1+\^K/BO_APK^R/_`- 'PG_WX^/'
M_P!$A1_PX5_9'_Z /A/_`+\?'C_Z)"OT$\%?MI_##6KGQ_X*UN3Q#KOQ7^!N
MEZT/CUIGP;^%WQ8\=^ ?"GBWPM#I,_B/PCX5\52>&8Y?$FNI#K>GW.A^&A&O
MBC6K-[FYM=.=+.=DIV?_``4(_9>OOAEK_P`51KOQ+L-+\-^*=-\#ZCX$U?X*
M?$S2?CE<>*=9A^U:1I.C? V]T"/XEZY/J=BL^IV4FEZ#<1W&E6.HZC&3:6%S
M)&WB<P7M%&M5FJ+IQG.,I.-ZDH1IV=]>9VMW[(E1I/V:E34)5-E.*33BKR4M
MK62N^V[29\#_`/#A7]D?_H ^$_\`OQ\>/_HD*/\`APK^R/\`] 'PG_WX^/'_
M`-$A7W7J_P#P46_9:\/S^%K;7=3^+^DS^)M.TC5[^&_^`/Q8M9/AAIFOSB#1
M;WX[I-X;1_@?!J<1;5+-OB0-"\_18IM87.GQ/,,OXS?M$?M0?![XE^&=7NO@
MY\$-<_9=\5?%/X7?"K1O$%G\2/&!_:&UR^^)<L>GQ^*=!\&Q:(_P[N/#NBZI
M*DMQ;3^(H]:NM%/VNWLWGPAJ-?,Y.E%U:L(UJCIPJN3474C;W4V[-OE=DKW2
M;UW+E3I1YDX1YE359044Y.#:]ZS6D==6]%\SXH_X<*_LC_\`0!\)_P#?CX\?
M_1(4?\.%?V1_^@#X3_[\?'C_`.B0K]N==N-5L=%UBZT'38M:URVTV]FT72+B
MY6RM]3U5+=WT^QN;P_\`'G;3W7E175P`7@A\UHU>154_E#\0OV\_VHOV?_ 7
M[3%U^T)\#OV=K#XF?!'X!>$/C[X<@^&'Q3^(6M?"B32O%WCI/ 8\,_%7Q#XG
M\-:7XG\,:KHETMUK>H7^@:5J.ERZ)")[2XFE$BKG2QN.JU*E*%>7/2@YV=1I
MS4.7FY;R5[65^R-:.%C6<(PIQ;G)0^%+ENE9R=E9-Z+>[NCR3_APK^R/_P!
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
M=.:IU%4LWR-336MDM=DKF/:_L$?\$U;HJ$\`^)5W<@MH7Q6''7./^&J_IQJ@\CT&?RK[&TCX-> Y?#=M\1[7Q
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
M_P#H!Z1_X>KX;?XTOJ6(_P"?;^:?EY>?]:7/:0_F1^K]%?E!_P`/<_@7_P!
M/1__``]?PV/\C1_P]S^!?_0#T?\`\/7\-O\`'K[=:?U+$_\`/M_CY>7G^##V
MD/YE]Z\O/S_,_5^BOR@_X>Y_`O'_`" ](_\`#U?#;CZ\\?C1_P`/<O@7_P!
M/2/_``]7PV_QS^F*7U+$?\^W]S\O+S_K2Y[2'\R^\_5^BOR@_P"'N?P+_P"@
M'I'_`(>KX;<_K_+-'_#W/X%_] /1_P#P]?PV[?CU]NM-8+$O_EV_QZV\O/\`
M!A[2'\R^]>7=^?X,_5^BOR@_X>Y_`O\`Z >C_P#AZ_AL/YFC_A[G\"_^@'I'
M_AZOAM_C2^I8G_GW+[G_`)?U9^5SVD/YE]Y^K]%?E!_P]S^!?_0#TC_P]7PV
M_P`:/^'N?P+_`.@'H_\`X>OX;'^1H6"Q#_Y=O\?+R\_ZTN>TA_,OO\[?UY'Z
MOT5^4'_#W/X%_P#0#TC_`,/5\-O\:/\`A[G\"_\`H!Z1_P"'J^&W^-/ZEB?^
M?;^Y^7EY_@_*Y[2'\R^\_5^BOR@_X>Y_`O\`Z >D?^'J^&_^-'_#W/X%_P#0
M#TC_`,/5\-_\:7U+$_\`/M_<_+R\_P"M+GM(?S+[S]7Z*_*#_A[G\"_^@'I'
M_AZOAO\`XT?\/<_@7_T`](_\/5\-_P#&G]2Q/_/M_<_+R\_P8>TA_,OO].U^
M_P!]S]7Z*_*#_A[G\"_^@'I'_AZOAO\`XT?\/<O@7_T`](_\/5\-_P#&E]2Q
M/_/M_<_+R\_P]+GM(?S(_5^BOR@_X>Y_`O\`Z >D?^'J^&_^-'_#W/X%_P#0
M#T?_`,/7\-NWX]?;K3^HXG_GV_Q\O+S_``?8/:0_F7WKR[OS_!GZOT5^4'_#
MW/X%_P#0#T?_`,/7\-A_,T?\/<_@7_T`](_\/5\-O\:7U+$_\^Y?<_\`+^K/
MRN>TA_,C]7Z*_*#_`(>Y_ O_`* >D?\`AZOAM_C1_P`/<_@7_P! /1__``]?
MPV/\C36"Q+_Y=O7U\O+S_!A[2#VDOO\`-+KZ_F?J_17Y0?\`#W/X%_\`0#T?
M_P`/7\-O\>OMUH_X>Y_ O_H!Z/\`^'K^&W'UYX_&CZEB?^?;^Y^7EY_@_*Y[
M2'\R^\_5^BOR@_X>Y? O_H!Z1_X>KX;?XY_3%'_#W/X%_P#0#TC_`,/5\-N?
MU_EFDL%B'_R[?X];>7G_`%I<]I#^9??^NQ^K]%?E`/\`@KG\"_\`H!Z1W_YK
M5\-NW;K_`/7]J/\`A[G\"_\`H!Z/_P"'K^&P_F:?U+$_\^W]S\O+S_!^5SVD
M.LDOGY)]/4_5^BOR@_X>Y_ O_H!Z1_X>KX;?XT?\/<_@7_T`](_\/5\-O\:7
MU+$?\^W]S\O+S_K2Y[2'\R^_^OZ]4?J_17Y0?\/<_@7_`- /1_\`P]?PV/\`
M(T?\/<_@7_T`]'_\/7\-O\>OMUI_4L3_`,^W^/EY>?X,/:0_F7WKR^?7\'V/
MU?HK\H/^'N?P+_Z >D?^'J^&W^-'_#W/X%_]`/2/_#U?#?\`QI?4L3_S[E]S
M_P`OZL_*Y[2'\R^_^NW]71^K]%?E!_P]S^!?_0#TC_P]7PV_QH_X>Y_ O_H!
MZ1_X>KX;_P"--8+$O_EV_P`?+R\_P8>TA_,OO7EW]?P9^K]%?E!_P]S^!?\`
MT ](_P##U?#?_&C_`(>Y_ O_`* >D?\`AZOAO_C2^I8G_GW+[G_E_5GY7/:0
M_F7WGZOT5^4'_#W+X%_]`/2/_#U?#?\`QH_X>Y_ O_H!Z/\`^'J^&W^--8+$
MO_EV_N?EY>?X,/:0_F7W_P"9^K]%?E!_P]S^!?\`T ](_P##U?#;_&C_`(>Y
M_ O./[$T?/\`V6OX;?XT?4L3_P`^W]S\O+S_``8>TA_,NG7OZ7]/4_5^BOR@
M_P"'N7P+_P"@'I'_`(>KX;_XT?\`#W/X%_\`0#TC_P`/5\-O\:2P6)_Y]O75
M:/;3R_K[KMS@FO>6J3W[GZOT5^4'_#W/X%\?\2/2/_#U?#?G]:/^'N?P+_Z
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
MBUF\;)XIL/B)I&F/ILR_;/#D@?[,BK_5XTJ<Z/++VN%PE:$^D:DWB

maschoen

RE: interrupt handling

Post by maschoen » Wed Jul 25, 2007 7:47 pm

I'm not able to look at your jpg right now, but 125u is short enough
that it is possible that occaisionally you do not reset your
interrupt before the next one comes in. If this happens because
your ISR is too long, then you will have to do something about that
yourself. Otherwise, you could try making your interrupt a higher
priority interrupt.

Kevin Stallard

Re: interrupt handling

Post by Kevin Stallard » Wed Jul 25, 2007 8:54 pm

I haven't used this tool for quite some time, so please forgive the naive
questions, but the tick marks under interrupt 0x5, if that is the actual
interrupt line, then the interrupt is indeed missing as it never occured.

Also something that is a bit suspect is the irregularity of the interrupt
(if the tick marks are the actual interrupt). Are you sure this device is
interrupting reliably on the 125usec interval as you say should be
happening?

Thanks
Kevin

"dadji" <ydadji@hotmail.com> wrote in message
news:f8817p$p8a$1@inn.qnx.com...
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used the
function InterruptAttach to connect the handler to the Interrupt line. As
i notice that the handler didn't notice one particular interrupt, i
decided no to unmask the interrupt line. I also deceided to use a ring
buffer to store the contain of the interrupt register each time it is read
from the the HW within the Interrupt Service Routine (ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by
the system!?
I thank you in advance.
Yannick D.


Colin Burgess

Re: interrupt handling

Post by Colin Burgess » Thu Jul 26, 2007 11:47 am

There's no reason for this interrupt to be dropped that I can see. Kevin's note that the interrupts
to be irregular is interesting. They do appear to smooth out after that burst of activity. I would
suspect that some other application is enabling/disabling interrupts.

Is interrupt 5 shared with another driver?

On another note, if you are using 6.3.2 then you really should upgrade to the 4.0.1 IDE, the System
Profiler is much much better in that version.

Also, you appear to be running a pre-SP2 version of tracelogger, given the number of threads running
in it. Check the output of use -i /usr/sbin/tracelogger

Regards,

Colin

dadji wrote:
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used the
function InterruptAttach to connect the handler to the Interrupt line. As i
notice that the handler didn't notice one particular interrupt, i decided no
to unmask the interrupt line. I also deceided to use a ring buffer to store
the contain of the interrupt register each time it is read from the the HW
within the Interrupt Service Routine (ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by the
system!?
I thank you in advance.
Yannick D.



// System include
#include <pthread.h
#include <sched.h
#include <stdio.h

// just for tiime measurements
#include <sys/types.h
#include <sys/syspage.h
#include <hw/inout.h

// local include
#include "callback.h"
#include "general.h"
#include "interrupt.h"
#include "hw_ohci.h"
#include "ieee1394_private.h"

#define BUFFERSIZE 100


volatile t_uint32 IntRegRingBuffer[BUFFERSIZE]; // ring buffer for interrupt register contain
int iLeftBufferIndex;
int iRightBufferIndex;

extern int iIAsyncRxIntCount ;

extern t_CommStatus *psCommStatus; // declared in init.c
extern t_ShMemAddress sShMemAddress; //declared in inti.c
extern t_CommConfigExtension *psCommConfigExtension; //declared in inti.c

/**
* Create interrupt thread
*
* This function configures and starts the interrupt thread.
*
* @param OhciCard
*
* @return IEEE1394_OK
*/
unsigned int Create_Int_Thread( tGlobal_Config *OhciCard )
{
pthread_attr_t attr;

// Iinitialize attribute structure
pthread_attr_init( &attr );

// reset the bufferindex
iLeftBufferIndex = 0;
iRightBufferIndex = 0;

// set the detach state to "detached"
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );

// set thread attributes
pthread_attr_setinheritsched( &attr, DEFAULT_INT_THREAD_INHERIT );
pthread_attr_setschedpolicy( &attr, DEFAULT_INT_THREAD_POLICY );
attr.param.sched_priority = DEFAULT_INT_THREAD_PRIORITY;

// create new thread: Int_Thread
pthread_create( NULL, &attr, &Int_Thread, (void*) OhciCard);

return( IEEE1394_OK );
}


/**
* This thread is dedicated to handling and managing interrupts
*/
void * Int_Thread (void *arg){
int interruptID = 0;
t_AsyncRxBuffer* psAsyncRxBuffer;
t_RxBufferIndex* psRxBufferIndex;
t_BusStatus* psBusStatus;


struct sigevent event;
volatile _uint32 rx_event;
volatile _uint32 tx_event;
tGlobal_Config* OhciCard = (tGlobal_Config*) arg;

// set local pointer variables (shorter names)
psAsyncRxBuffer = sShMemAddress.psAsyncRxBuffer;
psRxBufferIndex = sShMemAddress.psRxBufferIndex;
psBusStatus = sShMemAddress.psBusStatus;

sShMemAddress.psBusStatus->uiBusStatusFlag = BUS_STATUS_FLAG_INIT;

OhciCard->uICancelIntThread = FALSE;

// enable I/O privilege
ThreadCtl (_NTO_TCTL_IO, NULL);

// init event
SIGEV_INTR_INIT(&event);

// attach the ISR to IRQ
interruptID = InterruptAttach ( PciInf.Irq, isr_handler, &event, sizeof(event), 0 );

// printf("InterruptID = %d\n", interruptID);

if (interruptID == -1)
{
printf("InterruptAttach() fehlgeschlagen!\n");

exit(-1);
}

// now service the hardware when the ISR says to
while( 1 )
{
InterruptWait (NULL, NULL);

// check if some interrupts were received
while(iRightBufferIndex != iLeftBufferIndex)
{
// check if overflow
if(iRightBufferIndex == ( (iLeftBufferIndex+1) % BUFFERSIZE) )
printf("INT_THREAD: Error Ring buffer overflow\n");

// while loop, because of the CST that can arrive while the IntThread is processing
if( IntRegRingBuffer[iRightBufferIndex])
{
if( OhciCard->uICancelIntThread )
{
// disable interrupts
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear, 0xFFFFFFFF);

InterruptUnmask( PciInf.Irq, interruptID);

// Detach the interrupt source
InterruptDetach(interruptID);

pthread_exit(NULL);
}

// do the work
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_cycleInconsistent) {

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_cycleInconsistent;
}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_cycleSynch) {

#ifdef _SYNC_MEASURE
out8(0x378, 1);
#endif

CB_OHCI1394_cycleSynch(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_cycleSynch;
}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_reqTxComplete) {

CB_OHCI1394_reqTxComplete(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_reqTxComplete;

}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_isochTx)
{
tx_event = *IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoXmitIntEventSet);

IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoXmitIntEventClear, tx_event);

CB_OHCI1394_isochTx(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_isochTx;
}


////////////////////////////////// Async Packet received //////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_RQPkt)
{
++iIAsyncRxIntCount;

// lock mutex when SHARED MEMORY is accessed
pthread_mutex_lock(&(psBusStatus->BusStatusMutex));

// Check if Busreset Packet received
if (psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].aulPacket[ 0 ] & 0xE0)
{
// if Packet mode activ
if (psCommConfigExtension->uiAsyncRxMode == ASYNC_RX_PACKET_MODE)
{
psBusStatus->uiGenCount =
((psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].aulPacket[ 2 ] & 0xFF0000) >> 16);
}
}

// Async packet received
else if(psCommStatus->uiAsyRxRunning == TRUE)
{

// Decrement uiRxPktsToGo counter in STATUS
if( psCommStatus->uiAsyRxPktsToGo > 0 )
psCommStatus->uiAsyRxPktsToGo--;

// Set Flag if all packets received
if( psCommStatus->uiAsyRxPktsToGo == 0 )
psCommStatus->uiAsyRxPktsDone = TRUE;

// check if receive Buffer not full
if( ((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER) == psRxBufferIndex->ulAsyncListHead )
{
// too many receives pending ==> packet lost!
psRxBufferIndex->ulAsyncListHead = ((psRxBufferIndex->ulAsyncListHead+1)%MAX_RX_PKTS_IN_BUFFER);

// set Packet-Lost-Flag
psCommStatus->uiAsyRxPktLost = TRUE;
}

// insert message into ASYNC receive list
psRxBufferIndex->ulAsyncListToe = ((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER);

// set the adress of the next packet
OhciCard->psAsyncRxDeskr->DataAddress = psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].dataoffset;


// check if last Packet receive
if (psCommStatus->uiAsyRxPktsDone == TRUE)
{
// set the receive complete Flag
sShMemAddress.psBusStatus->uiBusStatusFlag |= BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// case of Auto Async Receive
if(!psCommConfigExtension->uiNotifyAsyRx)
{
// check if Automatic Asynchronous Rx set.
if (psCommConfigExtension->uiContinuousAsyncRx)
{
// reset the packet counter
psCommStatus->uiAsyRxPktsToGo = psCommConfigExtension->uiNumberOfAsyncRxPkts;
psCommStatus->uiAsyRxPktsDone = FALSE;
}

// inform the User Callback Control Thread
sem_post( &sShMemAddress.psBusStatus->sem_UC_Control );
}
else //case of Manuell receive
{
// execute stop reception
psCommConfigExtension->uiNotifyAsyRx = FALSE;
sShMemAddress.psBusStatus->uiAsyncRxEventCode = ACK_COMPLETE;

// send sync pulse back to APPLICATION
MsgReply(OhciCard->ircvid, 0, NULL, 0);
}
}

}

// unlock mutex
pthread_mutex_unlock(&(psBusStatus->BusStatusMutex));

IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15); /* run-Bit zurücksetzen */
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15); /* run-Bit setzen */

#ifdef _ASYNC_AUTO_RX

if (iProfilerId < iMaxMsrIteration)

PROFILER_Mark(0, 1);

#endif

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_RQPkt;
}

/*** Handle Block Rx ***/
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_ARRQ)
{
CB_OHCI1394_ARRQ(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_ARRQ;
}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_isochRx)
{
rx_event = *IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoRecvIntEventSet);

IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoRecvIntEventClear, rx_event);

CB_OHCI1394_isochRx(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_isochRx;
}

// Busreset Interrupt
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_busReset)
{
if(psCommStatus->uiBusResetRunning == TRUE)
{

// if the Block-Mode is active, then change to the packet-Mode
if (psCommConfigExtension->uiAsyncRxMode == ASYNC_RX_BLOCK_MODE)
{
//// reset the Block-Mode ////


// Disable ARRQ Interrupt
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear, OHCI1394_ARRQ);

// clear the ARRQ-interrupt in the event register
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_ARRQ);

// Stop command. Stop the Processing of the Async Rx Block-Mode
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15);


//////////// Setting configuration for default mode (Packet-Mode) /////////////
psCommConfigExtension->uiAsyncRxMode = ASYNC_RX_PACKET_MODE;
psCommStatus->uiAsyRxPktsDone = FALSE;
psCommStatus->uiAsyRxPktsToGo = DEFAULT_NUMBER_OF_ASYNC_RX_PKTS;
psCommStatus->uiAsyRxRunning = TRUE;

// Enable RQPkt Interrupt for the normal mode
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// set the default Descriptor
IEEE1394_HW_OHCI_SetReg(OHCI1394_AsReqRcvCommandPtr, OhciCard->AsyncRxDeskrOffset | 0x1);

//clear the FIFOs for the Packet-Mode
sShMemAddress.psRxBufferIndex->ulAsyncListHead = 0;
sShMemAddress.psRxBufferIndex->ulAsyncListToe = 0;
sShMemAddress.psBusStatus->uiBusStatusFlag &= ~BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// start the Packet Mode
// clear the RQPkt-interrupt in the event register
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_RQPkt);

// set the RQPkt interrupt
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// reset and set run Bit, to force the ieee1394 PCI Device to fetch descriptor information
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15);

}

psBusStatus->uiLocalBusId =
(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0xFFC0) >> 6;

psBusStatus->uiLocalNodeId =
(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0x3F);

psCommStatus->uiRootNodeEnabled = IEEE1394_HW_OHCI_GetBit(OHCI1394_NodeID, 30);

// inform the Driver API
sShMemAddress.psBusStatus->uiBusStatusFlag |= BUS_STATUS_FLAG_BUS_RST_OCCURED;

sem_post( &sShMemAddress.psBusStatus->sem_UC_Control );
}

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_busReset;

}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_selfIDComplete) {

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_selfIDComplete;
}

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("IntRegRingBuffer[iRightBufferIndex] contain [0x%x] Event clear register[0x%x]\n",
IntRegRingBuffer[iRightBufferIndex], *IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear) );
}

}// if(IntRegRingBuffer[iRightBufferIndex])

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("ATTENTION: no processed Interrupt: 0x%X\n", IntRegRingBuffer[iRightBufferIndex]);
}

// increment the RightBufferIndex
iRightBufferIndex = (iRightBufferIndex +1) % BUFFERSIZE;

} //while (iRightBufferIndex != iLeftBufferIndex)

}
}


/**
* This is the interrupt service routine
*
* The routine will be activated by every occurring interrupt,
* it reads the interrupt-register-status of the card
* and reset it immediatly after this. In case the
* interrupt was generated from the PCI card, the Interrupt-Thread
* is inform about throug the SIGEV_INTR event
*
* @param event
* @param interruptID: return value of the InterruptAttach function
*
* Return SIGEV_INTR in case a Interrupt occures if not return NULL
*/
const struct sigevent * isr_handler (void *event, int interruptID)
{
// Read and clear the interrupt event register
IntRegRingBuffer[iLeftBufferIndex] = *IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear);
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, IntRegRingBuffer[iLeftBufferIndex] );

// check if Interrupt for the attached card
if (!IntRegRingBuffer[iLeftBufferIndex])
{
return NULL;
}
else
{
iLeftBufferIndex = (iLeftBufferIndex +1) % BUFFERSIZE;

// return the event to the IntThread
return (event);
}
}
--
cburgess@qnx.com

Colin Burgess

Re: interrupt handling

Post by Colin Burgess » Thu Jul 26, 2007 11:48 am

One more thing - I would recommend that you always pass _NTO_INTR_FLAGS_TRKMSK to InterruptAttach
so that the kernel will keep tabs on your mask level.

Colin Burgess wrote:
There's no reason for this interrupt to be dropped that I can see.
Kevin's note that the interrupts
to be irregular is interesting. They do appear to smooth out after that
burst of activity. I would
suspect that some other application is enabling/disabling interrupts.

Is interrupt 5 shared with another driver?

On another note, if you are using 6.3.2 then you really should upgrade
to the 4.0.1 IDE, the System
Profiler is much much better in that version.

Also, you appear to be running a pre-SP2 version of tracelogger, given
the number of threads running
in it. Check the output of use -i /usr/sbin/tracelogger

Regards,

Colin

dadji wrote:
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used
the function InterruptAttach to connect the handler to the Interrupt
line. As i notice that the handler didn't notice one particular
interrupt, i decided no to unmask the interrupt line. I also deceided
to use a ring buffer to store the contain of the interrupt register
each time it is read from the the HW within the Interrupt Service
Routine (ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In
the trace picture you will see the interrupt line (0x5) and the
interrupt handler. Special 1394 Interrupt called CST-interrupt occur
every 125 microsec. In the trace picture one CST interrupt is missed.
i don't know waht could be the cause of this, since i don't mask the
interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed
by the system!?
I thank you in advance.
Yannick D.



// System include
#include <pthread.h
#include <sched.h
#include <stdio.h

// just for tiime measurements
#include <sys/types.h
#include <sys/syspage.h
#include <hw/inout.h

// local include
#include "callback.h"
#include "general.h"
#include "interrupt.h"
#include "hw_ohci.h"
#include "ieee1394_private.h"

#define BUFFERSIZE 100


volatile t_uint32 IntRegRingBuffer[BUFFERSIZE]; // ring buffer for
interrupt register contain
int iLeftBufferIndex;
int iRightBufferIndex;

extern int iIAsyncRxIntCount ;

extern t_CommStatus *psCommStatus; // declared in init.c
extern t_ShMemAddress sShMemAddress; //declared in inti.c
extern t_CommConfigExtension *psCommConfigExtension; //declared in
inti.c

/**
* Create interrupt thread
*
* This function configures and starts the interrupt thread.
*
* @param OhciCard
*
* @return IEEE1394_OK
*/
unsigned int Create_Int_Thread( tGlobal_Config *OhciCard )
{
pthread_attr_t attr;

// Iinitialize attribute structure
pthread_attr_init( &attr );

// reset the bufferindex
iLeftBufferIndex = 0;
iRightBufferIndex = 0;

// set the detach state to "detached"
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );

// set thread attributes
pthread_attr_setinheritsched( &attr, DEFAULT_INT_THREAD_INHERIT );
pthread_attr_setschedpolicy( &attr, DEFAULT_INT_THREAD_POLICY );
attr.param.sched_priority = DEFAULT_INT_THREAD_PRIORITY;

// create new thread: Int_Thread
pthread_create( NULL, &attr, &Int_Thread, (void*) OhciCard);

return( IEEE1394_OK );
}


/**
* This thread is dedicated to handling and managing interrupts
*/
void * Int_Thread (void *arg){
int interruptID = 0;
t_AsyncRxBuffer* psAsyncRxBuffer;
t_RxBufferIndex* psRxBufferIndex;
t_BusStatus* psBusStatus;


struct sigevent event;
volatile _uint32 rx_event;
volatile _uint32 tx_event;
tGlobal_Config* OhciCard = (tGlobal_Config*) arg;

// set local pointer variables (shorter names)
psAsyncRxBuffer = sShMemAddress.psAsyncRxBuffer;
psRxBufferIndex = sShMemAddress.psRxBufferIndex;
psBusStatus = sShMemAddress.psBusStatus;

sShMemAddress.psBusStatus->uiBusStatusFlag = BUS_STATUS_FLAG_INIT;

OhciCard->uICancelIntThread = FALSE;

// enable I/O privilege
ThreadCtl (_NTO_TCTL_IO, NULL);

// init event
SIGEV_INTR_INIT(&event);

// attach the ISR to IRQ
interruptID = InterruptAttach ( PciInf.Irq, isr_handler, &event,
sizeof(event), 0 );

// printf("InterruptID = %d\n", interruptID);

if (interruptID == -1)
{
printf("InterruptAttach() fehlgeschlagen!\n");

exit(-1);
}

// now service the hardware when the ISR says to
while( 1 )
{
InterruptWait (NULL, NULL);

// check if some interrupts were received
while(iRightBufferIndex != iLeftBufferIndex)
{
// check if overflow
if(iRightBufferIndex == ( (iLeftBufferIndex+1) %
BUFFERSIZE) )
printf("INT_THREAD: Error Ring buffer overflow\n");

// while loop, because of the CST that can arrive while
the IntThread is processing
if( IntRegRingBuffer[iRightBufferIndex])
{
if( OhciCard->uICancelIntThread )
{
// disable interrupts
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear,
0xFFFFFFFF);

InterruptUnmask( PciInf.Irq, interruptID);

// Detach the interrupt source
InterruptDetach(interruptID);

pthread_exit(NULL);
}

// do the work
if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_cycleInconsistent) {

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_cycleInconsistent;
}
if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_cycleSynch) {

#ifdef _SYNC_MEASURE
out8(0x378, 1);
#endif

CB_OHCI1394_cycleSynch(OhciCard);

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_cycleSynch;
}

if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_reqTxComplete) {

CB_OHCI1394_reqTxComplete(OhciCard);

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_reqTxComplete;

}

if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_isochTx)
{
tx_event =
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoXmitIntEventSet);


IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoXmitIntEventClear, tx_event);

CB_OHCI1394_isochTx(OhciCard);

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_isochTx;
}


////////////////////////////////// Async Packet
received //////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_RQPkt)
{
++iIAsyncRxIntCount;

// lock mutex when SHARED MEMORY is accessed
pthread_mutex_lock(&(psBusStatus->BusStatusMutex));

// Check if Busreset Packet received
if (psAsyncRxBuffer[
psRxBufferIndex->ulAsyncListToe ].aulPacket[ 0 ] & 0xE0)
{
// if Packet mode activ
if (psCommConfigExtension->uiAsyncRxMode ==
ASYNC_RX_PACKET_MODE)
{
psBusStatus->uiGenCount =
((psAsyncRxBuffer[
psRxBufferIndex->ulAsyncListToe ].aulPacket[ 2 ] & 0xFF0000) >> 16);
}
}

// Async packet received
else if(psCommStatus->uiAsyRxRunning == TRUE)
{

// Decrement uiRxPktsToGo counter in STATUS
if( psCommStatus->uiAsyRxPktsToGo > 0 )
psCommStatus->uiAsyRxPktsToGo--;

// Set Flag if all packets received
if( psCommStatus->uiAsyRxPktsToGo == 0 )
psCommStatus->uiAsyRxPktsDone = TRUE;

// check if receive Buffer not full
if(
((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER) ==
psRxBufferIndex->ulAsyncListHead )
{
// too many receives pending ==> packet lost!
psRxBufferIndex->ulAsyncListHead =
((psRxBufferIndex->ulAsyncListHead+1)%MAX_RX_PKTS_IN_BUFFER);

// set Packet-Lost-Flag
psCommStatus->uiAsyRxPktLost = TRUE;
}

// insert message into ASYNC receive list
psRxBufferIndex->ulAsyncListToe =
((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER);

// set the adress of the next packet
OhciCard->psAsyncRxDeskr->DataAddress =
psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].dataoffset;


// check if last Packet receive
if (psCommStatus->uiAsyRxPktsDone == TRUE)
{
// set the receive complete Flag
sShMemAddress.psBusStatus->uiBusStatusFlag
|= BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// case of Auto Async Receive
if(!psCommConfigExtension->uiNotifyAsyRx)
{
// check if Automatic Asynchronous Rx
set. if
(psCommConfigExtension->uiContinuousAsyncRx)
{
// reset the packet counter
psCommStatus->uiAsyRxPktsToGo =
psCommConfigExtension->uiNumberOfAsyncRxPkts;
psCommStatus->uiAsyRxPktsDone =
FALSE;
}

// inform the User Callback Control
Thread
sem_post(
&sShMemAddress.psBusStatus->sem_UC_Control );
}
else //case of Manuell receive
{
// execute stop reception
psCommConfigExtension->uiNotifyAsyRx =
FALSE;

sShMemAddress.psBusStatus->uiAsyncRxEventCode = ACK_COMPLETE;

// send sync pulse back to APPLICATION
MsgReply(OhciCard->ircvid, 0, NULL, 0);
}
}

}

// unlock mutex
pthread_mutex_unlock(&(psBusStatus->BusStatusMutex));


IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15); /*
run-Bit zurücksetzen */

IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15); /*
run-Bit setzen */

#ifdef _ASYNC_AUTO_RX

if (iProfilerId < iMaxMsrIteration)

PROFILER_Mark(0, 1);

#endif

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_RQPkt;
}

/*** Handle Block Rx ***/
if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_ARRQ) {
CB_OHCI1394_ARRQ(OhciCard);

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_ARRQ;
}

if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_isochRx)
{
rx_event =
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoRecvIntEventSet);


IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoRecvIntEventClear, rx_event);

CB_OHCI1394_isochRx(OhciCard);

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_isochRx;
}

// Busreset Interrupt
if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_busReset)
{
if(psCommStatus->uiBusResetRunning == TRUE)
{

// if the Block-Mode is active, then change to
the packet-Mode
if (psCommConfigExtension->uiAsyncRxMode ==
ASYNC_RX_BLOCK_MODE)
{
//// reset the Block-Mode ////


// Disable ARRQ Interrupt

IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear, OHCI1394_ARRQ);

// clear the ARRQ-interrupt in the event
register

IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_ARRQ);

// Stop command. Stop the Processing of
the Async Rx Block-Mode

IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15);


//////////// Setting configuration for
default mode (Packet-Mode) /////////////
psCommConfigExtension->uiAsyncRxMode =
ASYNC_RX_PACKET_MODE;
psCommStatus->uiAsyRxPktsDone =
FALSE;
psCommStatus->uiAsyRxPktsToGo =
DEFAULT_NUMBER_OF_ASYNC_RX_PKTS;
psCommStatus->uiAsyRxRunning = TRUE;

// Enable RQPkt Interrupt for the normal mode

IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// set the default Descriptor

IEEE1394_HW_OHCI_SetReg(OHCI1394_AsReqRcvCommandPtr,
OhciCard->AsyncRxDeskrOffset | 0x1);

//clear the FIFOs for the Packet-Mode

sShMemAddress.psRxBufferIndex->ulAsyncListHead = 0;

sShMemAddress.psRxBufferIndex->ulAsyncListToe = 0;
sShMemAddress.psBusStatus->uiBusStatusFlag
&= ~BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// start the Packet Mode
// clear the RQPkt-interrupt in the event
register

IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_RQPkt);

// set the RQPkt interrupt

IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// reset and set run Bit, to force the
ieee1394 PCI Device to fetch descriptor information

IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15);

}

psBusStatus->uiLocalBusId =

(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0xFFC0) >> 6;

psBusStatus->uiLocalNodeId =

(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0x3F);

psCommStatus->uiRootNodeEnabled =
IEEE1394_HW_OHCI_GetBit(OHCI1394_NodeID, 30);

// inform the Driver API
sShMemAddress.psBusStatus->uiBusStatusFlag |=
BUS_STATUS_FLAG_BUS_RST_OCCURED;

sem_post(
&sShMemAddress.psBusStatus->sem_UC_Control );
}

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_busReset;

}

if (IntRegRingBuffer[iRightBufferIndex] &
OHCI1394_selfIDComplete) {

// reset the corresponding bit in the interrupt
register.
IntRegRingBuffer[iRightBufferIndex] &=
~OHCI1394_selfIDComplete;
}

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("IntRegRingBuffer[iRightBufferIndex]
contain [0x%x] Event clear register[0x%x]\n",
IntRegRingBuffer[iRightBufferIndex],
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear) );
}

}// if(IntRegRingBuffer[iRightBufferIndex])

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("ATTENTION: no processed Interrupt: 0x%X\n",
IntRegRingBuffer[iRightBufferIndex]);
}

// increment the RightBufferIndex
iRightBufferIndex = (iRightBufferIndex +1) % BUFFERSIZE;

} //while (iRightBufferIndex != iLeftBufferIndex)

}
}


/**
* This is the interrupt service routine
* * The routine will be activated by every occurring interrupt,
* it reads the interrupt-register-status of the card * and reset
it immediatly after this. In case the * interrupt was generated
from the PCI card, the Interrupt-Thread
* is inform about throug the SIGEV_INTR event
*
* @param event
* @param interruptID: return value of the InterruptAttach function
*
* Return SIGEV_INTR in case a Interrupt occures if not return NULL */
const struct sigevent * isr_handler (void *event, int interruptID)
{
// Read and clear the interrupt event register
IntRegRingBuffer[iLeftBufferIndex] =
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear);
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear,
IntRegRingBuffer[iLeftBufferIndex] );

// check if Interrupt for the attached card
if (!IntRegRingBuffer[iLeftBufferIndex])
{
return NULL;
}
else
{
iLeftBufferIndex = (iLeftBufferIndex +1) % BUFFERSIZE;

// return the event to the IntThread
return (event);
}
}

--
cburgess@qnx.com

dadji

Re: interrupt handling

Post by dadji » Thu Jul 26, 2007 1:12 pm

Hello,
how can i make my interrupt a higher priority interrupt?
If you mean the interrupt handler, it is already the highest priority thread
in the system.
Thanks.
"maschoen" <maschoen@pobox-dot-com.no-spam.invalid> schrieb im Newsbeitrag
news:f889c8$t6q$1@inn.qnx.com...
I'm not able to look at your jpg right now, but 125u is short enough
that it is possible that occaisionally you do not reset your
interrupt before the next one comes in. If this happens because
your ISR is too long, then you will have to do something about that
yourself. Otherwise, you could try making your interrupt a higher
priority interrupt.

Armin

Re: interrupt handling

Post by Armin » Thu Jul 26, 2007 4:25 pm

dadji wrote:
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used the
function InterruptAttach to connect the handler to the Interrupt line. As i
notice that the handler didn't notice one particular interrupt, i decided no
to unmask the interrupt line. I also deceided to use a ring buffer to store
the contain of the interrupt register each time it is read from the the HW
within the Interrupt Service Routine (ISR).
I would change the ISR in the following way if the IRQ5 is a _shared
interrupt_ :) :

const struct sigevent * isr_handler (void *event, int interruptID)
{

// check if Interrupt for the attached card
if (!IntRegRingBuffer[iLeftBufferIndex])
{
return NULL;
}
else
{
// Read and clear the interrupt event register
IntRegRingBuffer[iLeftBufferIndex] =
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear);
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear,
IntRegRingBuffer[iLeftBufferIndex] );

iLeftBufferIndex = (iLeftBufferIndex +1) % BUFFERSIZE;

// return the event to the IntThread
return (event);
}
}


Gruß

--Armin

htto://www.steinhoff-automation.com



I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by the
system!?
I thank you in advance.
Yannick D.


maschoen

RE: Re: interrupt handling

Post by maschoen » Thu Jul 26, 2007 5:58 pm

What I mean by higher priority interrupt, is that interrupts
themselves have priorities. This is a hardware feature of the
interrupt controller. Higher priority interrupts can pre-empt lower
priority interrupts, but not the other way around. If you execute
code in an ISR, then this priority could help. On the other hand,
if you have a thread that is woken up by the interrupt, it will not
help, as all ISR's execute ahead of threads. How you do this in
QNX 6 was a recent topic of dicussion either here or at the
www.openqnx.com forums. I don't recall exactly how, but it is a
very low level decision, probably made in the startup code.

dadji

Re: interrupt handling

Post by dadji » Fri Jul 27, 2007 7:46 am

Hello Kevin,
thank you for your contribution.
The tick mark are come from the CST-interrupts and other Asynchronous packet
interrupts. The CST is a reliable source of interrupt as part of the
IEEE1394 standard.
Thanks.
Yannick.

"Kevin Stallard" <kevin@a.com> schrieb im Newsbeitrag
news:f88chf$1cu$1@inn.qnx.com...
I haven't used this tool for quite some time, so please forgive the naive
questions, but the tick marks under interrupt 0x5, if that is the actual
interrupt line, then the interrupt is indeed missing as it never occured.

Also something that is a bit suspect is the irregularity of the interrupt
(if the tick marks are the actual interrupt). Are you sure this device
is interrupting reliably on the 125usec interval as you say should be
happening?

Thanks
Kevin

"dadji" <ydadji@hotmail.com> wrote in message
news:f8817p$p8a$1@inn.qnx.com...
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used
the function InterruptAttach to connect the handler to the Interrupt
line. As i notice that the handler didn't notice one particular
interrupt, i decided no to unmask the interrupt line. I also deceided to
use a ring buffer to store the contain of the interrupt register each
time it is read from the the HW within the Interrupt Service Routine
(ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by
the system!?
I thank you in advance.
Yannick D.




dadji

Re: interrupt handling

Post by dadji » Fri Jul 27, 2007 8:25 am

"Colin Burgess" <cburgess@qnx.com> schrieb im Newsbeitrag
news:f8a0s3$pn9$1@inn.qnx.com...
There's no reason for this interrupt to be dropped that I can see.
Kevin's note that the interrupts
to be irregular is interesting. They do appear to smooth out after that
burst of activity. I would
suspect that some other application is enabling/disabling interrupts.

Is interrupt 5 shared with another driver?
yes the graphic card is on the same line.

thank you for the further notes.
On another note, if you are using 6.3.2 then you really should upgrade to
the 4.0.1 IDE, the System
Profiler is much much better in that version.

Also, you appear to be running a pre-SP2 version of tracelogger, given the
number of threads running
in it. Check the output of use -i /usr/sbin/tracelogger

Regards,

Colin

dadji wrote:
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used
the function InterruptAttach to connect the handler to the Interrupt
line. As i notice that the handler didn't notice one particular
interrupt, i decided no to unmask the interrupt line. I also deceided to
use a ring buffer to store the contain of the interrupt register each
time it is read from the the HW within the Interrupt Service Routine
(ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by
the system!?
I thank you in advance.
Yannick D.



// System include
#include <pthread.h
#include <sched.h
#include <stdio.h

// just for tiime measurements
#include <sys/types.h
#include <sys/syspage.h
#include <hw/inout.h

// local include
#include "callback.h"
#include "general.h"
#include "interrupt.h"
#include "hw_ohci.h"
#include "ieee1394_private.h"

#define BUFFERSIZE 100


volatile t_uint32 IntRegRingBuffer[BUFFERSIZE]; // ring buffer for
interrupt register contain
int iLeftBufferIndex;
int iRightBufferIndex;

extern int iIAsyncRxIntCount ;

extern t_CommStatus *psCommStatus; // declared in init.c
extern t_ShMemAddress sShMemAddress; //declared in inti.c
extern t_CommConfigExtension *psCommConfigExtension; //declared in inti.c

/**
* Create interrupt thread
*
* This function configures and starts the interrupt thread.
*
* @param OhciCard
*
* @return IEEE1394_OK
*/
unsigned int Create_Int_Thread( tGlobal_Config *OhciCard )
{
pthread_attr_t attr;

// Iinitialize attribute structure
pthread_attr_init( &attr );

// reset the bufferindex
iLeftBufferIndex = 0;
iRightBufferIndex = 0;

// set the detach state to "detached"
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );

// set thread attributes
pthread_attr_setinheritsched( &attr, DEFAULT_INT_THREAD_INHERIT );
pthread_attr_setschedpolicy( &attr, DEFAULT_INT_THREAD_POLICY );
attr.param.sched_priority = DEFAULT_INT_THREAD_PRIORITY;

// create new thread: Int_Thread
pthread_create( NULL, &attr, &Int_Thread, (void*) OhciCard);

return( IEEE1394_OK );
}


/**
* This thread is dedicated to handling and managing interrupts
*/
void * Int_Thread (void *arg){
int interruptID = 0;
t_AsyncRxBuffer* psAsyncRxBuffer;
t_RxBufferIndex* psRxBufferIndex;
t_BusStatus* psBusStatus;


struct sigevent event;
volatile _uint32 rx_event;
volatile _uint32 tx_event;
tGlobal_Config* OhciCard = (tGlobal_Config*) arg;

// set local pointer variables (shorter names)
psAsyncRxBuffer = sShMemAddress.psAsyncRxBuffer;
psRxBufferIndex = sShMemAddress.psRxBufferIndex;
psBusStatus = sShMemAddress.psBusStatus;

sShMemAddress.psBusStatus->uiBusStatusFlag = BUS_STATUS_FLAG_INIT;

OhciCard->uICancelIntThread = FALSE;

// enable I/O privilege
ThreadCtl (_NTO_TCTL_IO, NULL);

// init event
SIGEV_INTR_INIT(&event);

// attach the ISR to IRQ
interruptID = InterruptAttach ( PciInf.Irq, isr_handler, &event,
sizeof(event), 0 );

// printf("InterruptID = %d\n", interruptID);

if (interruptID == -1)
{
printf("InterruptAttach() fehlgeschlagen!\n");

exit(-1);
}

// now service the hardware when the ISR says to
while( 1 )
{
InterruptWait (NULL, NULL);

// check if some interrupts were received
while(iRightBufferIndex != iLeftBufferIndex)
{
// check if overflow
if(iRightBufferIndex == ( (iLeftBufferIndex+1) % BUFFERSIZE) )
printf("INT_THREAD: Error Ring buffer overflow\n");

// while loop, because of the CST that can arrive while the IntThread is
processing
if( IntRegRingBuffer[iRightBufferIndex])
{
if( OhciCard->uICancelIntThread )
{
// disable interrupts
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear, 0xFFFFFFFF);

InterruptUnmask( PciInf.Irq, interruptID);

// Detach the interrupt source
InterruptDetach(interruptID);

pthread_exit(NULL);
}

// do the work
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_cycleInconsistent) {

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_cycleInconsistent;
} if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_cycleSynch) {

#ifdef _SYNC_MEASURE
out8(0x378, 1);
#endif

CB_OHCI1394_cycleSynch(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_cycleSynch;
}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_reqTxComplete) {

CB_OHCI1394_reqTxComplete(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_reqTxComplete;

}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_isochTx)
{
tx_event = *IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoXmitIntEventSet);

IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoXmitIntEventClear, tx_event);

CB_OHCI1394_isochTx(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_isochTx;
}


////////////////////////////////// Async Packet received
//////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_RQPkt)
{
++iIAsyncRxIntCount;

// lock mutex when SHARED MEMORY is accessed
pthread_mutex_lock(&(psBusStatus->BusStatusMutex));

// Check if Busreset Packet received
if (psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].aulPacket[ 0 ] &
0xE0)
{ // if Packet mode activ
if (psCommConfigExtension->uiAsyncRxMode == ASYNC_RX_PACKET_MODE)
{
psBusStatus->uiGenCount =
((psAsyncRxBuffer[ psRxBufferIndex->ulAsyncListToe ].aulPacket[ 2 ] &
0xFF0000) >> 16);
}
}

// Async packet received
else if(psCommStatus->uiAsyRxRunning == TRUE)
{ // Decrement uiRxPktsToGo counter in STATUS if(
psCommStatus->uiAsyRxPktsToGo > 0 )
psCommStatus->uiAsyRxPktsToGo--;

// Set Flag if all packets received
if( psCommStatus->uiAsyRxPktsToGo == 0 )
psCommStatus->uiAsyRxPktsDone = TRUE;

// check if receive Buffer not full
if( ((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER) ==
psRxBufferIndex->ulAsyncListHead )
{ // too many receives pending ==> packet lost!
psRxBufferIndex->ulAsyncListHead =
((psRxBufferIndex->ulAsyncListHead+1)%MAX_RX_PKTS_IN_BUFFER);

// set Packet-Lost-Flag
psCommStatus->uiAsyRxPktLost = TRUE;
}

// insert message into ASYNC receive list
psRxBufferIndex->ulAsyncListToe =
((psRxBufferIndex->ulAsyncListToe+1)%MAX_RX_PKTS_IN_BUFFER);

// set the adress of the next packet
OhciCard->psAsyncRxDeskr->DataAddress = psAsyncRxBuffer[
psRxBufferIndex->ulAsyncListToe ].dataoffset;


// check if last Packet receive
if (psCommStatus->uiAsyRxPktsDone == TRUE)
{
// set the receive complete Flag
sShMemAddress.psBusStatus->uiBusStatusFlag |=
BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// case of Auto Async Receive
if(!psCommConfigExtension->uiNotifyAsyRx)
{
// check if Automatic Asynchronous Rx set. if
(psCommConfigExtension->uiContinuousAsyncRx)
{
// reset the packet counter
psCommStatus->uiAsyRxPktsToGo =
psCommConfigExtension->uiNumberOfAsyncRxPkts;
psCommStatus->uiAsyRxPktsDone = FALSE;
}

// inform the User Callback Control Thread
sem_post( &sShMemAddress.psBusStatus->sem_UC_Control );
}
else //case of Manuell receive
{
// execute stop reception
psCommConfigExtension->uiNotifyAsyRx = FALSE;
sShMemAddress.psBusStatus->uiAsyncRxEventCode = ACK_COMPLETE;

// send sync pulse back to APPLICATION
MsgReply(OhciCard->ircvid, 0, NULL, 0);
}
}

}

// unlock mutex
pthread_mutex_unlock(&(psBusStatus->BusStatusMutex));

IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15); /*
run-Bit zurücksetzen */
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15); /*
run-Bit setzen */

#ifdef _ASYNC_AUTO_RX

if (iProfilerId < iMaxMsrIteration)

PROFILER_Mark(0, 1);

#endif

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_RQPkt;
}

/*** Handle Block Rx ***/
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_ARRQ) {
CB_OHCI1394_ARRQ(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_ARRQ;
}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_isochRx)
{
rx_event = *IEEE1394_HW_OHCI_GetReg(OHCI1394_IsoRecvIntEventSet);

IEEE1394_HW_OHCI_SetReg(OHCI1394_IsoRecvIntEventClear, rx_event);

CB_OHCI1394_isochRx(OhciCard);

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_isochRx;
}

// Busreset Interrupt
if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_busReset)
{
if(psCommStatus->uiBusResetRunning == TRUE)
{

// if the Block-Mode is active, then change to the packet-Mode
if (psCommConfigExtension->uiAsyncRxMode == ASYNC_RX_BLOCK_MODE)
{
//// reset the Block-Mode ////


// Disable ARRQ Interrupt
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskClear, OHCI1394_ARRQ);

// clear the ARRQ-interrupt in the event register
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_ARRQ);

// Stop command. Stop the Processing of the Async Rx Block-Mode
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlClear, 15);


//////////// Setting configuration for default mode (Packet-Mode)
/////////////
psCommConfigExtension->uiAsyncRxMode = ASYNC_RX_PACKET_MODE;
psCommStatus->uiAsyRxPktsDone = FALSE;
psCommStatus->uiAsyRxPktsToGo = DEFAULT_NUMBER_OF_ASYNC_RX_PKTS;
psCommStatus->uiAsyRxRunning = TRUE;

// Enable RQPkt Interrupt for the normal mode
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// set the default Descriptor
IEEE1394_HW_OHCI_SetReg(OHCI1394_AsReqRcvCommandPtr,
OhciCard->AsyncRxDeskrOffset | 0x1);

//clear the FIFOs for the Packet-Mode
sShMemAddress.psRxBufferIndex->ulAsyncListHead = 0;
sShMemAddress.psRxBufferIndex->ulAsyncListToe = 0;
sShMemAddress.psBusStatus->uiBusStatusFlag &=
~BUS_STATUS_FLAG_ASYNC_RX_COMPLETED;

// start the Packet Mode
// clear the RQPkt-interrupt in the event register
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear, OHCI1394_RQPkt);

// set the RQPkt interrupt
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntMaskSet, OHCI1394_RQPkt);

// reset and set run Bit, to force the ieee1394 PCI Device to fetch
descriptor information
IEEE1394_HW_OHCI_SetBit(OHCI1394_AsReqRcvContextControlSet, 15);

}

psBusStatus->uiLocalBusId =
(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0xFFC0) >> 6;

psBusStatus->uiLocalNodeId =
(*IEEE1394_HW_OHCI_GetReg(OHCI1394_NodeID) & 0x3F);

psCommStatus->uiRootNodeEnabled =
IEEE1394_HW_OHCI_GetBit(OHCI1394_NodeID, 30);

// inform the Driver API
sShMemAddress.psBusStatus->uiBusStatusFlag |=
BUS_STATUS_FLAG_BUS_RST_OCCURED;

sem_post( &sShMemAddress.psBusStatus->sem_UC_Control ); }

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_busReset;

}

if (IntRegRingBuffer[iRightBufferIndex] & OHCI1394_selfIDComplete) {

// reset the corresponding bit in the interrupt register.
IntRegRingBuffer[iRightBufferIndex] &= ~OHCI1394_selfIDComplete;
}

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("IntRegRingBuffer[iRightBufferIndex] contain [0x%x] Event clear
register[0x%x]\n",
IntRegRingBuffer[iRightBufferIndex],
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear) );
}

}// if(IntRegRingBuffer[iRightBufferIndex])

if (IntRegRingBuffer[iRightBufferIndex])
{
printf("ATTENTION: no processed Interrupt: 0x%X\n",
IntRegRingBuffer[iRightBufferIndex]);
}

// increment the RightBufferIndex
iRightBufferIndex = (iRightBufferIndex +1) % BUFFERSIZE;

} //while (iRightBufferIndex != iLeftBufferIndex)

}
}


/**
* This is the interrupt service routine
* * The routine will be activated by every occurring interrupt,
* it reads the interrupt-register-status of the card * and reset it
immediatly after this. In case the * interrupt was generated from the PCI
card, the Interrupt-Thread
* is inform about throug the SIGEV_INTR event
*
* @param event
* @param interruptID: return value of the InterruptAttach function
*
* Return SIGEV_INTR in case a Interrupt occures if not return NULL */
const struct sigevent * isr_handler (void *event, int interruptID)
{
// Read and clear the interrupt event register
IntRegRingBuffer[iLeftBufferIndex] =
*IEEE1394_HW_OHCI_GetReg(OHCI1394_IntEventClear);
IEEE1394_HW_OHCI_SetReg(OHCI1394_IntEventClear,
IntRegRingBuffer[iLeftBufferIndex] );

// check if Interrupt for the attached card
if (!IntRegRingBuffer[iLeftBufferIndex])
{
return NULL;
}
else
{
iLeftBufferIndex = (iLeftBufferIndex +1) % BUFFERSIZE;

// return the event to the IntThread
return (event);
}
}


--
cburgess@qnx.com

Armin

Re: interrupt handling

Post by Armin » Fri Jul 27, 2007 8:31 am

dadji wrote:
Hello Kevin,
thank you for your contribution.
The tick mark are come from the CST-interrupts and other Asynchronous packet
interrupts.
That means the interrupt handled by your ISR is a shared one?

If yes, you shoudn't reset the interrupt logic of your board before you
check if the interrupt source is really your board.

Any interrupt from an other board will also start your ISR, which does
unconditionally reset the interrupt logic of your board.

That's the best way to loose interrupts ...

--Armin




The CST is a reliable source of interrupt as part of the
IEEE1394 standard.
Thanks.
Yannick.

"Kevin Stallard" <kevin@a.com> schrieb im Newsbeitrag
news:f88chf$1cu$1@inn.qnx.com...
I haven't used this tool for quite some time, so please forgive the naive
questions, but the tick marks under interrupt 0x5, if that is the actual
interrupt line, then the interrupt is indeed missing as it never occured.

Also something that is a bit suspect is the irregularity of the interrupt
(if the tick marks are the actual interrupt). Are you sure this device
is interrupting reliably on the 125usec interval as you say should be
happening?

Thanks
Kevin

"dadji" <ydadji@hotmail.com> wrote in message
news:f8817p$p8a$1@inn.qnx.com...
Hello,
i am writing and interrupt handler for for a IEEE1394 PCI card. i used
the function InterruptAttach to connect the handler to the Interrupt
line. As i notice that the handler didn't notice one particular
interrupt, i decided no to unmask the interrupt line. I also deceided to
use a ring buffer to store the contain of the interrupt register each
time it is read from the the HW within the Interrupt Service Routine
(ISR).
I'm working under QNX6.3.2 and i have made a trace of the system. In the
trace picture you will see the interrupt line (0x5) and the interrupt
handler. Special 1394 Interrupt called CST-interrupt occur every 125
microsec. In the trace picture one CST interrupt is missed. i don't know
waht could be the cause of this, since i don't mask the interrupt line.
i also sent the code of the Interrupt handler.
Can somebody give me some advice, how to get all interrupts processed by
the system!?
I thank you in advance.
Yannick D.






Post Reply

Return to “qnx.rtos”