Erlang/OTP Forums

Author Message

<  Advanced Erlang/OTP  ~  Async driver & code loading problem

i2c
Posted: Fri Dec 25, 2009 4:44 pm Reply with quote
Joined: 25 Dec 2009 Posts: 1
Hi, All !
I'm developing a server that receieves data from linux device via linked-in port driver and sends it over network. Port driver uses a poll() cycle.

The problem: when driver thread waits for poll() return, code:load_file() hangs up shell and implicit code loading stops any operation as well. If I have explicitly preloaded all needed modules before driver started, everything works fine.

I'm not an erlang expert but this does not look like normal behaviour.
Any ideas?

erlang:

Erlang R13B (erts-5.7.1) [source] [smp:1:1] [rq:1] [async-threads:128] [hipe] [kernel-poll:false]

driver:


Code:


typedef struct {
  ErlDrvPort port;
  brd_data_handle_t board;
  int polling;
  int poll_timeout;
} LidData;

static void ready_async(ErlDrvData data, ErlDrvThreadData td)
{

}

static void do_dev_poll(void* data)
{
  LidData *dd = (LidData*)data;
  DrvPollData poll_data;
  int retval;
  ErlDrvBinary *bin;
  uint bin_size = 0;
  const uint hdr_size = 1;
  char hdr[hdr_size+1];
  dbg("do_dev_poll called from thread %0X\r\n",
      pthread_self());
   
  while(dd->polling){
    dbg("polling %u", dd->polling);
    switch (dev_poll(dd->board, &poll_data, dd->poll_timeout)){
    case RET_TIMEOUT:
      dbg("poll timeout");
      hdr[0] = DRV_TIMEOUT;
      driver_output_binary(dd->port, hdr, hdr_size, NULL, 0, 0);
      break;
   
    case RET_OK:
      hdr[0] = DRV_DATA;
      bin_size = 4 + poll_data.size[0] + poll_data.size[1];
      bin = driver_alloc_binary(bin_size);
      *(uint32_t*)bin->orig_bytes = poll_data.code;
      //      dbg("%u %u %u; %p %p %p \n", bin_size, poll_data.size[0], poll_data.size[1], bin->orig_bytes, poll_data.buff[0], poll_data.buff[1]);
      memcpy(bin->orig_bytes + 4, poll_data.buff[0], poll_data.size[0]);
      memcpy(bin->orig_bytes + 4 + poll_data.size[0], poll_data.buff[1], poll_data.size[1]);
      dbg("data from board %s (%x)", dd->board->board_id, poll_data.code);
      driver_output_binary(dd->port, hdr, hdr_size, bin, 0, bin_size);
      if (bin_size)
        driver_free_binary(bin);
      break;
     
    case RET_ERROR:
      dbg("polling error");
      dd->polling = 0;
      hdr[0] = DRV_ERROR;
      driver_output_binary(dd->port, hdr, hdr_size, NULL, 0, 0);
      return;
     
    }
  }
}

static void do_free(void* data)
{
  LidData *dd = (LidData*)data;
  dd->polling = 0;
  dbg("do_free called from thread %0X\r\n",
pthread_self());

}

static ErlDrvData start(ErlDrvPort port, char *command)
{
  char
    board_id[20],

  LidData* dd = (LidData*) driver_alloc(sizeof(LidData));
 
/*
some hw init code here
*/
  dd->port = port;
  set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
  dd->polling = 0;
  dd->poll_timeout = DRV_DEFAULT_POLL_TIMEOUT;
 
  dbg("started %s", board_id);
  return (ErlDrvData) dd;
}

static void stop(ErlDrvData handle)
{
  LidData* dd = (LidData*) handle;
  dbg("stopping %s", dd->board->board_id);
  hw_data_free(dd->board);
  driver_free(dd);
}

 
static int control(ErlDrvData drv_data, unsigned int command, char *buf,
                   int len, char **rbuf, int rlen)
{

  LidData *dd = (LidData*)drv_data;
  switch (command){
  case DRV_CTL_START_POLL:
    dbg("ctl start poll");
    dd->polling = 1;
    dbg("control called from thread %0X\r\n",
pthread_self());
     
    driver_async(dd->port, &key, do_dev_poll, dd, do_free);
   
    break;

  case DRV_CTL_POLL_TIMEOUT:
    dd->poll_timeout = (uint32_t)*(uint32_t*)buf;
    dbg("poll_timeout set to %u\n", dd->poll_timeout);
    break;
  default:
    dbg("WTF?! unknown command");
  }
  dbg("ctl ok");
  return 0;
}

static ErlDrvEntry d_entry = {
    .init = NULL,                        /* init */
    .start = start,
    .stop = stop,
    .driver_name = "libhwintf_drv",     /* the name of the driver */
    .control = control,
    .ready_async = ready_async,
};

DRIVER_INIT(libhwintf_drv){
  return &d_entry;
}

View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum