No interrupts in mulithread device resource manager

I try made mulithread device resource manager with interrupt handler but
this handler is never executed. This same resource manager written as
single-thread device resource manager work fine and handler is executed.
What can be reason that external interrupt is not execute in multi
thread device resource manager. Other interrupt as timers work fine.

Thanks
Tom

tom <tomasz.walenczak@radmor.com.pl> wrote:

I try made mulithread device resource manager with interrupt handler but
this handler is never executed. This same resource manager written as
single-thread device resource manager work fine and handler is executed.
What can be reason that external interrupt is not execute in multi
thread device resource manager. Other interrupt as timers work fine.

In general, this should not matter from the OS/API. That you are
seeing this behaviour almost definitely is a bug in the initiation
of your driver, where going multi-threaded has changed the initiation
path and/or order of operations.

Without seeing/knowing your code, it is almost impossible to give you
a general purpose answer as to what you did wrong. But, one of the
places to start is, do you check the return value on your
InterruptAttach() calls? If they fail, what errno? And start working
from there.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

I try made mulithread device resource manager with interrupt handler but
this handler is never executed. This same resource manager written as
single-thread device resource manager work fine and handler is executed.
What can be reason that external interrupt is not execute in multi
thread device resource manager. Other interrupt as timers work fine.


In general, this should not matter from the OS/API. That you are
seeing this behaviour almost definitely is a bug in the initiation
of your driver, where going multi-threaded has changed the initiation
path and/or order of operations.

Without seeing/knowing your code, it is almost impossible to give you
a general purpose answer as to what you did wrong. But, one of the
places to start is, do you check the return value on your
InterruptAttach() calls? If they fail, what errno? And start working
from there.

InterruptAttach return positive value.
This is a part of this driver:
Compiled without define MULTI_THREAD working fine but compiletd with
this defien doesn’t work.


#define MULTI_THREAD

#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>

#define THREAD_POOL_PARAM_T dispatch_context_t

#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <string.h>
#include <hw/inout.h>
#include <sys/mman.h>
#include <devctl.h>
#include <fcntl.h>
#include <time.h>
#include <arm/pxa250.h>
#include <sys/neutrino.h>
#include <sched.h>

#define ADDR_DEFAULT 0x0C000400
#define IRQ_BASE 126
#define IRQ_DEFAULT 2
#define I2C_RESMGR_NAME “i2c”

volatile uint8_t *control_byte;
volatile uint8_t *data_byte_rx;
volatile uint8_t *data_byte_tx;
struct sigevent event;
char buffor_w[1000];

const struct sigevent * przerwanie (void *argc, int argv);
int odpowiedz (message_context_t *ctp,int code,unsigned flags,void
*handle);
int io_write(resmgr_context_t *ctp,io_write_t *msg,RESMGR_OCB_T *ocb);
void test (void);
static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

typedef struct{
unsigned int read_flag :1;
unsigned int req_end :1;
unsigned int enable_end :1;
unsigned int enable_byte :1;
unsigned int irq :2;
unsigned int reset :1;
unsigned int ext_irq :1;
}i2c_control;

union i2c_data_t{
uint8_t value;
i2c_control bits;
};
i2c_data_t i2c_data;
int saved_rcvid;

int main(int argc, char *argv[]) {
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
int id;
#ifndef MULTI_THREAD
dispatch_context_t *ctp;
#else
thread_pool_t *tpp;
thread_pool_attr_t pool_attr;
#endif
int intrpins[] = {73,72,71};

if((dpp=dispatch_create())==NULL){
fprintf(stderr,"%s: Unable to allocate dispatch
handle.\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
};
memset(&resmgr_attr,0,sizeof resmgr_attr);
resmgr_attr.nparts_max=1;
resmgr_attr.msg_max_size=2048;
iofunc_func_init(_RESMGR_CONNECT_NFUNCS,&connect_funcs,
_RESMGR_IO_NFUNCS,&io_funcs);
io_funcs.write=io_write;
iofunc_attr_init(&attr,S_IFNAM | 0666,0,0);

id=resmgr_attach(
dpp,
&resmgr_attr,
“/dev/i2c”,
_FTYPE_ANY,
_RESMGR_FLAG_DIR,
&connect_funcs,
&io_funcs,
&attr);
if(id==-1){
fprintf(stderr,"%s: Unable to attach system
name\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
ThreadCtl( _NTO_TCTL_IO, 0 );
if(InterruptAttach (intrpins[IRQ_DEFAULT]+IRQ_BASE, &przerwanie, 0,
0, _NTO_INTR_FLAGS_TRK_MSK)<0)
return EXIT_FAILURE;
control_byte =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+4);
data_byte_rx =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+0);
data_byte_tx =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+0);


if((event.sigev_coid=message_connect(dpp, MSG_FLAG_SIDE_CHANNEL)) == -1) {
fprintf(stderr, “%s: Unable to attach to channel.\n”,I2C_RESMGR_NAME);
return EXIT_FAILURE;
}

if((event.sigev_code=pulse_attach(dpp,MSG_FLAG_ALLOC_PULSE,0,&odpowiedz,NULL))==-1){
fprintf(stderr,"%s: Unable to attach pulse\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
event.sigev_notify=SIGEV_PULSE;
event.sigev_priority=-1;
#ifndef MULTI_THREAD
ctp=dispatch_context_alloc(dpp);
#else
memset(&pool_attr,0,sizeof pool_attr);
pool_attr.handle=dpp;
pool_attr.context_alloc=dispatch_context_alloc;
pool_attr.block_func=dispatch_block;
pool_attr.handler_func=dispatch_handler;
pool_attr.context_free=dispatch_context_free;
pool_attr.lo_water=2;
pool_attr.hi_water=4;
pool_attr.increment=1;
pool_attr.maximum=50;
if((tpp=thread_pool_create(&pool_attr,POOL_FLAG_EXIT_SELF))==NULL)
{
fprintf(stderr,“i2c: Unable to initialize thread pool.\n”);
return EXIT_FAILURE;
};
#endif
if(!fork()){
test();
}
#ifndef MULTI_THREAD
while(1){
if((ctp=dispatch_block(ctp))==NULL){
fprintf(stderr,"%s: Blocking error\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
#else
thread_pool_start(tpp);
#endif
}

const struct sigevent * przerwanie (void *argc, int argv)
{
return (&event);
}
int odpowiedz(message_context_t *ctp,int _code,unsigned flags,void *handle)
{
printf(“Answer\n”);
MsgReply(saved_rcvid,0,NULL,0);
return EOK;
}
int io_write(resmgr_context_t *ctp,io_write_t *msg,RESMGR_OCB_T *ocb)
{
int status;

if((status=iofunc_write_verify(ctp,msg,ocb,NULL))!=EOK)return(status);
if(msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE) return(ENOSYS);
_IO_SET_WRITE_NBYTES(ctp,msg->i.nbytes);


resmgr_msgread(ctp,buffor_w,msg->i.nbytes,sizeof(msg->i));//przepisanie
danych do bufora
if(msg->i.nbytes>0)
ocb->attr->flags |=IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;

i2c_data.bits.read_flag =0;
i2c_data.bits.enable_end =0;
i2c_data.bits.enable_byte =0;
i2c_data.bits.req_end =0;
i2c_data.bits.irq=IRQ_DEFAULT;
i2c_data.bits.reset =1;
i2c_data.bits.ext_irq =0;
*control_byte=i2c_data.value; //reset i2c
i2c_data.bits.reset =0;
i2c_data.bits.enable_byte =1;

*control_byte=i2c_data.value; //start i2c
saved_rcvid=ctp->rcvid;
printf(“Wait for interrupt\n”);
return (_RESMGR_NOREPLY);

}
void test (void)
{
int plik;
uint32_t buffor;
int p;

plik=open("/dev/i2c",O_RDWR|O_NONBLOCK);
buffor=0x01;
p=write(plik,&buffor,sizeof(buffor));
if(p<0)printf(“Error:%d\n”,errno);
close(plik);
}

Thanks
Tom

tom wrote:

I try made mulithread device resource manager with interrupt handler but

fork() doesn’t word in a multithreaded environment. Where is the
InterruptWait call ??

–Armin



this handler is never executed. This same resource manager written as
single-thread device resource manager work fine and handler is executed.
What can be reason that external interrupt is not execute in multi
thread device resource manager. Other interrupt as timers work fine.


In general, this should not matter from the OS/API. That you are
seeing this behaviour almost definitely is a bug in the initiation
of your driver, where going multi-threaded has changed the initiation
path and/or order of operations.

Without seeing/knowing your code, it is almost impossible to give you
a general purpose answer as to what you did wrong. But, one of the
places to start is, do you check the return value on your
InterruptAttach() calls? If they fail, what errno? And start working
from there.


InterruptAttach return positive value.
This is a part of this driver:
Compiled without define MULTI_THREAD working fine but compiletd with
this defien doesn’t work.


#define MULTI_THREAD

#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h

#define THREAD_POOL_PARAM_T dispatch_context_t

#include <sys/iofunc.h
#include <sys/dispatch.h
#include <string.h
#include <hw/inout.h
#include <sys/mman.h
#include <devctl.h
#include <fcntl.h
#include <time.h
#include <arm/pxa250.h
#include <sys/neutrino.h
#include <sched.h

#define ADDR_DEFAULT 0x0C000400
#define IRQ_BASE 126
#define IRQ_DEFAULT 2
#define I2C_RESMGR_NAME “i2c”

volatile uint8_t *control_byte;
volatile uint8_t *data_byte_rx;
volatile uint8_t *data_byte_tx;
struct sigevent event;
char buffor_w[1000];

const struct sigevent * przerwanie (void *argc, int argv);
int odpowiedz (message_context_t *ctp,int code,unsigned flags,void
*handle);
int io_write(resmgr_context_t *ctp,io_write_t *msg,RESMGR_OCB_T *ocb);
void test (void);
static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

typedef struct{
unsigned int read_flag :1;
unsigned int req_end :1;
unsigned int enable_end :1;
unsigned int enable_byte :1;
unsigned int irq :2;
unsigned int reset :1;
unsigned int ext_irq :1;
}i2c_control;

union i2c_data_t{
uint8_t value;
i2c_control bits;
};
i2c_data_t i2c_data;
int saved_rcvid;

int main(int argc, char *argv[]) {
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
int id;
#ifndef MULTI_THREAD
dispatch_context_t *ctp;
#else
thread_pool_t *tpp;
thread_pool_attr_t pool_attr;
#endif
int intrpins[] = {73,72,71};

if((dpp=dispatch_create())==NULL){
fprintf(stderr,"%s: Unable to allocate dispatch
handle.\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
};
memset(&resmgr_attr,0,sizeof resmgr_attr);
resmgr_attr.nparts_max=1;
resmgr_attr.msg_max_size=2048;
iofunc_func_init(_RESMGR_CONNECT_NFUNCS,&connect_funcs,
_RESMGR_IO_NFUNCS,&io_funcs);
io_funcs.write=io_write;
iofunc_attr_init(&attr,S_IFNAM | 0666,0,0);

id=resmgr_attach(
dpp,
&resmgr_attr,
“/dev/i2c”,
_FTYPE_ANY,
_RESMGR_FLAG_DIR,
&connect_funcs,
&io_funcs,
&attr);
if(id==-1){
fprintf(stderr,"%s: Unable to attach system
name\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
ThreadCtl( _NTO_TCTL_IO, 0 );
if(InterruptAttach (intrpins[IRQ_DEFAULT]+IRQ_BASE, &przerwanie, 0,
0, _NTO_INTR_FLAGS_TRK_MSK)<0)
return EXIT_FAILURE;
control_byte =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+4);
data_byte_rx =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+0);
data_byte_tx =(uint8_t *)mmap_device_memory(0,1,PROT_NOCACHE |
PROT_READ | PROT_WRITE, 0,ADDR_DEFAULT+0);


if((event.sigev_coid=message_connect(dpp, MSG_FLAG_SIDE_CHANNEL)) == -1) {
fprintf(stderr, “%s: Unable to attach to channel.\n”,I2C_RESMGR_NAME);
return EXIT_FAILURE;
}

if((event.sigev_code=pulse_attach(dpp,MSG_FLAG_ALLOC_PULSE,0,&odpowiedz,NULL))==-1){
fprintf(stderr,"%s: Unable to attach pulse\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
event.sigev_notify=SIGEV_PULSE;
event.sigev_priority=-1;
#ifndef MULTI_THREAD
ctp=dispatch_context_alloc(dpp);
#else
memset(&pool_attr,0,sizeof pool_attr);
pool_attr.handle=dpp;
pool_attr.context_alloc=dispatch_context_alloc;
pool_attr.block_func=dispatch_block;
pool_attr.handler_func=dispatch_handler;
pool_attr.context_free=dispatch_context_free;
pool_attr.lo_water=2;
pool_attr.hi_water=4;
pool_attr.increment=1;
pool_attr.maximum=50;
if((tpp=thread_pool_create(&pool_attr,POOL_FLAG_EXIT_SELF))==NULL)
{
fprintf(stderr,“i2c: Unable to initialize thread pool.\n”);
return EXIT_FAILURE;
};
#endif
if(!fork()){
test();
}
#ifndef MULTI_THREAD
while(1){
if((ctp=dispatch_block(ctp))==NULL){
fprintf(stderr,"%s: Blocking error\n",I2C_RESMGR_NAME);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
#else
thread_pool_start(tpp);
#endif
}

const struct sigevent * przerwanie (void *argc, int argv)
{
return (&event);
}
int odpowiedz(message_context_t *ctp,int _code,unsigned flags,void *handle)
{
printf(“Answer\n”);
MsgReply(saved_rcvid,0,NULL,0);
return EOK;
}
int io_write(resmgr_context_t *ctp,io_write_t *msg,RESMGR_OCB_T *ocb)
{
int status;

if((status=iofunc_write_verify(ctp,msg,ocb,NULL))!=EOK)return(status);
if(msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE) return(ENOSYS);
_IO_SET_WRITE_NBYTES(ctp,msg->i.nbytes);


resmgr_msgread(ctp,buffor_w,msg->i.nbytes,sizeof(msg->i));//przepisanie
danych do bufora
if(msg->i.nbytes>0)
ocb->attr->flags |=IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;

i2c_data.bits.read_flag =0;
i2c_data.bits.enable_end =0;
i2c_data.bits.enable_byte =0;
i2c_data.bits.req_end =0;
i2c_data.bits.irq=IRQ_DEFAULT;
i2c_data.bits.reset =1;
i2c_data.bits.ext_irq =0;
*control_byte=i2c_data.value; //reset i2c
i2c_data.bits.reset =0;
i2c_data.bits.enable_byte =1;

*control_byte=i2c_data.value; //start i2c
saved_rcvid=ctp->rcvid;
printf(“Wait for interrupt\n”);
return (_RESMGR_NOREPLY);

}
void test (void)
{
int plik;
uint32_t buffor;
int p;

plik=open("/dev/i2c",O_RDWR|O_NONBLOCK);
buffor=0x01;
p=write(plik,&buffor,sizeof(buffor));
if(p<0)printf(“Error:%d\n”,errno);
close(plik);
}

tom <tomasz.walenczak@radmor.com.pl> wrote:

if((tpp=thread_pool_create(&pool_attr,POOL_FLAG_EXIT_SELF))==NULL)

POOL_FLAG_EXIT_SELF might be the problem.

First thing I’d check – is anything important for your interrupt
handling on the stack of main()? Or on the stack of any other
function, because this tells the main thread to exit, which may
make its stack invalid.

I didn’t notice anything else obvious on a quick first glance,
if that isn’t it, I’ll take another look through.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Armin Steinhoff <a-steinhoff@web.de> wrote:

tom wrote:
I try made mulithread device resource manager with interrupt handler but


fork() doesn’t word in a multithreaded environment. Where is the
InterruptWait call ??

Actually, I’m pretty sure the fork() is fine, because it is before
the thread_pool_start(), therefor the application shouldn’t be
multi-threaded when he issues it.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Hey tom,

We are actually creating a single threaded resource manager and do not
know how to implement the io-methods. can you give me some information
about?

yours, muhkuh