Data Structures | |
struct | BUS_DRIVER |
struct | DD_MT_CHANNEL |
struct | DD_MT_BUFFER |
struct | EQUIPMENT_INFO |
struct | DEVICE_DRIVER |
struct | EQUIPMENT_STATS |
struct | eqpmnt |
Defines | |
#define | DF_INPUT (1<<0) |
#define | DF_OUTPUT (1<<1) |
#define | DF_PRIO_DEVICE (1<<2) |
#define | DF_READ_ONLY (1<<3) |
#define | DF_MULTITHREAD (1<<4) |
#define | DF_HW_RAMP (1<<5) |
Typedefs | |
typedef eqpmnt * | PEQUIPMENT |
typedef eqpmnt | EQUIPMENT |
Functions | |
INT | device_driver (DEVICE_DRIVER *device_driver, INT cmd,...) |
#define DF_MULTITHREAD (1<<4) |
#define DF_PRIO_DEVICE (1<<2) |
#define DF_READ_ONLY (1<<3) |
typedef struct eqpmnt* PEQUIPMENT |
INT device_driver | ( | DEVICE_DRIVER * | device_driver, | |
INT | cmd, | |||
... | ||||
) |
Definition at line 401 of file mfe.c.
00402 { 00403 va_list argptr; 00404 HNDLE hKey; 00405 INT channel, status, i, j; 00406 float value, *pvalue; 00407 char *name, *label, str[256]; 00408 00409 va_start(argptr, cmd); 00410 status = FE_SUCCESS; 00411 00412 switch (cmd) { 00413 case CMD_INIT: 00414 hKey = va_arg(argptr, HNDLE); 00415 00416 if (device_drv->flags & DF_MULTITHREAD) { 00417 status = device_drv->dd(CMD_INIT, hKey, &device_drv->dd_info, 00418 device_drv->channels, device_drv->flags, 00419 device_drv->bd); 00420 00421 if (status == FE_SUCCESS && (device_drv->flags & DF_MULTITHREAD)) { 00422 /* create inter-thread data exchange buffers */ 00423 device_drv->mt_buffer = (DD_MT_BUFFER *) calloc(1, sizeof(DD_MT_BUFFER)); 00424 device_drv->mt_buffer->n_channels = device_drv->channels; 00425 device_drv->mt_buffer->channel = (DD_MT_CHANNEL *) calloc(device_drv->channels, sizeof(DD_MT_CHANNEL)); 00426 assert(device_drv->mt_buffer->channel); 00427 00428 /* set all set values to NaN */ 00429 for (i=0 ; i<device_drv->channels ; i++) 00430 for (j=CMD_SET_FIRST ; j<=CMD_SET_LAST ; j++) 00431 device_drv->mt_buffer->channel[i].variable[j] = (float)ss_nan(); 00432 00433 /* get default names for this driver already now */ 00434 for (i = 0; i < device_drv->channels; i++) 00435 device_drv->dd(CMD_GET_LABEL, device_drv->dd_info, i, 00436 device_drv->mt_buffer->channel[i].label); 00437 00438 /* create semaphore */ 00439 sprintf(str, "DD_%s", device_drv->name); 00440 status = ss_semaphore_create(str, &device_drv->semaphore); 00441 if (status != SS_CREATED && status != SS_SUCCESS) 00442 return FE_ERR_DRIVER; 00443 status = FE_SUCCESS; 00444 } 00445 } else { 00446 status = device_drv->dd(CMD_INIT, hKey, &device_drv->dd_info, 00447 device_drv->channels, device_drv->flags, 00448 device_drv->bd); 00449 } 00450 break; 00451 00452 case CMD_START: 00453 if (device_drv->flags & DF_MULTITHREAD && device_drv->mt_buffer != NULL) { 00454 /* create dedicated thread for this device */ 00455 device_drv->mt_buffer->thread_id = ss_thread_create(sc_thread, device_drv); 00456 } 00457 break; 00458 00459 case CMD_STOP: 00460 if (device_drv->flags & DF_MULTITHREAD && device_drv->mt_buffer != NULL) { 00461 device_drv->stop_thread = 1; 00462 /* wait for max. 10 seconds until thread has gracefully stopped */ 00463 for (i = 0; i < 1000; i++) { 00464 if (device_drv->stop_thread == 2) 00465 break; 00466 ss_sleep(10); 00467 } 00468 00469 /* if timeout expired, kill thread */ 00470 if (i == 1000) 00471 ss_thread_kill(device_drv->mt_buffer->thread_id); 00472 00473 ss_semaphore_delete(device_drv->semaphore, TRUE); 00474 free(device_drv->mt_buffer->channel); 00475 free(device_drv->mt_buffer); 00476 } 00477 break; 00478 00479 case CMD_EXIT: 00480 status = device_drv->dd(CMD_EXIT, device_drv->dd_info); 00481 break; 00482 00483 case CMD_SET_LABEL: 00484 channel = va_arg(argptr, INT); 00485 label = va_arg(argptr, char *); 00486 status = device_drv->dd(CMD_SET_LABEL, device_drv->dd_info, channel, label); 00487 break; 00488 00489 case CMD_GET_LABEL: 00490 channel = va_arg(argptr, INT); 00491 name = va_arg(argptr, char *); 00492 status = device_drv->dd(CMD_GET_LABEL, device_drv->dd_info, channel, name); 00493 break; 00494 00495 default: 00496 00497 if (cmd >= CMD_SET_FIRST && cmd <= CMD_SET_LAST) { 00498 00499 /* transfer data to sc_thread for SET commands */ 00500 channel = va_arg(argptr, INT); 00501 value = (float) va_arg(argptr, double); // floats are passed as double 00502 if (device_drv->flags & DF_MULTITHREAD) { 00503 ss_semaphore_wait_for(device_drv->semaphore, 1000); 00504 device_drv->mt_buffer->channel[channel].variable[cmd] = value; 00505 status = device_drv->mt_buffer->status; 00506 ss_semaphore_release(device_drv->semaphore); 00507 } else { 00508 status = device_drv->dd(cmd, device_drv->dd_info, channel, value); 00509 } 00510 00511 } else if (cmd >= CMD_GET_FIRST && cmd <= CMD_GET_LAST) { 00512 00513 /* transfer data from sc_thread for GET commands */ 00514 channel = va_arg(argptr, INT); 00515 pvalue = va_arg(argptr, float *); 00516 if (device_drv->flags & DF_MULTITHREAD) { 00517 ss_semaphore_wait_for(device_drv->semaphore, 1000); 00518 *pvalue = device_drv->mt_buffer->channel[channel].variable[cmd]; 00519 status = device_drv->mt_buffer->status; 00520 ss_semaphore_release(device_drv->semaphore); 00521 } else 00522 status = device_drv->dd(cmd, device_drv->dd_info, channel, pvalue); 00523 00524 } else { 00525 00526 /* all remaining commands which are passed directly to the device driver */ 00527 channel = va_arg(argptr, INT); 00528 pvalue = va_arg(argptr, float *); 00529 status = device_drv->dd(cmd, device_drv->dd_info, channel, pvalue); 00530 } 00531 00532 break; 00533 } 00534 00535 va_end(argptr); 00536 return status; 00537 }