Friday, November 24, 2006

Funções GPIB 488.2

Ibask Retorna informação sobre parâmetros configuráveis do software
ibbna Atribuir a um identificador de um dispositivo um nome de acesso á interface
ibclr Limpa dispositivo especifico
ibconfig Alterar parâmetros configuráveis
ibdev Inicializar dispositivo
ibeos Configurar “end-of-string” (EOS) em “termination mode” ou
caracter
ibeot Liga ou desliga a inserção automática da linha GPIB EOI no final de todas as operações I/O
ibln Verifica a presença de dispositivos no BUS
ibloc Modo Local
ibonl Colocar dispositivo ONLINE ou OFFLINE
ibpad Alterar Endereço Primário
ibpct Com a utilização do controlador, passar a comunicação para outro dispositivo
ibrd Ler Dados do dispositivo para a memoria
ibrdf Ler Dados do dispositivo para a um ficheiro
ibrsp Controlar uma “serial poll”
ibsad Alterar ou desligar Endereço Secundário
ibstop Aborta operação I/O assincronizado
ibtmo Alterar ou desligar o período I/O timeout
ibtrg Acciona dispositivo especifico
ibwait Espere por eventos de GPIB
ibwrt Escrever dados da memoria para dispositivo
Ibwrtf Escrever dados de um ficheiro para dispositivo

Monday, November 20, 2006

GPIB (Briefing)

O primeiro GPIB foi criado pela Hewlett-Packard em 1960 com o propósito de conectar instrumentos programáveis da mesma marca (HP-IB). Mas com a entrada de novos instrumentos digitais e equipamentos de teste programáveis, houve a necessidade de criar uma interface standard de grande velocidade que permitisse a comunicação entre equipamentos de diferentes fabricantes.

A primeira standard, ANSI/IEEE Standard 488-1975, será publicada em 1975 pelo “Institute of Electrical and Electronic Engineers” (IEEE), que continha todas as especificações eléctricas, mecânicas e funcionais.

Devido a original IEEE488 não conter nenhuma orientação em relação a sintaxe e formatações convencionais, procurou-se aperfeiçoar todos estes pormenores juntamente com um a necessidade de um aumento de compatibilidade entre instrumentos de teste. Desta investigação resultou o standard IEEE 488.2 que não foi substituir o IEEE 488 renomeando-o para IEEE 488.1.

Em 1990, o IEEE 488.2 inclui o documento “Standard Commands for Programmable Instrumentation” (SCPI), que viria a definir comandos específicos para diferentes classes de instrumentos, garantindo sempre a compatibilidade entre eles e facilitando ao utilizador não obrigação de ter que saber diferentes comandos para cada tipo de instrumentos num sistema SCPI, e até mesmo garantido a possibilidade de substituir instrumentos de marcas diferentes.

Funções com Parâmetros

Para construir uma função que necessita de receber argumentos, o PHP irá recorrer á Macro zend_parse_parameters().

Ex: zend_parse_parameters( zend_num_args() TSRMLS_CC, tipo_variavel, referencia_variavel, referencia_tamanho)


zend_num_args() – retorna um INT com o nº de parâmetros passados para a função

Tipos de Variável:

b -Booleano zend_bool
l -Inteiro long
d -Virgula Flutuante double
s -String char*, int
r -Resource zval*
a -Array zval*
o -Instância de um Objecto zval*
O -Instância de um Objecto de um tipo especifico zval*, zend_class_entry*
z -Zval não especifico zval*
Z -Zval não especifico referenciado zval**

Ex:

Em PHP:

function testPar($value) {
echo " $value ";
}



Em C:

PHP_FUNCTION(testPar)
{
char *value;
int value_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
&value, &value_len) == FAILURE) {
RETURN_NULL();
}
PHPWRITE(value, value_len);
}


Parâmetros Opcionais:

| -Valor Opcional
! -Se a variável logo a seguir for do tipo NULL, o PHP irá atribuirlhe o valor interno IS_NULL zval.
/ -Criação de nova variável is_ref==0 e refcount==1.

Tuesday, November 07, 2006

Retornar Valores com Macros e Variaveis

Para cada vez que um a função tiver que retornar valores o PHP terá que utilizar a macros correspondentes para cada tipo de dados.

Macro ZVAL
ZVAL_NULL(return_value)-> RETVAL_NULL()
ZVAL_BOOL(return_value, bval)-> RETVAL_BOOL(bval)
ZVAL_TRUE(return_value)-> RETVAL_TRUE
ZVAL_FALSE(return_value)-> RETVAL_FALSE
ZVAL_LONG(return_value, lval)-> RETVAL_LONG(lval)
ZVAL_DOUBLE(return_value, dval)-> RETVAL_DOUBLE(dval)
ZVAL_STRING(return_value, str, dup)-> RETVAL_STRING(str, dup)
ZVAL_STRINGL(return_value, str, len, dup)-> RETVAL_STRINGL(str,len,dup)

Ex:

PHP:

 $var = 'value'; 


C:

{
zval *var;

MAKE_STD_ZVAL(var);//alocar memoria para variavel
ZVAL_LONG(var, 45);//tipo long
RETVAL_LONG(var);//retornar valor

}

Funções Internas Zend

Estas funções, iniciadas por "zif_", têm como finalidade possibilitar a utilização de nomes de funções do lado do utilizador que possam vir a entrar em conflito com a linguagem C em que se está programar, mas nem sempre esta solução é possivel.
Por exemplo a função "fopen" em PHP não poderia ser implementada directamente, porque iria entrar em conflito com a livraria stdio em C.
A solução passará pela utilização de PHP_NAMED_FUNCTION() para atribuir um nome interno á função que queremos utilizar.

Ex:

PHP_NAMED_FE(check_open_file, fopen, NULL);

Existe também a possibilidade de poder referenciar uma função por mais do que 1 nome, para isso poderemos utilizar o PHP_NAMED_FE().

Ex:

PHP_FE(ex_func, NULL)
PHP_NAMED_FE(func, zif_exp_func, NULL)

Ou mais directamente utilizando as funções PHP_FNAME() e PHP_FALIAS()

Ex:

PHP_NAMED_FE(func, PHP_FNAME (exp_func) , NULL)
PHP_ALIAS(func, exp_func, NULL)

Monday, November 06, 2006

PHP_INFO()

Depois de copiar a dll para a pasta das extensões do PHP o php_info() irá mostrar a tabela com a informação da dll:



Criada pela função PHP_MINFO_FUNCTION :


PHP_MINFO_FUNCTION(gpib){
php_info_print_table_start();
php_info_print_table_header(2, "GPIB Functions", "enabled");
php_info_print_table_row(2, "Gpib Version","0.1");
php_info_print_table_row(2, "Gpib Date","26/10/2006");
php_info_print_table_row(2, "Gpib Author","José Mendonça");
php_info_print_table_end();
/* Remove comments if you have entries
in php.ini DISPLAY_INI_ENTRIES(); */
}

EXTENSÃO SIMPLES "HelloWorld"

Ficheiro de configuração config.w32:




// $Id$
// vim:ft=javascript
// Para referir a argumentos externos -> ARG_WITH
// ARG_WITH("gpib", "for gpib support", "no");
// De outro modo -> ARG_ENABLE
// ARG_ENABLE("gpib", "enable gpib support",
"no");
if (PHP_GPIB != "no") {
EXTENSION("gpib", "gpib.c");
}


php_gpib.h



$Id: header,v 1.16.2.1 2006/01/01 12:50:00 sniper Exp $ */
#ifndef
PHP_GPIB_H#define PHP_GPIB_H
extern zend_module_entry
gpib_module_entry;#define phpext_gpib_ptr &gpib_module_entry
#ifdef
PHP_WIN32#define PHP_GPIB_API __declspec(dllexport)
#else#
define
PHP_GPIB_API#endif
#ifdef ZTS#include
"TSRM.h"
#endif
PHP_MINFO_FUNCTION(gpib);
PHP_FUNCTION(hello_world);/*
Função HelloWorld */
#ifdef ZTS#define GPIB_G(v) TSRMG(gpib_globals_id,zend_gpib_globals *, v)
#else#
define GPIB_G(v)
(gpib_globals.v)
#endif
#endif /* PHP_GPIB_H */


gpib.c

#ifdef
HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_gpib.h"
/* True global resources - no need for thread safety here
*/static int le_gpib;
/* {{{
gpib_functions[] * * Todas as Funções
visiveis ao utilizador devem
estar aqui declaradas.
*/
zend_function_entry gpib_functions[] =
{
PHP_FE(hello_world, NULL)
{NULL, NULL,NULL}
/* Sempre a ultima linha no gpib_functions[] */};/*
}}} */
/* {{{
gpib_module_entry
*/zend_module_entry
gpib_module_entry = {#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"gpib",
gpib_functions,
NULL,/*MINIT */
NULL, /* MSHUTDOWN */
NULL, /* RINIT */
NULL, /* RSHUTDOWN */

PHP_MINFO(gpib),#if
ZEND_MODULE_API_NO >= 20010901 "0.1", /* Nº da
versão da extensão
*/#endif STANDARD_MODULE_PROPERTIES};/* }}} */
#ifdef
COMPILE_DL_GPIBZEND_GET_MODULE(gpib)#endif
PHP_MINFO_FUNCTION(gpib){
php_info_print_table_start();
php_info_print_table_header(2, "GPIB Functions", "enabled");
php_info_print_table_row(2, "Gpib Version","0.1");
php_info_print_table_row(2, "Gpib Date","26/10/2006");
php_info_print_table_row(2, "Gpib Author","José Mendonça");
php_info_print_table_end();
/* Remove comments if you
have entries
in
php.ini DISPLAY_INI_ENTRIES(); */}/* }}} */
/* {{{
HelloWorld
*/PHP_FUNCTION(hello_world){ php_printf("Hello World!\n");}/* }}}
*/



Funções ZEND de Gestão de Memória

pemalloc(buffer,1) -> malloc(buffer) memória persistente
pemalloc(buffer,0) -> emalloc(buffer) memória não persistente

safe_ pemalloc () -> evita buffers negativos ou pequenos demais

estrndup(void* var, len) -> strdup(void* var)

pefree(*var, char persistente) -> necessitada variável persistente para identificar a varriavel como persistente ou não
efree(void *var)

Sunday, November 05, 2006

TIPOS DE DADOS ZEND/PHP

TIPOS DE DADOS

A unidade de armazenamento de dados no PHP designa-se por zval, trata-se de uma estrutura simples de 4 membros que está definida no ficheiro zend.h.

typedef struct _zval_struct { zvalue_value
value; zend_uint refcount; zend_uchar
type; zend_uchar is_ref;
} zval;

Tipos de dados utilizados por Zend:

IS_NULL -> valor por defeito de qualquer variável não utilizada, usualmente designada por “non-value” é considerada por variável nula, mas diferente de 0 ou valor lógico FALSE.

IS_BOOL -> condições TRUE\FALSE - ZVAL_BOOL (var, x);

IS_LONG -> do tipo dos Inteiros, com valores entre -2147483648 e +2147483647 (32 bits) - ZVAL_LONG(var, value);

IS_DOUBLE -> do tipo Virgula Flutuante (Float) com valores entre 2.225x10^ (-308) e 1.798x10^308 (32 bits) - ZVAL_DOUBLE(var, value);

IS_STRING -> bloco de memoria, com espaço suficiente para guardar os caracteres de uma string - ZVAL_STRING(var, str, dup);

IS_ARRAY -> trata-se de estrutura de dados especial, que associa chaves de pesquisa a valores, mais conhecida por Tabela Hash.

IS_OBJECT -> pode ser constituído por vários elementos, classes e métodos os quais o utilizador pode aceder sem ter que conhecer a sua constituição.

IS_RESOURCE -> recurso é uma variável especial, mantendo uma referência de recurso externo. Recursos são criados e utilizados por funções especiais.

Funções:

Z_TYPE(variável) -> retorna tipo de variável
Ex: Z_TYPE (var) == IS_LONG
STRVAL (strings) -> (char*) valor da string
STRLEN (strings) -> (int) tamanho da string
ARRVAL (array) -> tabela hash



MAKE_STD_ZVAL () -> macro do zend para alocar memória de forma segura para variável

ALLOC_INIT_ZVAL () -> iniciativa a variável a NULL

Saturday, November 04, 2006

Construção de Extensão PHP em WIN32

O que irá permitir a comunicação entre a interface GPIB e o utilizador será uma extensão PHP construída na Linguagem C utilizando as livrarias do Core do PHP-ZEND. Devido á pouca existência de documentação de criação de extensões PHP em ambiente win32, fiz uma pesquisa e após muitos erros de compilação e falhas de versões (Abençoado UNIX), consegui encontrar a forma mais simples de compilação.

Optei por utilizar um versão do php >5, devido a existirem menos bugs de gestão de memoria e nova funções que podem vir a ser muito uteis.

Software Necessário:

Microsoft® Windows Server 2003 R2 Platform SDK (Caso seja necessário compilar o Core do PHP)
http://www.microsoft.com/downloads/details.aspx?FamilyId=0BAF2B35-C656-4969-ACE8-E4C0C0716ADB&displaylang=en

(Nota: A instalação típica tem tudo o que precisamos, mas (400MB é muito) aconselho a fazer costum e só instalar o Core do SDK)

Visual Studio 6 C++


Apache http Server 2.0.59
http://httpd.apache.org/

PHP 5.1.6 Windows Binary
http://php.mirror.camelnetwork.com/get/php-5.1.6-Win32.zip/from/a/mirror
PHP 5.1.5 Source Code
http://php.mirror.camelnetwork.com/get/php-5.1.6.tar.bz2/from/a/mirror

win32 buildtools do PHP em /extra/win32build.zip

O código-fonte para o DNS name resolver usado pelo PHP em /extra/bindlib_w32.zip. Esse é um substituto para a biblioteca resolv.lib inclusa no arquivo win32build.zip

Passos:

1. Instalar PHP 5.1.6 e Servidor Apache
2. Criar Pasta “mãe” num local de trabalho ex.: c: \projecto
3. Descompactar win32build.zip nesta pasta –> c: \projecto\win32build
4. Descompactar bindlib_w32.zip nesta pasta –> c: \projecto\ bindlib_w32
5. Descompactar código fonte do PHP –> c: \ projecto\php-5.1.6
6. Compilar bindlib_w32, para isso abrir bindlib.dsp com VS6 C++ fazer build (F7), de seguida copiar resolv.lib para a pasta win32build e substituir a que lá está.
7. O primeiro passo para construir a extensão será correr o script tipo SKEL do unix, que irá criar uma pasta na directoria php5.1.6/ext com o projecto para Visual Studio.
a. Colocar a pasta c: \PHP no PATH do Windows
b. Entrar na directoria c: \projecto\php-5.1.6\ext\
c. Linha de Comandos do Windos: php ext_skel_win32.php --extname= [nome da extensão]
8. Copiar a livraria php5ts.lib do directório c: \php\dev para a pasta da extensão
9. Entrar na directoria c: \projecto\php-5.1.6\ext\ [nome da extensão] e abrir ficheiro .dsp para o visual studio
10. Fazer Build (F7) da versão RELEASE_TS
11. A extensão DLL foi criada na pasta c:\projecto\php-5.1.6\release_ts
12. Copiar o DLL para a pasta c:\php\ext (ter em atenção o PHP.INI extension_dir= c:\php\ext e extension=php_[nome da extensão].dll)
13. Restart ao Apache e fazer um phpinfo() para ver se tudo está bem.
14. Esta extensão ira ter algum lixo desnecessário que se pode limpar, como por exemplo :
a. linha 43 em php_[nome da extensão].h
b. linha 42 em [nome da extensão].c
c. linha 155-167 em [nome da extensão].c

Básico Concluído :)

PHP

O PHP ("PHP: Hypertext Preprocessor") é uma linguagem de programação que foi originalmente pensada para criação de conteúdos dinâmicos em páginas Web.
Trata-se de uma linguagem interpretada no lado do servidor (Server-Side) que pode ser utilizada acendendo ao mesmo remotamente, por linha de comandos (CLI) ou como aplicação gráfica independente (GTK+).

Esta linguagem é constituída internamente por 5 partes:

TSRM (Thread Safe Resource Management) – esta irá ser a camada mais superficial do PHP que irá servir de interpretador e permitir a que uma instância consiga executar múltiplos pedidos sem que hajam conflitos entre eles.
SAPI (Server API) – Interface que permite a comunicação com servidores e controle do ciclo de vida dos processos.
PHP CORE – Gestão de pedidos e eventos no sistema, gestão de erros, operações simples de baixo nível e operações com ficheiros.
ZEND – Compilação, execução e gestão de memória.
EXTENSÕES – Conjunto de livrarias e funções que podem ser utilizadas pelo utilizador.


CICLO DE VIDA DO PHP

Existem 2 tipos de ciclos de arranque no PHP, o do PHP Interpreter que irá iniciar todas a variáveis e estruturas durante o funcionamento da SAPI e os pedidos ocasionais que só acontecem durante o pedido de uma página.
SAPI
Arranque:
Na primeira fase de arranque o PHP ira executar um processo chamado MINIT (inicialização de módulos), que irá declarar variáveis, definir classes e recursos, que poderão ser utilizados a qualquer momento durante todos os tipos de pedidos.
PEDIDO
Arranque:
Quando é efectuado um pedido, o PHP ira correr um método chamado RINIT (inicialização de pedido) que irá aceder a todas a extensões e poder alterar e reiniciar a tabela de símbolos.
Fim:
No fim de cada pedido irá ser executado, ou a pagina ter sido fechada, o método RSHUTDOWN irá ter a finalidade de fazer a “limpeza” da tabela de símbolos e de todos os outros recursos, não persistentes, utilizados neste pedido.

Fim:
Quando todos os pedidos estiverem concluídos o PHP irá correr em todas as extensões o método MSHUTDOWN tem como finalidade libertar todos os recursos iniciados pelo MINIT e limpar tabelas de símbolos.