示例#1
0
/*
 * The thread start routine for pipe stage threads.
 * Each will wait for a data item passed from the caller or the previous stage,
 * modify the data and pass it along to the next (or final) stage.
 */
void *pipe_stage(void *arg)
{
    stage_t *stage = (stage_t *)arg;
    stage_t *next_stage = stage->next;
    int status;

    status = pthread_mutex_lock(&stage->mutex);
    status_check(status, "Lock pipe stage");
    
    while (1) {
        while (!stage->data_ready) {
            status = pthread_cond_wait(&stage->avail, &stage->mutex);
            status_check(status, "Wait for previous stage");
        }
        pipe_send(next_stage, stage->data + 1);
        stage->data_ready = false;
        status = pthread_cond_signal(&stage->ready);
        status_check(status, "Wake next stage");
    }
    
    /*
     * Notice that the routine never unlocks the stage->mutex.
     * The call to pthread_cond_wait implicitly unlocks the mutex
     * while the thread is waiting, allowing other threads to make progress.
     * Because the loop never terminates, this function has no need to unlock
     * the mutex explicitly.
     */
    
    return NULL;
}
示例#2
0
/*
 * Collect the result of the pipeline. Wait for a result if the pipeline
 * hasn't produced one.
 * return true when get result, false when does not get a result.
 */
bool pipe_result(pipe_t *pipe, long *result)
{
    stage_t *tail = pipe->tail;
    bool empyt = false;
    int status;
    
    status = pthread_mutex_lock(&pipe->mutex);
    status_check(status, "Lock pipe mutex");
    if (pipe->active <= 0) {
        empyt = true;
    } else {
        pipe->active--;
    }
    
    status = pthread_mutex_unlock(&pipe->mutex);
    status_check(status, "Unlock pipe mutex");
    if (empyt) {
        return false;
    }
    
    status = pthread_mutex_lock(&tail->mutex);
    status_check(status, "Lock tail mutex");
    while (!tail->data_ready) {
        pthread_cond_wait(&tail->avail, &tail->mutex);
    }
    *result = tail->data;
    tail->data_ready = false;
    status = pthread_cond_signal(&tail->ready);
    status_check(status, "Signal tail ready");
    status = pthread_mutex_unlock(&tail->mutex);
    status_check(status, "Unlock tail mutex");
    return true;
}
示例#3
0
void SensorResource::activeCheck()
{
	bool sensor_changed = false;

	sensor_changed = status_check(m_gas) || status_check(m_fan)
			|| status_check(m_led) || status_check(m_pri);

	if (sensor_changed) {
		ChangeSensorRepresentation();
	}
}
示例#4
0
文件: cpu.c 项目: avaudagna/elestac
void finished_quantum_post_process() {
    printf(ANSI_COLOR_RED);
    log_info(cpu_log, "=== Finished Quantum ===");
    printf(ANSI_COLOR_RESET);
    if(status_check() == EXECUTING) {
        status_update(READY);
    }
    if(status_check() == BLOCKED || status_check() == WAITING) {
        return;
    }
    send_quantum_end_notif();
}
示例#5
0
文件: cpu.c 项目: avaudagna/elestac
int post_process_operations() {
    actual_kernel_data->Q--;
    actual_pcb->program_counter++;
    if(status_check() != WAITING && status_check() != BROKEN) {
        printf(ANSI_COLOR_BLUE);
        log_info(cpu_log, "Remaining Quantum : %d", actual_kernel_data->Q);
        printf(ANSI_COLOR_RESET);
        printf(ANSI_COLOR_YELLOW);
        log_info(cpu_log, "Next execution line :%d", actual_pcb->program_counter);
        printf(ANSI_COLOR_RESET);
    }
    return SUCCESS;
}
示例#6
0
/*
 * External function to create a pipeline. All the data is initialized
 * and the threads created. They'll wait for data.
 */
int pipe_create(pipe_t *pipe, int stages)
{
    int pipe_index;
    stage_t **link = &pipe->head, *new_stage = NULL, *stage;
    int status;
    
    status = pthread_mutex_init(&pipe->mutex, NULL);
    status_check(status, "Init pipe mutex");
    pipe->stages = stages;
    pipe->active = 0;
    
    /*
     * Create (stages + 1) stage, final stage is for stash result
     */
    for (pipe_index = 0; pipe_index <= stages; pipe_index++) {
        new_stage = (stage_t *)malloc(sizeof(stage_t));
        condition_check(new_stage != NULL, "Allocate stage");
        status = pthread_mutex_init(&new_stage->mutex, NULL);
        status_check(status, "Init stage mutex");
        status = pthread_cond_init(&new_stage->avail, NULL);
        status_check(status, "Init avail condition");
        status = pthread_cond_init(&new_stage->ready, NULL);
        status_check(status, "Init ready condition");
        new_stage->data_ready = false;
        *link = new_stage;
        link = &new_stage->next;
    }
    
    *link = (stage_t *)NULL;        /* Terminate list */
    pipe->tail = new_stage;         /* Record the tail */
    
    
    /*
     * Create the threads for the pipe stage only after all the data is 
     * initialized (including all links). Note that the last stage doesn't get
     * thread, it's just a receptacle for the final pipeline value.
     *
     * At this point, proper cleanup on an error would take up more space
     * than worthwhile in a "simple example", so instead of cancelling and
     * detaching all the threads already created, plus the synchronization 
     * object and memory cleanup done for earlier errors, it will simply abort.
     */
    for (stage = pipe->head; stage->next != NULL; stage = stage->next) {
        status = pthread_create(&stage->thread, NULL, pipe_stage, (void *)stage);
        status_check(status, "Create pipe stage");
    }
    
    return 0;
}
t_valor_variable obtenerValorCompartida(t_nombre_compartida variable){
    if(status_check() != EXECUTING)
        return ERROR;

    //5 + 0 + nameSize + name (1+1+4+nameSize bytes)
    void* buffer = NULL;
    int value = 0, variable_name_length = (int) strlen(variable), buffer_index = 0;
    char operation = SHARED_VAR_ID, action = GET_VAR;

//    asprintf(&buffer, "%d%d%04d%s", atoi(SHARED_VAR_ID), atoi(GET_VAR), strlen(variable), variable);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&action, sizeof(char), &buffer, &buffer_index);
    serialize_data(&variable_name_length, sizeof(int), &buffer, &buffer_index);
    serialize_data(variable, (size_t) variable_name_length, &buffer, &buffer_index);

    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "send of obtener variable compartida of %s failed", variable);
        free(buffer);
        return ERROR;
    }
    free(buffer);
    buffer = calloc(1, sizeof(int));
    if(recv(kernelSocketClient, buffer, sizeof(int),  0) <= 0) {
        log_error(cpu_log, "recv of obtener variable compartida failed");
        return ERROR;
    }
    int deserialize_index = 0;
    deserialize_data(&value, sizeof(int), buffer, &deserialize_index);
    log_info(cpu_log, "recv value %d of obtener variable %s", value, variable);
    free(buffer);
    return value;

}
示例#8
0
static void
impl_setLineStatus(PortableServer_Servant servant, GNOME_Evolution_ShellState shell_state, GNOME_Evolution_Listener listener, CORBA_Environment *ev)
{
	struct _setline_data *sd;
	int status = status_check(shell_state);

	/* This will dis/enable further auto-mail-check action. */
	/* FIXME: If send/receive active, wait for it to finish? */
	if (status)
		camel_session_set_online(session, status);

	sd = g_malloc0(sizeof(*sd));
	sd->status = status;
	sd->listener = CORBA_Object_duplicate(listener, ev);
	if (ev->_major == CORBA_NO_EXCEPTION)
		mail_component_stores_foreach(mail_component_peek(), setline_check, sd);
	else
		CORBA_exception_free(ev);

	if (sd->pending == 0) {
		if (sd->listener) {
			CORBA_Object_release(sd->listener, ev);
			CORBA_exception_free(ev);
		}

		g_free(sd);

		if (!status)
			camel_session_set_online(session, status);
		GNOME_Evolution_Listener_complete(listener, ev);
	}
}
void la_wait (t_nombre_semaforo identificador_semaforo){
    if(status_check() != EXECUTING)
        return;

    void * buffer = NULL, *response_buffer = calloc(1,sizeof(char));
    int buffer_index = 0, identificador_semaforo_length = (int) strlen(identificador_semaforo);
    char operation = SEMAPHORE_ID, action = WAIT_ID;
//    asprintf(&buffer, "%d%d%04d%s", atoi(SEMAPHORE_ID), atoi(WAIT_ID), strlen(identificador_semaforo), identificador_semaforo);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&action, sizeof(char), &buffer, &buffer_index);
    serialize_data(&identificador_semaforo_length, sizeof(int), &buffer, &buffer_index);
    serialize_data(identificador_semaforo, (size_t) identificador_semaforo_length, &buffer, &buffer_index);

    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "wait(%s) failed", identificador_semaforo);
        return;
    }
    status_update(WAITING);
    log_info(cpu_log, "Starting wait");
    //me quedo esperando activamente a que kernel me responda
//    recv(kernelSocketClient, response_buffer, sizeof(char), 0);
    //kernel_response debería ser '0'
//    log_info(cpu_log, "Finished wait");
    free(buffer);
    free(response_buffer);
}
示例#10
0
/*
 * External interface to start a pipeline by passing data to the first stage.
 * The routine returns while the pipeline processes in parallel. Call the
 * pipe_result return to collect the final stage values (note that the pipeline
 * will stall when each stage fills, until the result is collected).
 */
int pipe_start(pipe_t *pipe, long value)
{
    int status;
    
    status = pthread_mutex_lock(&pipe->mutex);
    status_check(status, "Lock pipe mutex");
    if (pipe->active >= pipe->stages) {
        fprintf(stdout, "Pipeline is fully, please try later.\n");
        status = pthread_mutex_unlock(&pipe->mutex);
        status_check(status, "Unlock pipe mutex");
        return 1;
    }
    pipe->active++;
    status = pthread_mutex_unlock(&pipe->mutex);
    status_check(status, "Unlock pipe mutex");
    pipe_send(pipe->head, value);
    
    return 0;
}
示例#11
0
void llamarSinRetorno (t_nombre_etiqueta etiqueta){
    if(status_check() != EXECUTING)
        return;

    t_ret_var * ret_var_addr = calloc(1, sizeof(t_ret_var));
    t_stack * stack_index = actual_pcb->stack_index;
    //1) Creo la nueva entrada del stack
    t_stack_entry* new_stack_entry = create_new_stack_entry();
    //2) Guardo la posicion de PC actual como retpos de la nueva entrada
    new_stack_entry->ret_pos = actual_pcb->program_counter;
    //3) Agrego la strack entry a la queue de stack
    queue_push(actual_pcb->stack_index, new_stack_entry);
    //4) Asigno el PC a la etiqueta objetivo
    irAlLabel(etiqueta);
}
示例#12
0
void retornar(t_valor_variable retorno) {
    if(status_check() != EXECUTING)
        return;

    //1) Obtengo el stack index
    t_stack * actual_stack_index = actual_pcb->stack_index;
    //2) Obtengo la entrada actual
    t_stack_entry *last_entry = get_last_entry(actual_stack_index);
    //3) Actualizo el PC a la posicion de retorno de la entrada actual
    actual_pcb->program_counter = last_entry->ret_pos;
    //4) Asigno el valor de retorno de la entrada actual a la variable de retorno
    asignar(obtener_t_posicion(last_entry->ret_vars), retorno);
    //5) Libero la ultima entrada del indice de stack
    free(pop_stack(actual_stack_index));
}
示例#13
0
文件: cpu.c 项目: avaudagna/elestac
int check_execution_state() {
    switch(status_check()) {
        case EXIT:
        case BROKEN:
        case ABORTED:
            program_end_notification();
            return EXIT;
        case BLOCKED:
        case WAITING:
            return EXIT;
        default:
            break;
    }
    return SUCCESS;
}
示例#14
0
static status_check
parse_status_check_arg(const std::string& arg)
{
    const std::string::size_type delimiter = arg.find(':');
    bool negated = (arg.compare(0, 4, "not-") == 0);
    const std::string action_str = arg.substr(0, delimiter);
    const std::string action = negated ? action_str.substr(4) : action_str;
    const std::string value_str = (
        delimiter == std::string::npos ? "" : arg.substr(delimiter + 1));
    int value;

    status_check_t type;
    if (action == "eq") {
        // Deprecated; use exit instead.  TODO: Remove after 0.10.
        type = sc_exit;
        if (negated)
            throw atf::application::usage_error("Cannot negate eq checker");
        negated = false;
        value = parse_exit_code(value_str);
    } else if (action == "exit") {
        type = sc_exit;
        if (value_str.empty())
            value = INT_MIN;
        else
            value = parse_exit_code(value_str);
    } else if (action == "ignore") {
        if (negated)
            throw atf::application::usage_error("Cannot negate ignore checker");
        type = sc_ignore;
        value = INT_MIN;
    } else if (action == "ne") {
        // Deprecated; use not-exit instead.  TODO: Remove after 0.10.
        type = sc_exit;
        if (negated)
            throw atf::application::usage_error("Cannot negate ne checker");
        negated = true;
        value = parse_exit_code(value_str);
    } else if (action == "signal") {
        type = sc_signal;
        if (value_str.empty())
            value = INT_MIN;
        else
            value = parse_signal(value_str);
    } else
        throw atf::application::usage_error("Invalid output checker");

    return status_check(type, negated, value);
}
示例#15
0
void imprimir(t_valor_variable valor) {
    if(status_check() != EXECUTING)
        return;

    void * buffer = NULL;
    int buffer_index = 0;
    char operation = IMPRIMIR_ID;
//    asprintf(&buffer, "%d%04d", atoi(IMPRIMIR_ID), valor);
    serialize_data(&operation , sizeof(char), &buffer, &buffer_index);
    serialize_data(&valor, sizeof(int), &buffer, &buffer_index);
    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "imprimir value %d send to KERNEL failed", valor);
        return ;
    }
    log_info(cpu_log, "imprimir value %d sent to KERNEL");
    free(buffer);
}
示例#16
0
t_valor_variable dereferenciar(t_posicion direccion_variable) {
    if(status_check() != EXECUTING)
        return ERROR;

    //Hacemos el request a la UMC con el codigo 2
    t_list *pedidos = NULL;
    construir_operaciones_lectura(&pedidos, direccion_variable);

    void * variable_buffer = calloc(1, ANSISOP_VAR_SIZE), *umc_request_buffer = NULL;
    int variable_buffer_index = 0;
    char response_status;
    logical_addr * current_address = NULL;
    while(list_size(pedidos) > 0) {
        current_address  = list_remove(pedidos, 0);
//      asprintf(&umc_request_buffer, "3%04d%04d%04d", current_address->page_number,
//                 current_address->offset, current_address->tamanio);
        int umc_request_buffer_index = 0;
        char operation = PEDIDO_BYTES;
        serialize_data(&operation, sizeof(char), &umc_request_buffer, &umc_request_buffer_index);
        serialize_data(&current_address->page_number, sizeof(int), &umc_request_buffer, &umc_request_buffer_index);
        serialize_data(&current_address->offset, sizeof(int), &umc_request_buffer, &umc_request_buffer_index);
        serialize_data(&current_address->tamanio, sizeof(int), &umc_request_buffer, &umc_request_buffer_index);
        log_info(cpu_log, "sending request : op:%c (%d,%d,%d) for direccion variable %d",operation, current_address->page_number,
                 current_address->offset, current_address->tamanio, direccion_variable);
//        log_info(cpu_log, "sending request : %s for direccion variable %d", &umc_request_buffer, direccion_variable);
        if( send(umcSocketClient, umc_request_buffer, (size_t) umc_request_buffer_index, 0) < 0) {
            log_error(cpu_log, "UMC expected addr send failed");
            return ERROR;
        }

        if(check_umc_response(recv_umc_response_status()) != SUCCESS) {
            return ERROR;
        }

        if( recv(umcSocketClient , ((char*) variable_buffer) + variable_buffer_index , (size_t) current_address->tamanio, 0) <= 0) {
            log_error(cpu_log, "UMC response recv failed");
            break;
        }
        variable_buffer_index += current_address->tamanio;
    }

	free(umc_request_buffer);
    log_info(cpu_log, "Valor variable obtained : %d", *(int*)variable_buffer);
    return (t_valor_variable) *(t_valor_variable*)variable_buffer;
}
示例#17
0
void asignar(t_posicion direccion_variable, t_valor_variable valor) {
    if(status_check() != EXECUTING)
        return;

    t_list * pedidos = NULL;
    obtener_lista_operaciones_escritura(&pedidos, direccion_variable, ANSISOP_VAR_SIZE, valor);

    char * umc_response_buffer = calloc(1, sizeof(char));
    if(umc_response_buffer == NULL) {
        log_error(cpu_log, "asignar umc_response_buffer mem alloc failed");
        return;
    }

    int index = 0;
    t_nodo_send * nodo = NULL;
    int page, offset, size, print_index = 0;
    char operation;
    while (list_size(pedidos) > 0) {
        nodo = list_remove(pedidos, index);
        if(nodo != NULL) {
            deserialize_data(&operation, sizeof(char), nodo->data, &print_index);
            deserialize_data(&page, sizeof(int), nodo->data, &print_index);
            deserialize_data(&offset, sizeof(int), nodo->data, &print_index);
            deserialize_data(&size, sizeof(int), nodo->data, &print_index);
            log_info(cpu_log, "Sending request op:%c (%d,%d,%d) for direccion variable %d with value %d", operation, page, offset, size, direccion_variable, valor);
//            log_info(cpu_log, "sending request : %s for direccion variable %d with value %d",  nodo->data , direccion_variable, valor);
            if( send(umcSocketClient, nodo->data , (size_t ) nodo->data_length, 0) < 0) {
                log_error(cpu_log, "UMC expected addr send failed");
                break;
            }

            //EXITO (Se podria loggear de que la operacion fue exitosa)
            if(check_umc_response(recv_umc_response_status()) == SUCCESS){
                log_info(cpu_log, "Asignar variable operation to UMC with value %d was successful", valor);
            } else {
                log_error(cpu_log, "Asignar variable operation to UMC with value %d failed", valor);
                break;
            }
            free(nodo);
        }
    }
    list_destroy(pedidos); //Liberamos la estructura de lista reservada
	free(umc_response_buffer);
	log_info(cpu_log, "Finished asignar variable operations");
}
示例#18
0
void la_signal (t_nombre_semaforo identificador_semaforo){
    if(status_check() != EXECUTING)
        return;

    void * buffer = NULL;
    int buffer_index = 0, identificador_semaforo_length = (int) strlen(identificador_semaforo);
    char operation = SEMAPHORE_ID, action = SIGNAL_ID;
//    asprintf(&buffer, "%d%d%04d%s", atoi(SEMAPHORE_ID), atoi(SIGNAL_ID), strlen(identificador_semaforo), identificador_semaforo);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&action, sizeof(char), &buffer, &buffer_index);
    serialize_data(&identificador_semaforo_length, sizeof(int), &buffer, &buffer_index);
    serialize_data(identificador_semaforo, identificador_semaforo_length, &buffer, &buffer_index);

    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "signal(%s) failed", identificador_semaforo);
        return;
    }
}
示例#19
0
void imprimirTexto(char* texto) {
    if(status_check() != EXECUTING)
        return;

    void * buffer = NULL;
    int texto_len = (int) strlen(texto), buffer_index = 0;
    char operation = IMPRIMIR_TEXTO_ID;
//    asprintf(&buffer, "%d%04d%s", atoi(IMPRIMIR_TEXTO_ID), texto_len, texto);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&texto_len, sizeof(int), &buffer, &buffer_index);
    serialize_data(texto, (size_t) texto_len, &buffer, &buffer_index);

    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "imprimirTexto with texto : %s , send failed", texto);
        return;
    }
    log_info(cpu_log, "imprimirTexto with texto : %s , sent to KERNEL", texto);
    free(buffer);
}
示例#20
0
t_posicion obtenerPosicionVariable(t_nombre_variable variable) {
    if(status_check() != EXECUTING)
        return ERROR;

    logical_addr * direccion_logica = NULL;
	int i = 0;
    //1) Obtener el stack index actual
    t_stack_entry* current_stack_index = get_last_entry(actual_pcb->stack_index);
    //2) Obtener puntero a las variables
    t_var* indice_variable = current_stack_index->vars;

    for (i = 0; i < current_stack_index->cant_vars ; i++) {
        if( (indice_variable + i)->var_id == variable ) {
            return get_t_posicion(indice_variable + i); // (t_posicion) (indice_variable->page_number * setup->PAGE_SIZE) + indice_variable->offset;
        }
    }

    return ERROR;
}
示例#21
0
void llamarConRetorno(t_nombre_etiqueta etiqueta, t_puntero donde_retornar) {
    if(status_check() != EXECUTING)
        return;

    t_ret_var * ret_var_addr = calloc(1, sizeof(t_ret_var));
    //1) Obtengo la direccion a donde apunta la variable de retorno
    ret_var_addr = armar_direccion_logica_variable(donde_retornar, setup->PAGE_SIZE);
    t_stack_entry * actual_stack_entry = get_last_entry(actual_pcb->stack_index);
    //2) Creo la nueva entrada del stack
    t_stack_entry* new_stack_entry = create_new_stack_entry();
    //3) Guardo la posicion de PC actual como retpos de la nueva entrada
    new_stack_entry->pos = actual_stack_entry->pos + 1;
    new_stack_entry->ret_pos = actual_pcb->program_counter;
    //4) Agrego la retvar a la entrada
    add_ret_var(&new_stack_entry, ret_var_addr);
    //5) Agrego la strack entry a la queue de stack
    queue_push(actual_pcb->stack_index, new_stack_entry);
//    (t_stack_entry*) list_get(actual_pcb->stack_index->elements, 1)
    //6) Asigno el PC a la etiqueta objetivo
    irAlLabel(etiqueta);
}
示例#22
0
t_valor_variable asignarValorCompartida(t_nombre_compartida variable, t_valor_variable valor){
    if(status_check() != EXECUTING)
        return ERROR;

    //5 + 1 + nameSize + name + value (1+1+4+nameSize+4 bytes)
    void* buffer = NULL;
    int buffer_index = 0, variable_length = (int) strlen(variable);
    char operation = SHARED_VAR_ID, action = SET_VAR;
//    asprintf(&buffer, "%d%d%04d%s%04d", atoi(SHARED_VAR_ID), atoi(SET_VAR), strlen(variable), variable, valor);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&action, sizeof(char), &buffer, &buffer_index);
    serialize_data(&variable_length, sizeof(int), &buffer, &buffer_index);
    serialize_data(variable, (size_t) variable_length, &buffer, &buffer_index);
    serialize_data(&valor, sizeof(int), &buffer, &buffer_index);

    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "set value of %s failed", variable);
        return ERROR;
    }
    log_info(cpu_log, "asignarValorCompartida of %s with value %d was successful", variable, valor);
    free(buffer);
    return valor;
}
示例#23
0
void entradaSalida(t_nombre_dispositivo dispositivo, int tiempo) {
    if(status_check() != EXECUTING)
        return;

    //cambio el estado del pcb
    status_update(BLOCKED);
    //3+ ioNameSize + ioName + io_units (1+4+ioNameSize+4 bytes)
    void * buffer = NULL;
    char operation = ENTRADA_SALIDA_ID;
    int dispositivo_length = (int) strlen(dispositivo), buffer_index = 0;
    //Armo paquete de I/O operation
//    asprintf(&buffer, "%d%04d%s%04d", atoi(ENTRADA_SALIDA_ID), strlen(dispositivo), dispositivo, tiempo);
    serialize_data(&operation, sizeof(char), &buffer, &buffer_index);
    serialize_data(&dispositivo_length, sizeof(int), &buffer, &buffer_index);
    serialize_data(dispositivo, (size_t) dispositivo_length, &buffer, &buffer_index);
    serialize_data(&tiempo, sizeof(int), &buffer, &buffer_index);

    //Envio el paquete a KERNEL
    if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) {
        log_error(cpu_log, "entrada salida of dispositivo %s %d time send to KERNEL failed", dispositivo, tiempo);
    }
    free(buffer);
}
示例#24
0
文件: piotest.c 项目: OXKernel/ox
int
main()
{
    unsigned char status_reg = 0, error_reg = 1;
    char ptr[512]={0};
    printf("%x\n",get_drive_head(0,0));
    printf("%x\n",test(0xAB));
    printf("%x\n",test1(0xBA));
    printf("%x\n",test2(0xCA));
    printf("ptr=%x %x\n",ptr,pio_read(0xA,0xB,0xC,0xD,ptr));
    printf("%x\n",0xC+0x4);
    printf("%x\n",0x10+0x4);
    status_reg = 1;
    // status_reg |= (1<<7); // Set BSY
    if(status_check(0, error_reg, status_reg) == 0) {
        printf("status_check:: no error\n");
    }
    if(bit_test(status_reg)==1) {
        printf("bit_test:: error\n");
    } else {
        printf("bit_test:: no error\n"); 
    }
    return 0;
}
示例#25
0
文件: monitor.c 项目: lwhibernate/xen
int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
{
    int rc;
    struct arch_domain *ad = &d->arch;
    uint32_t capabilities = get_capabilities(d);

    rc = xsm_vm_event_control(XSM_PRIV, d, mop->op, mop->event);
    if ( rc )
        return rc;

    switch ( mop->op )
    {
    case XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES:
        mop->event = capabilities;
        return 0;

    case XEN_DOMCTL_MONITOR_OP_EMULATE_EACH_REP:
        d->arch.mem_access_emulate_each_rep = !!mop->event;
        return 0;
    }

    /*
     * Sanity check
     */
    if ( mop->op != XEN_DOMCTL_MONITOR_OP_ENABLE &&
         mop->op != XEN_DOMCTL_MONITOR_OP_DISABLE )
        return -EOPNOTSUPP;

    /* Check if event type is available. */
    if ( !(capabilities & (1 << mop->event)) )
        return -EOPNOTSUPP;

    switch ( mop->event )
    {
    case XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG:
    {
        unsigned int ctrlreg_bitmask =
            monitor_ctrlreg_bitmask(mop->u.mov_to_cr.index);
        bool_t status =
            !!(ad->monitor.write_ctrlreg_enabled & ctrlreg_bitmask);
        struct vcpu *v;

        rc = status_check(mop, status);
        if ( rc )
            return rc;

        if ( mop->u.mov_to_cr.sync )
            ad->monitor.write_ctrlreg_sync |= ctrlreg_bitmask;
        else
            ad->monitor.write_ctrlreg_sync &= ~ctrlreg_bitmask;

        if ( mop->u.mov_to_cr.onchangeonly )
            ad->monitor.write_ctrlreg_onchangeonly |= ctrlreg_bitmask;
        else
            ad->monitor.write_ctrlreg_onchangeonly &= ~ctrlreg_bitmask;

        domain_pause(d);

        if ( !status )
            ad->monitor.write_ctrlreg_enabled |= ctrlreg_bitmask;
        else
            ad->monitor.write_ctrlreg_enabled &= ~ctrlreg_bitmask;

        domain_unpause(d);

        if ( mop->u.mov_to_cr.index == VM_EVENT_X86_CR3 )
            /* Latches new CR3 mask through CR0 code */
            for_each_vcpu ( d, v )
                hvm_update_guest_cr(v, 0);

        break;
    }

    case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR:
    {
        bool_t status = ad->monitor.mov_to_msr_enabled;

        rc = status_check(mop, status);
        if ( rc )
            return rc;

        if ( mop->op == XEN_DOMCTL_MONITOR_OP_ENABLE &&
             mop->u.mov_to_msr.extended_capture )
        {
            if ( hvm_enable_msr_exit_interception(d) )
                ad->monitor.mov_to_msr_extended = 1;
            else
                return -EOPNOTSUPP;
        } else
            ad->monitor.mov_to_msr_extended = 0;

        domain_pause(d);
        ad->monitor.mov_to_msr_enabled = !status;
        domain_unpause(d);
        break;
    }

    case XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP:
    {
        bool_t status = ad->monitor.singlestep_enabled;

        rc = status_check(mop, status);
        if ( rc )
            return rc;

        domain_pause(d);
        ad->monitor.singlestep_enabled = !status;
        domain_unpause(d);
        break;
    }

    case XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT:
    {
        bool_t status = ad->monitor.software_breakpoint_enabled;

        rc = status_check(mop, status);
        if ( rc )
            return rc;

        domain_pause(d);
        ad->monitor.software_breakpoint_enabled = !status;
        domain_unpause(d);
        break;
    }

    case XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST:
    {
        bool_t status = ad->monitor.guest_request_enabled;

        rc = status_check(mop, status);
        if ( rc )
            return rc;

        ad->monitor.guest_request_sync = mop->u.guest_request.sync;

        domain_pause(d);
        ad->monitor.guest_request_enabled = !status;
        domain_unpause(d);
        break;
    }

    default:
        return -EOPNOTSUPP;

    };

    return 0;
}
static pwr_tStatus IoAgentInit(io_tCtx ctx, io_sAgent* ap)
{
  int sts;
  io_sLocalHilscher_cifX_PnController* local;
  pwr_sClass_Hilscher_cifX_PnController* op
      = (pwr_sClass_Hilscher_cifX_PnController*)ap->op;

  local = (io_sLocalHilscher_cifX_PnController*)calloc(
      1, sizeof(io_sLocalHilscher_cifX_PnController));
  ap->Local = local;

  strcpy(op->ErrorStr, "");
  op->Status = 0;

  if (driver == 0) {
    struct CIFX_LINUX_INIT init;

    memset(&init, 0, sizeof(init));
    init.init_options = CIFX_DRIVER_INIT_AUTOSCAN;
    init.trace_level = 255;

    sts = cifXDriverInit(&init);
    if (!status_check(op, ap, sts, "cifXDriverInit"))
      return IO__INITFAIL;

    sts = xDriverOpen(&driver);
    if (!status_check(op, ap, sts, "xDriverOpen"))
      return IO__INITFAIL;
  }

  // Find the board
  unsigned long board = 0;
  BOARD_INFORMATION boardinfo;
  boardinfo.lBoardError = 0;
  int found = 0;

  while (xDriverEnumBoards(driver, board, sizeof(boardinfo), &boardinfo)
      == CIFX_NO_ERROR) {
    if (str_NoCaseStrcmp(boardinfo.abBoardAlias, op->Alias) == 0) {
      found = 1;
      break;
    }
    board++;
  }
  if (!found) {
    sprintf(op->ErrorStr, "Board with alias \"%s\" not found", op->Alias);
    errh_Error("IO init %s, '%s'", ap->Name, op->ErrorStr);
    return IO__INITFAIL;
  }

  op->Diag.DeviceNumber = boardinfo.tSystemInfo.ulDeviceNumber;
  op->Diag.SerialNumber = boardinfo.tSystemInfo.ulSerialNumber;
  op->Diag.SystemError = boardinfo.ulSystemError;
  // op->Diag.VendorId = boardinfo.tSystemInfo.usManufacturer;

  local->channel = 0;

  local->chan = NULL;

  sts = xChannelOpen(NULL, (char*)CIFX_DEV, local->channel, &local->chan);
  if (!status_check(op, ap, sts, "xChannelOpen"))
    return IO__INITFAIL;

  uint32_t state;
  strcpy(op->ErrorStr, "Device host state not ready");
  for (;;) {
    sts = xChannelHostState(local->chan, CIFX_HOST_STATE_READY, &state, 100);
    if (sts != CIFX_DEV_NOT_READY)
      break;
    sleep(1);
  }
  strcpy(op->ErrorStr, "");

  sts = xChannelReset(local->chan, CIFX_SYSTEMSTART, 2000);
  if (sts != CIFX_NO_ERROR) {
    printf("xChannelReset: 0x%08x\n", sts);
  }

  for (;;) {
    sts = xChannelHostState(local->chan, CIFX_HOST_STATE_READY, &state, 100);
    if (sts != CIFX_DEV_NOT_READY)
      break;
    sleep(1);
  }

  CHANNEL_INFORMATION channelinfo = { { 0 } };
  sts = xDriverEnumChannels(
      driver, board, local->channel, sizeof(channelinfo), &channelinfo);
  if (sts == CIFX_NO_ERROR) {
    strncpy(op->Diag.FirmwareName, (char*)channelinfo.abFWName,
        sizeof(op->Diag.FirmwareName));
    snprintf(op->Diag.FirmwareVersion, sizeof(op->Diag.FirmwareVersion),
        "%u.%u.%u-%u (%4u-%02hu-%02hu)", channelinfo.usFWMajor,
        channelinfo.usFWMinor, channelinfo.usFWBuild, channelinfo.usFWRevision,
        channelinfo.usFWYear, channelinfo.bFWMonth, channelinfo.bFWDay);
  }

  RCX_LOCK_UNLOCK_CONFIG_REQ_T unlock = { { 0 } };
  RCX_LOCK_UNLOCK_CONFIG_CNF_T unlock_cnf = { { 0 } };

  unlock.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  unlock.tHead.ulLen = HOST_TO_LE32(sizeof(unlock.tData));
  unlock.tHead.ulCmd = HOST_TO_LE32(RCX_LOCK_UNLOCK_CONFIG_REQ);
  unlock.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  unlock.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
  unlock.tData.ulParam = 2; // Unlock

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&unlock, 10);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(
      local->chan, sizeof(unlock_cnf), (CIFX_PACKET*)&unlock_cnf, 20000);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, unlock_cnf.tHead.ulCmd, RCX_LOCK_UNLOCK_CONFIG_CNF)
      || !status_check(op, ap, unlock_cnf.tHead.ulSta, "Unlock channel"))
    return IO__INITFAIL;

  t_addr ipaddress;
  t_addr subnetmask;
  int num;

  num = sscanf(op->IP_Address, "%hhu.%hhu.%hhu.%hhu", &ipaddress.b[3],
      &ipaddress.b[2], &ipaddress.b[1], &ipaddress.b[0]);
  if (num != 4) {
    sprintf(op->ErrorStr, "IP Address syntax error, %s", ap->Name);
    return IO__INITFAIL;
  }
  num = sscanf(op->SubnetMask, "%hhu.%hhu.%hhu.%hhu", &subnetmask.b[3],
      &subnetmask.b[2], &subnetmask.b[1], &subnetmask.b[0]);
  if (num != 4) {
    sprintf(op->ErrorStr, "SubnetMask syntax error, %s", ap->Name);
    return IO__INITFAIL;
  }

  PNM_APCFG_CFG_PNM_REQ_T pnm_config = { { 0 } };
  PNM_APCFG_CFG_PNM_CNF_T pnm_config_cnf;

  memset(&pnm_config, 0, sizeof(pnm_config));
  memset(&pnm_config_cnf, 0, sizeof(pnm_config_cnf));

  pnm_config.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  pnm_config.tHead.ulDestId = 0;
  pnm_config.tHead.ulLen = HOST_TO_LE32(sizeof(pnm_config.tData));
  pnm_config.tHead.ulId = HOST_TO_LE32(msg_id++);
  pnm_config.tHead.ulCmd = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_PNM_REQ);
  pnm_config.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  pnm_config.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
  pnm_config.tData.tSubHead.ulTrCntrId = 0;
  pnm_config.tData.tSubHead.ulTrDevId = 0;
  pnm_config.tData.tSubHead.ulTrApId = 0;
  pnm_config.tData.tSubHead.ulTrModId = 0;
  pnm_config.tData.tSubHead.ulTrSubModId = 0;
  pnm_config.tData.tSubHead.ulTrIdCnt = 1;
  pnm_config.tData.atData[0].ulTrId = 1;
  pnm_config.tData.atData[0].ulSystemFlags = PNM_APCFG_STARTMODE_APPLICATION;
  pnm_config.tData.atData[0].ulWdgTime = 1000;
  strncpy((char*)pnm_config.tData.atData[0].abTypeOfStation, op->DeviceType,
      sizeof(pnm_config.tData.atData[0].abTypeOfStation));
  pnm_config.tData.atData[0].usTypeOfStationLen
      = strlen((char*)pnm_config.tData.atData[0].abTypeOfStation);
  strncpy((char*)pnm_config.tData.atData[0].abNameOfStation, op->DeviceName,
      sizeof(pnm_config.tData.atData[0].abNameOfStation));
  pnm_config.tData.atData[0].usNameOfStationLen
      = strlen((char*)pnm_config.tData.atData[0].abNameOfStation);
  pnm_config.tData.atData[0].usVendorID
      = 0x011E; /* Hilscher Profinet VendorID */
  pnm_config.tData.atData[0].usDeviceID
      = 0x0203; /* Hilscher cifX DeviceID for IO-Controller */
  pnm_config.tData.atData[0].ulIPAddr = ipaddress.m;
  pnm_config.tData.atData[0].ulNetmask = subnetmask.m;
  pnm_config.tData.atData[0].ulGateway = 0;
  pnm_config.tData.atData[0].ulIPFlags = 0;
  // These are in the 'EXT' message
  // pnm_config.tData.atData[0].usMAUTypePort0 = PNM_APCFG_PNM_MAUTYPE_AUTO;
  // pnm_config.tData.atData[0].usMAUTypePort1 = PNM_APCFG_PNM_MAUTYPE_AUTO;
  // pnm_config.tData.atData[0].ulStructVersion =
  // PNM_APCFG_CFG_PNM_STRUCT_VERS_1;

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&pnm_config, 10);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(
      local->chan, sizeof(pnm_config_cnf), (CIFX_PACKET*)&pnm_config_cnf, 20);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, pnm_config_cnf.tHead.ulCmd,
             PNM_APCTL_CMD_SET_CONFIG_PNM_CNF)
      || !status_check(op, ap, pnm_config_cnf.tHead.ulSta, "Controller Config"))
    return IO__INITFAIL;

  // Device loop

  int device = 0;

  int input_dpm_offset = 0;
  int output_dpm_offset = 0;
  int prev_input_dpm_offset = 0;
  int prev_output_dpm_offset = 0;
  io_sRack* rp;
  io_sCard* cp;

  int dev_cnt = 0;
  for (rp = ap->racklist; rp; rp = rp->next) {
    io_sPnRackLocal* rp_local;

    dev_cnt++;

    rp_local = (io_sPnRackLocal*)calloc(1, sizeof(io_sPnRackLocal));
    rp->Local = rp_local;

    rp_local->userdata = calloc(1, sizeof(cifx_sDeviceUserData));

    for (cp = rp->cardlist; cp; cp = cp->next)
      cp->Local = calloc(1, sizeof(io_sPnCardLocal));

    GsdmlDeviceData* dev_data;
    dev_data = new GsdmlDeviceData;
    pwr_tFileName fname;

    sprintf(fname, "$pwrp_load/pwr_pn_%s.xml",
        cdh_ObjidToFnString(NULL, rp->Objid));
    dcli_translate_filename(fname, fname);

    sts = dev_data->read(fname);
    if (EVEN(sts)) {
      snprintf(op->ErrorStr, sizeof(op->ErrorStr),
          "Missing device xml file, %s", rp->Name);
      return IO__INITFAIL;
    }

    ((cifx_sDeviceUserData*)rp_local->userdata)->dev_data = dev_data;
  }

  // PNM_IOD

  PNM_APCFG_CFG_IOD_REQ_T* iod_config = (PNM_APCFG_CFG_IOD_REQ_T*)calloc(1,
      sizeof(*iod_config) + (dev_cnt - 1) * sizeof(iod_config->tData.atData));
  PNM_APCFG_CFG_IOD_CNF_T iod_config_cnf = { { 0 } };

  iod_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  iod_config->tHead.ulLen = HOST_TO_LE32(sizeof(iod_config->tData)
      + (dev_cnt - 1) * sizeof(iod_config->tData.atData));
  iod_config->tHead.ulId = HOST_TO_LE32(msg_id++);
  iod_config->tHead.ulCmd = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_REQ);
  iod_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  iod_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
  iod_config->tData.tSubHead.ulTrCntrId = 1;
  iod_config->tData.tSubHead.ulTrDevId = 0;
  iod_config->tData.tSubHead.ulTrApId = 0;
  iod_config->tData.tSubHead.ulTrModId = 0;
  iod_config->tData.tSubHead.ulTrSubModId = 0;
  iod_config->tData.tSubHead.ulTrIdCnt = dev_cnt;

  device = 0;
  for (rp = ap->racklist; rp; rp = rp->next) {
    t_addr ipaddress;
    t_addr subnetmask;

    io_sPnRackLocal* rp_local = (io_sPnRackLocal*)rp->Local;
    GsdmlDeviceData* dev_data
        = ((cifx_sDeviceUserData*)rp_local->userdata)->dev_data;

    sscanf(dev_data->ip_address, "%hhu.%hhu.%hhu.%hhu", &ipaddress.b[3],
        &ipaddress.b[2], &ipaddress.b[1], &ipaddress.b[0]);
    sscanf(dev_data->subnet_mask, "%hhu.%hhu.%hhu.%hhu", &subnetmask.b[3],
        &subnetmask.b[2], &subnetmask.b[1], &subnetmask.b[0]);

    iod_config->tData.atData[device].ulTrId = device + 1;
    iod_config->tData.atData[device].ulFlags = PNM_APCFG_IOD_FLAG_IOD_ACTIVE;
    strncpy((char*)iod_config->tData.atData[device].abNameOfStation,
        dev_data->device_name,
        sizeof(iod_config->tData.atData[device].abNameOfStation));
    iod_config->tData.atData[device].usNameOfStationLen
        = strlen((char*)iod_config->tData.atData[device].abNameOfStation);
    iod_config->tData.atData[device].usVendorID = dev_data->vendor_id;
    iod_config->tData.atData[device].usDeviceID = dev_data->device_id;
    iod_config->tData.atData[device].ulIPAddr = ipaddress.m;
    iod_config->tData.atData[device].ulNetworkMask = subnetmask.m;
    iod_config->tData.atData[device].ulGatewayAddr = 0;
    iod_config->tData.atData[device].ulArUuidData1 = device + 1;
    iod_config->tData.atData[device].usArUuidData2 = device + 1;
    iod_config->tData.atData[device].usArUuidData3 = device + 1;
    iod_config->tData.atData[device].usARType = PNIO_API_AR_TYPE_SINGLE;
    iod_config->tData.atData[device].ulARProp = PNIO_API_AR_PROP_SUPERVISOR_NONE
        | PNIO_API_AR_PROP_STATE_PRIMARY | PNIO_API_AR_PROP_SINGLE_AR | (1 << 4)
        | (1 << 5);
    iod_config->tData.atData[device].usAlarmCRType = PNIO_API_ALCR_TYPE_ALARM;
    iod_config->tData.atData[device].ulAlarmCRProp
        = PNIO_API_ALCR_PROP_PRIO_DEFAULT;
    iod_config->tData.atData[device].usAlarmCRVLANID = 0;
    iod_config->tData.atData[device].ulIPFlags = 0;
    iod_config->tData.atData[device].usRTATimeoutFact = 1;
    iod_config->tData.atData[device].usRTARetries = PNIO_API_RTA_RETRIES_MIN;
    iod_config->tData.atData[device].usObjUUIDInst = dev_data->instance;

    device++;
  }

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)iod_config, 10);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(
      local->chan, sizeof(iod_config_cnf), (CIFX_PACKET*)&iod_config_cnf, 20);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, iod_config_cnf.tHead.ulCmd,
             PNM_APCTL_CMD_SET_CONFIG_IOD_CNF)
      || !status_check(op, ap, pnm_config_cnf.tHead.ulSta, "Device Config"))
    return IO__INITFAIL;

  device = 0;
  for (rp = ap->racklist; rp; rp = rp->next) {
    // Read device xml-file
    io_sPnRackLocal* rp_local = (io_sPnRackLocal*)rp->Local;
    GsdmlDeviceData* dev_data
        = ((cifx_sDeviceUserData*)rp_local->userdata)->dev_data;

    unsigned char macaddr[6];

    // PNM_IOCR

    // Calculate data length
    unsigned int io_input_length = 0;
    unsigned int io_output_length = 0;
    unsigned int io_iocr_input_length = 0;
    unsigned int io_iocr_output_length = 0;

    for (unsigned int i = 0; i < dev_data->slot_data.size(); i++) {
      for (unsigned int j = 0; j < dev_data->slot_data[i]->subslot_data.size();
           j++) {
        if (dev_data->slot_data[i]->subslot_data[j]->io_input_length > 0) {
          io_input_length
              += dev_data->slot_data[i]->subslot_data[j]->io_input_length + 1;
          io_iocr_input_length += 1;
        }
        if (dev_data->slot_data[i]->subslot_data[j]->io_output_length > 0) {
          io_output_length
              += dev_data->slot_data[i]->subslot_data[j]->io_output_length + 1;
          io_iocr_output_length += 1;
        }
        if (dev_data->slot_data[i]->subslot_data[j]->io_input_length == 0
            && dev_data->slot_data[i]->subslot_data[j]->io_output_length == 0) {
          io_input_length += 1;
          io_iocr_input_length += 1;
        }
      }
    }

    PNM_APCFG_CFG_IOCR_REQ_T* iocr_config = (PNM_APCFG_CFG_IOCR_REQ_T*)calloc(
        1, sizeof(*iocr_config) + sizeof(iocr_config->tData.atData));
    PNM_APCFG_CFG_IOCR_CNF_T iocr_config_cnf = { { 0 } };

    sscanf(dev_data->mac_address, "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
        &macaddr[0], &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
        &macaddr[5]);

    iocr_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
    iocr_config->tHead.ulLen = HOST_TO_LE32(
        sizeof(iocr_config->tData) + sizeof(iocr_config->tData.atData));
    iocr_config->tHead.ulId = HOST_TO_LE32(msg_id++);
    iocr_config->tHead.ulCmd
        = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_IOCR_REQ);
    iocr_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
    iocr_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
    iocr_config->tData.tSubHead.ulTrCntrId = 1;
    iocr_config->tData.tSubHead.ulTrDevId = device + 1;
    iocr_config->tData.tSubHead.ulTrApId = 0;
    iocr_config->tData.tSubHead.ulTrModId = 0;
    iocr_config->tData.tSubHead.ulTrSubModId = 0;
    iocr_config->tData.tSubHead.ulTrIdCnt = 2;
    for (int i = 0; i < 2; i++) {
      iocr_config->tData.atData[i].ulTrId = i + 1;
      iocr_config->tData.atData[i].usType
          = dev_data->iocr_data[i ? 0 : 1]->type;
      iocr_config->tData.atData[i].usVLANID = 0;
      iocr_config->tData.atData[i].ulProp = PNIO_API_IOCR_PROP_RTCLASS_DATA1;
      // strncpy( (char *)iocr_config->tData.atData[i].abMcastMACAddr, (char
      // *)macaddr,
      //	     sizeof(iocr_config->tData.atData[i].abMcastMACAddr));
      memset((char*)iocr_config->tData.atData[i].abMcastMACAddr, 0,
          sizeof(iocr_config->tData.atData[i].abMcastMACAddr));
      if (iocr_config->tData.atData[i].usType == 1)
        iocr_config->tData.atData[i].usDataLen
            = io_input_length + io_iocr_output_length;
      else
        iocr_config->tData.atData[i].usDataLen
            = io_output_length + io_iocr_input_length;
      iocr_config->tData.atData[i].usSendClockFact
          = dev_data->iocr_data[i ? 0 : 1]->send_clock_factor;
      iocr_config->tData.atData[i].usReductRatio
          = dev_data->iocr_data[i ? 0 : 1]->reduction_ratio;
      iocr_config->tData.atData[i].usPhase
          = dev_data->iocr_data[i ? 0 : 1]->phase;
      iocr_config->tData.atData[i].usSequ = 0;
      iocr_config->tData.atData[i].ulFrameSendOffs
          = PNIO_API_FRAME_SEND_OFFSET_DEFAULT;
      iocr_config->tData.atData[i].usWatchdogFact
          = PNIO_API_CYCLIC_WATCHDOG_DEFAULT;
      iocr_config->tData.atData[i].usDataHoldFact
          = PNIO_API_CYCLIC_DATAHOLD_DEFAULT;
    }

    sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)iocr_config, 10);
    if (!status_check(op, ap, sts, "xChannelPutPacket"))
      return IO__INITFAIL;

    sts = xChannelGetPacket(local->chan, sizeof(iocr_config_cnf),
        (CIFX_PACKET*)&iocr_config_cnf, 20);
    if (!status_check(op, ap, sts, "xChannelGetPacket")
        || !cmd_check(op, ap, iocr_config_cnf.tHead.ulCmd,
               PNM_APCTL_CMD_SET_CONFIG_IOD_IOCR_CNF)
        || !status_check(op, ap, pnm_config_cnf.tHead.ulSta, "IOCR Config"))
      return IO__INITFAIL;

    free(iocr_config);

    // PNM_IOD_AP

    PNM_APCFG_CFG_AP_REQ_T ap_config = { { 0 } };
    PNM_APCFG_CFG_AP_CNF_T ap_config_cnf = { { 0 } };

    ap_config.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
    ap_config.tHead.ulLen = HOST_TO_LE32(sizeof(ap_config.tData));
    ap_config.tHead.ulId = HOST_TO_LE32(msg_id++);
    ap_config.tHead.ulCmd = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_AP_REQ);
    ap_config.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
    ap_config.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
    ap_config.tData.tSubHead.ulTrCntrId = 1;
    ap_config.tData.tSubHead.ulTrDevId = device + 1;
    ap_config.tData.tSubHead.ulTrApId = 0;
    ap_config.tData.tSubHead.ulTrModId = 0;
    ap_config.tData.tSubHead.ulTrSubModId = 0;
    ap_config.tData.tSubHead.ulTrIdCnt = 1;
    ap_config.tData.atData[0].ulTrId = 1;
    ap_config.tData.atData[0].ulAPI = 0;

    sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&ap_config, 10);
    if (!status_check(op, ap, sts, "xChannelPutPacket"))
      return IO__INITFAIL;

    sts = xChannelGetPacket(
        local->chan, sizeof(ap_config_cnf), (CIFX_PACKET*)&ap_config_cnf, 20);
    if (!status_check(op, ap, sts, "xChannelGetPacket")
        || !cmd_check(op, ap, ap_config_cnf.tHead.ulCmd,
               PNM_APCTL_CMD_SET_CONFIG_IOD_AP_CNF)
        || !status_check(
               op, ap, ap_config_cnf.tHead.ulSta, "Application Process"))
      return IO__INITFAIL;

    // PNM_MODULE

    // Check number of configured slots
    int slots = 0;
    for (unsigned int i = 0; i < dev_data->slot_data.size(); i++) {
      if (dev_data->slot_data[i]->module_ident_number == 0)
        break;
      slots++;
    }

    PNM_APCFG_CFG_MODULE_REQ_T* module_config
        = (PNM_APCFG_CFG_MODULE_REQ_T*)calloc(1, sizeof(*module_config)
                + (slots - 1) * sizeof(module_config->tData.atData));
    PNM_APCFG_CFG_MODULE_CNF_T module_config_cnf = { { 0 } };

    module_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
    module_config->tHead.ulLen = HOST_TO_LE32(sizeof(module_config->tData)
        + (slots - 1) * sizeof(module_config->tData.atData));
    module_config->tHead.ulId = HOST_TO_LE32(msg_id++);
    module_config->tHead.ulCmd
        = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_MODULE_REQ);
    module_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
    module_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
    module_config->tData.tSubHead.ulTrCntrId = 1;
    module_config->tData.tSubHead.ulTrDevId = device + 1;
    module_config->tData.tSubHead.ulTrApId = 1;
    module_config->tData.tSubHead.ulTrModId = 0;
    module_config->tData.tSubHead.ulTrSubModId = 0;
    module_config->tData.tSubHead.ulTrIdCnt = slots;
    for (int i = 0; i < slots; i++) {
      module_config->tData.atData[i].ulTrId = i + 1;
      module_config->tData.atData[i].ulModuleID
          = dev_data->slot_data[i]->module_ident_number;
      module_config->tData.atData[i].usModuleProp = 0;
      module_config->tData.atData[i].usSlotNumber
          = dev_data->slot_data[i]->slot_number;
    }

    sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)module_config, 10);
    if (!status_check(op, ap, sts, "xChannelPutPacket"))
      return IO__INITFAIL;

    sts = xChannelGetPacket(local->chan, sizeof(module_config_cnf),
        (CIFX_PACKET*)&module_config_cnf, 20);
    if (!status_check(op, ap, sts, "xChannelGetPacket")
        || !cmd_check(op, ap, module_config_cnf.tHead.ulCmd,
               PNM_APCTL_CMD_SET_CONFIG_IOD_MODULE_CNF)
        || !status_check(
               op, ap, module_config_cnf.tHead.ulSta, "Module Config"))
      return IO__INITFAIL;

    free(module_config);

    // PNM_SUBMODULE

    for (int i = 0; i < slots; i++) {
      int subslots = dev_data->slot_data[i]->subslot_data.size();

      PNM_APCFG_CFG_SUBMODULE_REQ_T* submodule_config
          = (PNM_APCFG_CFG_SUBMODULE_REQ_T*)calloc(1, sizeof(*submodule_config)
                  + (subslots - 1) * sizeof(submodule_config->tData.atData));
      PNM_APCFG_CFG_SUBMODULE_CNF_T submodule_config_cnf = { { 0 } };

      submodule_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
      submodule_config->tHead.ulLen
          = HOST_TO_LE32(sizeof(submodule_config->tData)
              + (subslots - 1) * sizeof(submodule_config->tData.atData));
      submodule_config->tHead.ulId = HOST_TO_LE32(msg_id++);
      submodule_config->tHead.ulCmd
          = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_SUBMODULE_REQ);
      submodule_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
      submodule_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
      submodule_config->tData.tSubHead.ulTrCntrId = 1;
      submodule_config->tData.tSubHead.ulTrDevId = device + 1;
      submodule_config->tData.tSubHead.ulTrApId = 1;
      submodule_config->tData.tSubHead.ulTrModId = i + 1;
      submodule_config->tData.tSubHead.ulTrSubModId = 0;
      submodule_config->tData.tSubHead.ulTrIdCnt = subslots;
      for (int j = 0; j < subslots; j++) {
        submodule_config->tData.atData[j].ulTrId = j + 1;
        submodule_config->tData.atData[j].ulSubmoduleID
            = dev_data->slot_data[i]->subslot_data[j]->submodule_ident_number;
        submodule_config->tData.atData[j].usSubmoduleProp = 0;
        if (dev_data->slot_data[i]->subslot_data[j]->io_input_length > 0
            && dev_data->slot_data[i]->subslot_data[j]->io_output_length > 0)
          submodule_config->tData.atData[j].usSubmoduleProp
              = PNIO_API_SUBM_PROP_TYPE_BOTH;
        else if (dev_data->slot_data[i]->subslot_data[j]->io_input_length > 0)
          submodule_config->tData.atData[j].usSubmoduleProp
              = PNIO_API_SUBM_PROP_TYPE_INPUT;
        else if (dev_data->slot_data[i]->subslot_data[j]->io_output_length > 0)
          submodule_config->tData.atData[j].usSubmoduleProp
              = PNIO_API_SUBM_PROP_TYPE_OUTPUT;
        else
          submodule_config->tData.atData[j].usSubmoduleProp
              = PNIO_API_SUBM_PROP_TYPE_NONE;

        submodule_config->tData.atData[j].usSubslotNumber
            = dev_data->slot_data[i]->subslot_data[j]->subslot_number;
        // printf( "Submodule %d %d\n", i+1, j+1);
      }

      sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)submodule_config, 10);
      if (!status_check(op, ap, sts, "xChannelPutPacket"))
        return IO__INITFAIL;

      sts = xChannelGetPacket(local->chan, sizeof(submodule_config_cnf),
          (CIFX_PACKET*)&submodule_config_cnf, 20);
      if (!status_check(op, ap, sts, "xChannelGetPacket")
          || !cmd_check(op, ap, submodule_config_cnf.tHead.ulCmd,
                 PNM_APCTL_CMD_SET_CONFIG_IOD_SUBMODULE_CNF)
          || !status_check(
                 op, ap, submodule_config_cnf.tHead.ulSta, "Submodule Config"))
        return IO__INITFAIL;

      free(submodule_config);
    }

    // PNM_SUBMDESCR

    int input_frame_offset = 0;
    int output_frame_offset = 0;
    int input_iocs_frame_offset = io_output_length;
    int output_iocs_frame_offset = io_input_length;

    for (int i = 0; i < slots; i++) {
      int subslots = dev_data->slot_data[i]->subslot_data.size();
      int prev_slot_input_dpm_offset = input_dpm_offset;
      int prev_slot_output_dpm_offset = output_dpm_offset;

      for (int j = 0; j < subslots; j++) {
        int io_input_length
            = dev_data->slot_data[i]->subslot_data[j]->io_input_length;
        int io_output_length
            = dev_data->slot_data[i]->subslot_data[j]->io_output_length;

        int size = 1;
        if (io_input_length > 0 && io_output_length > 0)
          size = 2;

        PNM_APCFG_CFG_SUBMDESCR_REQ_T* submdescr_config
            = (PNM_APCFG_CFG_SUBMDESCR_REQ_T*)calloc(
                1, sizeof(*submdescr_config)
                    + (size - 1) * sizeof(submdescr_config->tData.atData));
        PNM_APCFG_CFG_SUBMDESCR_CNF_T submdescr_config_cnf = { { 0 } };

        submdescr_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
        submdescr_config->tHead.ulLen
            = HOST_TO_LE32(sizeof(submdescr_config->tData)
                + (size - 1) * sizeof(submdescr_config->tData.atData));
        submdescr_config->tHead.ulId = HOST_TO_LE32(msg_id++);
        submdescr_config->tHead.ulCmd
            = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_SUBMDESCR_REQ);
        submdescr_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
        submdescr_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
        submdescr_config->tData.tSubHead.ulTrCntrId = 1;
        submdescr_config->tData.tSubHead.ulTrDevId = device + 1;
        submdescr_config->tData.tSubHead.ulTrApId = 1;
        submdescr_config->tData.tSubHead.ulTrModId = i + 1;
        submdescr_config->tData.tSubHead.ulTrSubModId = j + 1;
        submdescr_config->tData.tSubHead.ulTrIdCnt = size;
        for (int k = 0; k < size; k++) {
          submdescr_config->tData.atData[k].ulTrId = k + 1;
          if (io_input_length == 0 && io_output_length == 0) {
            submdescr_config->tData.atData[k].usDataDescr
                = PNIO_API_SUBMDESCR_DATA_DESCR_INPUT;
            submdescr_config->tData.atData[k].usSubmDataLen = 0;
            submdescr_config->tData.atData[k].usFrameOffs = input_frame_offset;
            submdescr_config->tData.atData[k].usIOCSFrameOffs
                = input_iocs_frame_offset;
            submdescr_config->tData.atData[k].ulIO_Block = 0;
            submdescr_config->tData.atData[k].ulDPM_Offset = 0;
            // printf( "%d %d None:   iocsoffs %d offs %d len %d\n", i+1, j+1,
            // input_iocs_frame_offset, input_frame_offset, io_input_length);
          } else if ((size == 1 && io_input_length > 0)
              || (size == 2 && k == 0)) {
            submdescr_config->tData.atData[k].usDataDescr
                = PNIO_API_SUBMDESCR_DATA_DESCR_INPUT;
            submdescr_config->tData.atData[k].usSubmDataLen = io_input_length;
            submdescr_config->tData.atData[k].usFrameOffs = input_frame_offset;
            submdescr_config->tData.atData[k].usIOCSFrameOffs
                = input_iocs_frame_offset;
            submdescr_config->tData.atData[k].ulIO_Block = 0;
            submdescr_config->tData.atData[k].ulDPM_Offset = input_dpm_offset;
            // printf( "%d %d Input:  iocsoffs %d offs %d len %d\n", i+1, j+1,
            // input_iocs_frame_offset, input_frame_offset, io_input_length);
          } else {
            submdescr_config->tData.atData[k].usDataDescr
                = PNIO_API_SUBMDESCR_DATA_DESCR_OUTPUT;
            submdescr_config->tData.atData[k].usSubmDataLen = io_output_length;
            submdescr_config->tData.atData[k].usFrameOffs = output_frame_offset;
            submdescr_config->tData.atData[k].usIOCSFrameOffs
                = output_iocs_frame_offset;
            submdescr_config->tData.atData[k].ulIO_Block = 0;
            submdescr_config->tData.atData[k].ulDPM_Offset = output_dpm_offset;
            // printf( "%d %d Output: iocsoffs %d offs %d len %d\n", i+1, j+1,
            // output_iocs_frame_offset, output_frame_offset, io_output_length);
          }
          submdescr_config->tData.atData[k].bIOPSLen = 1;
          submdescr_config->tData.atData[k].bIOCSLen = 1;
          submdescr_config->tData.atData[k].ulIOCRIdProd = 1;
          submdescr_config->tData.atData[k].ulIOCRIdCons = 2;
          submdescr_config->tData.atData[k].ulSignla_Attrib = 0;
        }

        sts = xChannelPutPacket(
            local->chan, (CIFX_PACKET*)submdescr_config, 10);
        if (!status_check(op, ap, sts, "xChannelPutPacket"))
          return IO__INITFAIL;

        sts = xChannelGetPacket(local->chan, sizeof(submdescr_config_cnf),
            (CIFX_PACKET*)&submdescr_config_cnf, 20);
        if (!status_check(op, ap, sts, "xChannelGetPacket")
            || !cmd_check(op, ap, submdescr_config_cnf.tHead.ulCmd,
                   PNM_APCTL_CMD_SET_CONFIG_IOD_SUBMDESCR_CNF)
            || !status_check(op, ap, submdescr_config_cnf.tHead.ulSta,
                   "Submodule Description"))
          return IO__INITFAIL;

        if (io_input_length > 0) {
          input_frame_offset += io_input_length + 1;
          input_iocs_frame_offset += 1;
          input_dpm_offset += io_input_length;
        }
        if (io_output_length > 0) {
          output_frame_offset += io_output_length + 1;
          output_iocs_frame_offset += 1;
          output_dpm_offset += io_output_length;
        }
        if (io_input_length == 0 && io_output_length == 0) {
          input_frame_offset += 1;
          input_iocs_frame_offset += 1;
        }

        free(submdescr_config);
      }

      if (i > 0) {
        // First slot is the device and has no card
        if (i == 1)
          cp = rp->cardlist;
        else
          cp = cp->next;

        if (!cp) {
          snprintf(op->ErrorStr, sizeof(op->ErrorStr),
              "Module config mismatch in xml-file, %s", rp->Name);
          errh_Error("IO init %s, '%s'", ap->Name, op->ErrorStr);
          return IO__INITFAIL;
        }

        io_sPnCardLocal* cp_local = (io_sPnCardLocal*)cp->Local;

        cp_local->input_area_size
            = input_dpm_offset - prev_slot_input_dpm_offset;
        cp_local->output_area_size
            = output_dpm_offset - prev_slot_output_dpm_offset;
      }
      prev_slot_input_dpm_offset = input_dpm_offset;
      prev_slot_output_dpm_offset = output_dpm_offset;
    }

    rp_local->bytes_of_input = input_dpm_offset - prev_input_dpm_offset;
    rp_local->bytes_of_output = output_dpm_offset - prev_output_dpm_offset;
    prev_input_dpm_offset = input_dpm_offset;
    prev_output_dpm_offset = output_dpm_offset;

    // PNM_RECORD

    for (int i = 0; i < slots; i++) {
      int subslots = dev_data->slot_data[i]->subslot_data.size();

      for (int j = 0; j < subslots; j++) {
        int records
            = dev_data->slot_data[i]->subslot_data[j]->data_record.size();

        if (!records)
          continue;

        int size = sizeof(PNM_APCFG_CFG_RECORD_REQ_T)
            + (records - 1) * (sizeof(PNM_APCFG_CFG_RECORD_DATA_T) - 1);
        for (int k = 0; k < records; k++)
          size += dev_data->slot_data[i]
                      ->subslot_data[j]
                      ->data_record[k]
                      ->data_length;

        PNM_APCFG_CFG_RECORD_REQ_T* record_config
            = (PNM_APCFG_CFG_RECORD_REQ_T*)calloc(1, size);
        PNM_APCFG_CFG_RECORD_CNF_T record_config_cnf = { { 0 } };

        record_config->tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
        record_config->tHead.ulLen = HOST_TO_LE32(size);
        record_config->tHead.ulId = HOST_TO_LE32(msg_id++);
        record_config->tHead.ulCmd
            = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_IOD_RECDATA_REQ);
        record_config->tHead.ulSrc = HOST_TO_LE32(PN_SRC);
        record_config->tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
        record_config->tData.tSubHead.ulTrCntrId = 1;
        record_config->tData.tSubHead.ulTrDevId = device + 1;
        record_config->tData.tSubHead.ulTrApId = 1;
        record_config->tData.tSubHead.ulTrModId = i + 1;
        record_config->tData.tSubHead.ulTrSubModId = j + 1;
        record_config->tData.tSubHead.ulTrIdCnt = records;

        PNM_APCFG_CFG_RECORD_DATA_T* rp = &record_config->tData.tRecord;
        for (int k = 0; k < records; k++) {
          rp->ulTrId = k + 1;
          rp->usIndex = k + 1;
          rp->ulDataLen = dev_data->slot_data[i]
                              ->subslot_data[j]
                              ->data_record[k]
                              ->data_length;
          memcpy(rp->abRecordData,
              dev_data->slot_data[i]->subslot_data[j]->data_record[k]->data,
              rp->ulDataLen);

          rp = (PNM_APCFG_CFG_RECORD_DATA_T*)((char*)rp + sizeof(*rp)
              + rp->ulDataLen - 1);
        }

        sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)record_config, 10);
        if (!status_check(op, ap, sts, "xChannelPutPacket"))
          return IO__INITFAIL;

        sts = xChannelGetPacket(local->chan, sizeof(record_config_cnf),
            (CIFX_PACKET*)&record_config_cnf, 20);
        if (!status_check(op, ap, sts, "xChannelGetPacket")
            || !cmd_check(op, ap, record_config_cnf.tHead.ulCmd,
                   PNM_APCTL_CMD_SET_CONFIG_IOD_RECDATA_CNF)
            || !status_check(
                   op, ap, record_config_cnf.tHead.ulSta, "Record Data"))
          return IO__INITFAIL;

        free(record_config);
      }
    }

    delete dev_data;
    ((cifx_sDeviceUserData*)rp_local->userdata)->dev_data = 0;

    device++;
  }

  // PNM_FIN

  PNM_APCFG_DWNL_FIN_REQ_T dwnl_fin_config = { { 0 } };
  PNM_APCFG_DWNL_FIN_CNF_T dwnl_fin_config_cnf = { { 0 } };

  dwnl_fin_config.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  dwnl_fin_config.tHead.ulLen = 0;
  dwnl_fin_config.tHead.ulId = HOST_TO_LE32(msg_id++);
  dwnl_fin_config.tHead.ulCmd
      = HOST_TO_LE32(PNM_APCTL_CMD_SET_CONFIG_DWNL_FIN_REQ);
  dwnl_fin_config.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  dwnl_fin_config.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&dwnl_fin_config, 10);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(local->chan, sizeof(dwnl_fin_config_cnf),
      (CIFX_PACKET*)&dwnl_fin_config_cnf, 20);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, dwnl_fin_config_cnf.tHead.ulCmd,
             PNM_APCTL_CMD_SET_CONFIG_DWNL_FIN_CNF)
      || !status_check(
             op, ap, dwnl_fin_config_cnf.tHead.ulSta, "Controller Config"))
    return IO__INITFAIL;

  // LOCK
  RCX_LOCK_UNLOCK_CONFIG_REQ_T lock = { { 0 } };
  RCX_LOCK_UNLOCK_CONFIG_CNF_T lock_cnf = { { 0 } };

  lock.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  lock.tHead.ulLen = HOST_TO_LE32(sizeof(lock.tData));
  lock.tHead.ulCmd = HOST_TO_LE32(RCX_LOCK_UNLOCK_CONFIG_REQ);
  lock.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  lock.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);
  lock.tData.ulParam = 1; // Lock

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&lock, 10);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(
      local->chan, sizeof(lock_cnf), (CIFX_PACKET*)&lock_cnf, 20);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, lock_cnf.tHead.ulCmd, RCX_LOCK_UNLOCK_CONFIG_CNF)
      || !status_check(op, ap, lock_cnf.tHead.ulSta, "Unlock channel"))
    return IO__INITFAIL;

  // Register application
  RCX_REGISTER_APP_REQ_T regapp = { { 0 } };
  RCX_REGISTER_APP_CNF_T regapp_cnf = { { 0 } };

  regapp.tHead.ulDest = HOST_TO_LE32(PNM_APPLICATION);
  regapp.tHead.ulLen = 0;
  regapp.tHead.ulCmd = HOST_TO_LE32(RCX_REGISTER_APP_REQ);
  regapp.tHead.ulSrc = HOST_TO_LE32(PN_SRC);
  regapp.tHead.ulSrcId = HOST_TO_LE32(PN_SRCID);

  sts = xChannelPutPacket(local->chan, (CIFX_PACKET*)&regapp, 1000);
  if (!status_check(op, ap, sts, "xChannelPutPacket"))
    return IO__INITFAIL;

  sts = xChannelGetPacket(
      local->chan, sizeof(regapp_cnf), (CIFX_PACKET*)&regapp_cnf, 10000);
  if (!status_check(op, ap, sts, "xChannelGetPacket")
      || !cmd_check(op, ap, regapp_cnf.tHead.ulCmd, RCX_REGISTER_APP_CNF)
      || !status_check(op, ap, regapp_cnf.tHead.ulSta, "Register Application"))
    return IO__INITFAIL;

  // Create input/output area
  local->input_area_size = input_dpm_offset;
  local->output_area_size = output_dpm_offset;

  local->input_area = calloc(1, MAX(local->input_area_size, 4));
  local->output_area = calloc(1, MAX(local->output_area_size, 4));

  int input_offset = 0;
  int output_offset = 0;
  for (rp = ap->racklist; rp; rp = rp->next) {
    io_sPnRackLocal* rp_local = (io_sPnRackLocal*)rp->Local;

    rp_local->inputs = (unsigned char*)local->input_area + input_offset;
    rp_local->outputs = (unsigned char*)local->output_area + output_offset;

    int slot_input_offset = input_offset;
    int slot_output_offset = output_offset;
    for (cp = rp->cardlist; cp; cp = cp->next) {
      io_sPnCardLocal* cp_local = (io_sPnCardLocal*)cp->Local;

      cp_local->input_area
          = (unsigned char*)local->input_area + slot_input_offset;
      cp_local->output_area
          = (unsigned char*)local->output_area + slot_output_offset;
      slot_input_offset += cp_local->input_area_size;
      slot_output_offset += cp_local->output_area_size;
    }
    input_offset += rp_local->bytes_of_input;
    output_offset += rp_local->bytes_of_output;

    // Set OK status on device
    ((pwr_sClass_PnDevice*)rp->op)->Status = PB__NORMAL;
    ((pwr_sClass_PnDevice*)rp->op)->State = pwr_ePnDeviceStateEnum_Connected;
  }

  for (;;) {
    sts = xChannelHostState(local->chan, CIFX_HOST_STATE_READY, &state, 100);
    if (sts != CIFX_DEV_NOT_RUNNING)
      break;
    sleep(1);
  }

  sts = xChannelHostState(local->chan, CIFX_HOST_STATE_READ, &state, 0);
  // printf( "Host state: %d\n", state);

  sts = xChannelBusState(local->chan, CIFX_BUS_STATE_GETSTATE, &state, 0);
  // printf( "Bus state: %d\n", state);

  sts = xChannelBusState(
      local->chan, CIFX_BUS_STATE_ON, &state, 5000 /* 20000 */);
  // printf( "Set bus state: 0x%08x\n", sts);

  sts = xChannelBusState(local->chan, CIFX_BUS_STATE_GETSTATE, &state, 0);
  // printf( "Bus state: %d\n", state);

  // It takes ~20 s to get COM-flag
  local->dev_init = 1;
  local->dev_init_limit = (unsigned int)(30.0 / ctx->ScanTime + 0.5);

  errh_Info("Init of Hilscher cifX Profinet Controller '%s'", ap->Name);
  return IO__SUCCESS;
}
示例#27
0
void irAlLabel(t_nombre_etiqueta etiqueta) {
    if(status_check() != EXECUTING)
        return;

    actual_pcb->program_counter = metadata_buscar_etiqueta(etiqueta, actual_pcb->etiquetas, (size_t) actual_pcb->etiquetas_size) - 1;
}
示例#28
0
t_posicion definirVariable(t_nombre_variable variable) {
    if(status_check() != EXECUTING)
        return ERROR;

    //1) Obtener el stack index actual
    t_stack* actual_stack_index = actual_pcb->stack_index;

    //2) Obtengo la primera posicion libre del stack
    t_posicion actual_stack_pointer = (t_posicion) actual_pcb->stack_pointer;

    //3) Armamos la logical address requerida
    logical_addr* direccion_espectante = armar_direccion_logica_variable(actual_stack_pointer, setup->PAGE_SIZE);

    int valor = 0;

    t_list * pedidos = NULL;
    //TODO: CAMBIAR ESTO PARA QUE LA LISTA DE PEDIDOS SEA DE NUMEROS, NO DE SPRINTF
    obtener_lista_operaciones_escritura(&pedidos, actual_stack_pointer, ANSISOP_VAR_SIZE, valor);

    int index = 0;
    t_nodo_send * nodo = NULL;
    char * umc_response_buffer = calloc(1, sizeof(char));
    if(umc_response_buffer == NULL) {
        log_error(cpu_log, "definirVariable umc_response_buffer mem alloc failed");
        return ERROR;
    }

    char operation;
    int page, offset, size, print_index = 0;
    while (list_size(pedidos) > 0) {
        nodo = list_remove(pedidos, index);
        deserialize_data(&operation, sizeof(char), nodo->data, &print_index);
        deserialize_data(&page, sizeof(int), nodo->data, &print_index);
        deserialize_data(&offset, sizeof(int), nodo->data, &print_index);
        deserialize_data(&size, sizeof(int), nodo->data, &print_index);
        log_info(cpu_log, "Sending request op:%c (%d,%d,%d) to define variable '%c' with value %d", operation, page, offset, size, variable, valor);
        if( send(umcSocketClient, nodo->data , (size_t ) nodo->data_length, 0) < 0) {
            log_error(cpu_log, "UMC expected addr send failed");
            return ERROR;
        }

        if(check_umc_response(recv_umc_response_status()) != SUCCESS) {
            return ERROR;
        }

    }

    list_destroy(pedidos); //Liberamos la estructura de lista reservada

    free(umc_response_buffer);

    //5) Si esta bien, agregamos la nueva t_var al stack
    t_var * nueva_variable = calloc(1, sizeof(t_var));
    nueva_variable->var_id = variable;
    nueva_variable->page_number = direccion_espectante->page_number;
    nueva_variable->offset = direccion_espectante->offset;
    nueva_variable->tamanio = direccion_espectante->tamanio;

    //6) Actualizo el stack pointer
    actual_pcb->stack_pointer += nueva_variable->tamanio;

    free(direccion_espectante);
    t_stack_entry *last_entry = get_last_entry(actual_stack_index);
    add_var( &last_entry, nueva_variable);

    //7) y retornamos la t_posicion asociada
    t_posicion posicion_nueva_variable = get_t_posicion(nueva_variable);
    return posicion_nueva_variable;
}