Interface: SysModManager Arquivos: sysmodmanager.h Última atualização: 15/04/2004 Autor: Luiz Henrique Shigunov |
Descrição Configuração Estruturas |
Funções para o sistema | |
0x00 - Broadcast - Chama uma função de todos os módulos que implementam uma interface 0x02 - DebugMsg - Imprime uma mensagem de debug 0x01 - DelModInfo - Retira dados armazenados na estrutura do módulo 0x05 - GetFunction - Obtém uma função dinamicamente 0x07 - GetFunctionInfoIndex - Obtém informações sobre uma função 0x0c - GetImpID - Obtém o identificador de uma implementação 0x0d - GetImpInfo - Obtém informações sobre uma implementação 0x0e - GetImpInfoIndex - Obtém informações sobre uma implementação 0x13 - GetInterID - Obtém o identificador de uma interface 0x0f - GetInterInfo - Obtém informações sobre uma interface |
0x10 - GetInterInfoIndex - Obtém informações sobre uma interface 0x06 - GetModInfo - Obtém dados armazenados na estrutura do módulo 0x11 - GetModuleInfo - Obtém informações sobre um módulo 0x12 - GetModuleInfoIndex - Obtém informações sobre um módulo 0x03 - PutImpID - Libera o identificador de uma implementação 0x08 - Register - Registra um módulo 0x09 - SetModInfo - Guarda dados na estrutura do módulo 0x0a - StartModule - Inicia um módulo 0x0b - Unregister - Retira do registro um módulo |
Funções para o usuário | |
0x04 - UGetFunctionInfoIndex - Obtém informações sobre uma função 0x14 - UGetImpInfoIndex - Obtém informações sobre uma implementação 0x15 - UGetInterID - Obtém o identificador de uma interface 0x16 - UGetInterInfo - Obtém informações sobre uma interface |
0x17 - UGetInterInfoIndex - Obtém informações sobre uma interface 0x18 - UGetModuleInfo - Obtém informações sobre um módulo 0x19 - UGetModuleInfoIndex - Obtém informações sobre um módulo |
Esta página descreve a interface SysModManager que centraliza tudo que for relacionado com os módulos do sistema: registro, carregamento, iniciação, interfaces, implementações e funções de uma interface, etc.
As interfaces e suas implementações possuem nomes e é através desses nomes que um módulo diz que quer utilizar esta ou aquela interface/implementação. Esses nomes só podem conter caracteres da tabela ASCII, ou seja, nada de acentos, ç, etc.
A escolha por nomes e não números foi porque isso dificulta a ocorrência de conflitos e torna desnecessário o cadastramento de números de interfaces e implementações como ocorre, por exemplo, com os números dos dispositivos PCI que têm que ser cadastrados para não ocorrer conflito.
Já as funções das interfaces são utilizadas pelos seus números já que não existe o risco de conflitos e os módulos que as utilizam devem saber os seus números mesmo.
Todos os nomes de interfaces e implementações ficam disponíveis num registro que é utilizado sempre que uma interface/implementação é requisitada para ser usada e é por isso que os módulos devem ser registrados: para disponibilizar para os outros módulos as suas implementações.
Cada módulo tem que implementar uma ou mais interfaces, sendo que cada interface pode ter mais de uma implementação no mesmo módulo. Ou seja, um módulo pode ter, por exemplo, duas implementações da interface AVLTree_In: Implementacao1 e Implementacao2.
Cada função de uma interface pode ser do usuário ou do sistema. Funções do usuário são acessíveis somente por módulos do usuário e funções do sistema somente por módulos do sistema. Essa diferença existe porque normalmente as funções do usuário fazem várias verificações que não são precisas quando são chamadas por módulos do sistema.
Para permitir uma maior modularidade, a iniciação de um módulo pode ser feita em duas fases: fase 0 e fase 1. Na fase 0 o processador está com as interrupções desabilitadas, já na fase 1 as interrupções estão habilitadas.
Por existirem duas fases, cada função de uma interface pode estar disponível já na fase 0 e outras somente na fase 1. Se uma função estiver disponível apenas na fase 1, ela não pode ser usada por funções que sejam usadas na fase 0 nem pela função de iniciação da fase 0.
Ambas as funções de iniciação devem ter a seguinte sintaxe:
int PhaseXStart(SysModManager_Module *modID);
Onde modID é a identificação do módulo que está sendo iniciado. Se a iniciação for bem sucedida a função deve retornar 0.
Todo módulo que não é utilizado dinamicamente, ou seja, a função GetFunction não é utilizada, deve ser iniciado pela função StartModule antes de ser usado. Como não é possível saber em qual módulo uma implementação de uma interface está, a função StartModule recebe como parâmetro um ponteiro para uma função. Esse parâmetro deve ser o ponteiro para uma função de uma implementação utilizada pelo módulo.
A iniciação desses módulos deve ser feita nas funções de iniciação porque os módulos usados pelas funções da fase 0 devem ser iniciados na fase 0 e os módulos usados pelas funções da fase 1 devem ser iniciados na fase 1, ou seja, um módulo que é usado por funções que podem ser executadas na fase 0 devem ser iniciados duas vezes.
Existem módulos que devem ser iniciados mesmo que não sejam usados por nenhum módulo. É por isso que um módulo pode ser de iniciação automática e nesse caso é iniciado na iniciação do sistema.
Antes que um módulo seja retirado da memória, a sua função de finalização, se existir, será executada. Essa função deve liberar todos os recursos usados pelo módulo e deve ter a seguinte sintaxe:
int Shutdown(void);
Se a finalização for bem sucedida, essa função tem que retornar 0.
Muitos módulos necessitam guardar informações sobre cada módulo. Um jeito seria cada módulo manter uma estrutura que relacionasse o módulo com os dados. Porém, esse método tem certos inconvenientes. Entre eles: maior quantidade de memória necessária (além dos dados precisa de uma estrutura de armazenamento e busca); tempo de acesso maior (tem que procurar na estrutura onde está a informação) e problemas de sincronizar o acesso a essa estrutura.
Pensando nisso, foi criado um mecanismo para permitir que informações de um módulo fossem guardadas na estrutura do módulo. Com isso se economiza memória, o tempo de acesso é mais rápido e o problema de sincronizar o acesso fica minimizado.
São oferecidas várias funções para inserir, retirar, atualizar ou obter essas informações armazenadas no módulo.
Algumas vezes é necessário informar os módulos que algo aconteceu ou vai acontecer. Por exemplo: que a memória física do sistema está chegando ao fim, que um módulo foi retirado da memória, que uma tarefa foi destruída, etc.
De posse dessa informação, os módulos poderiam agir de acordo (liberar memória de cache, fechar os arquivos abertos, etc).
Para implementar essa idéia, a função Broadcast foi criada. Essa função tem características interessantes entre elas: quem envia a mensagem não sabe para quem a mensagem vai; quem recebe não sabe de quem vem; quem recebe não precisa se registrar. Essas características tornam essa função melhor que o registro de cada módulo para receber informações.
typedef struct { unsigned int code; int prop; unsigned int words; } SysModManager_FunctionInfo;
Onde code é o início do código da função.
prop pode ser:
words é a quantidade de palavras de 4 bytes que a função recebe se for função do usuário.
typedef struct { SysModManager_Imp *imp; SysModManager_Module *module; SysModManager_Interface *interface; char *name; } SysModManager_ImpInfo;
Onde imp é o identificador da implementação, module é o identificador do módulo que contém a implementação, interface é o identificador da interface implementada e name o nome da implementação.
typedef struct { SysModManager_Interface *interface; unsigned int nFunctions; char *name; } SysModManager_InterInfo;
Onde interface é o identificador da interface, nFunction é o número de funções existentes na interface e name o nome da interface.
typedef struct { SysModManager_Module *module; int prop; unsigned int memStart; unsigned int memSize; unsigned int refCounter; char *path; unsigned int phase0Function; unsigned int phase1Function; unsigned int shutdownFunction; char md5[16]; } SysModManager_ModuleInfo;
Onde module é o identificador do módulo e prop pode ser:
memStart e memSize é o início e o tamanho da memória utilizada pelo módulo (código e dados iniciados e não iniciados). Será zero se não estiver carregado.
refCounter é o contador de utilização do módulo.
path é o caminho até o arquivo do módulo.
phase0Function, phase1Function e shutdownFunction são as funções de iniciação da fase 0 e fase 1 e de término. Será zero se não existir.
Esta interface define os seguintes grupos e chaves disponíveis através da interface CfgManager:
/system/SysModManager/modules | ||
Os módulos do sistema registrados permanentemente ficam neste grupo. Cada módulo tem um grupo dentro desse grupo que tem as seguintes chaves:
As propriedades do módulo devem ser 0x0 ou a soma de:
Alguns exemplos:
Grupo /system/SysModManager/modules/cfgmanager, chaves:
|
Estas funções são de uso exclusivo dos módulos do sistema.
void SysModManager_Broadcast(const char *interface, unsigned int function, void *param1, void *param2);
Esta função chama a função function com os parâmetros param1 e param2 de todos os módulos que já estejam iniciados e que implementem a interface interface.
param1 e param2 são opcionais, ou seja, podem ser NULL.
void SysModManager_DebugMsg(const char *format, ...);
Esta função mostra a mensagem format no dispositivo de erro, atualmente o dispositivo que implementar a interface TextVideo.
format e os demais parâmetros são formatados com a função PrintFArgs da interface StringMan.
O tamanho da mensagem final não pode ultrapassar 1024 bytes.
void *SysModManager_DelModInfo(SysModManager_Module *module, SysModManager_Module *which);
Esta função retira os dados do módulo which da estrutura do módulo module.
Os dados armazenados ou NULL em caso de erro.
void *SysModManager_GetFunction(SysModManager_Imp *imp, unsigned int function, int prop, int *words);
Esta função é a responsável pela ligação dinâmica. Ela obtém o ponteiro para a função function da implementação imp.
O ponteiro para a função pode ser usando enquanto imp não for liberada com PutImpID.
prop tem o seguinte formato:
Em caso de sucesso e se function for do usuário, words, se for diferente de NULL, terá o número de palavras de 4 bytes que devem ser copiadas da pilha do usuário para a pilha do sistema.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
int SysModManager_GetFunctionInfoIndex(SysModManager_Imp *imp, unsigned int index, SysModManager_FunctionInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre a função index da implementação imp.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
SysModManager_Imp *SysModManager_GetImpID(const char *interface, const char *imp);
Esta função obtém o identificador da implementação imp da interface interface.
Enquanto a implementação não for liberada pela função PutImpID ela pode ser usada. Para cada chamada para GetImpID, uma para PutImpID deve ser feita.
interface não pode ser NULL.
Já imp pode ser NULL e, nesse caso, a primeira implementação será usada.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
int SysModManager_GetImpInfo(SysModManager_Imp *imp, SysModManager_ImpInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre a implementação imp.
A implementação imp tem que ter sido obtida via GetImpID.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_GetImpInfoIndex(SysModManager_Interface *interface, unsigned int index, SysModManager_ImpInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre a implementação index da interface interface.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
SysModManager_Interface *SysModManager_GetInterID(const char *interface);
Esta função obtém o identificador da interface interface.
interface não pode ser NULL.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
int SysModManager_GetInterInfo(SysModManager_Interface *interface, SysModManager_InterInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre a interface interface.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_GetInterInfoIndex(unsigned int index, SysModManager_InterInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre a interface index.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
void *SysModManager_GetModInfo(SysModManager_Module *module, SysModManager_Module *which);
Esta função obtém o ponteiro para os dados do módulo which da estrutura do módulo module.
O ponteiro para os dados ou NULL em caso de erro.
int SysModManager_GetModuleInfo(SysModManager_Module *module, SysModManager_ModuleInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre o módulo module.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_GetModuleInfoIndex(unsigned int index, SysModManager_ModuleInfo *info, void *data, unsigned int size);
Esta função obtém informações sobre o módulo index.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_PutImpID(SysModManager_Imp *imp);
Esta função libera o identificador da implementação imp.
Para cada chamada para GetImpID, uma para PutImpID deve ser feita.
int SysModManager_Register(const char *path, int prop);
Esta função registra o módulo path.
prop tem o seguinte formato:
int SysModManager_SetModInfo(SysModManager_Module *module, SysModManager_Module *which, void *info, int prop, void **prev);
Esta função guarda os dados info do módulo which na estrutura do módulo module.
prop diz o que fazer no caso de já existirem dados armazenados:
Se o módulo which já tiver dados na estrutura do módulo e prop for 0, os dados serão substituídos e prev vai apontar para os dados antigos.
int SysModManager_StartModule(unsigned int function);
Esta função inicia o módulo que implementa a função function se ele não estiver iniciado.
Por exemplo, para iniciar o módulo da função IOPortManager_Alloc se faz:
StartModule((unsigned int)IOPortManager_Alloc);
int SysModManager_Unregister(const char *path, int prop);
Esta função retira do registro o módulo path. Somente módulos que não estejam em uso podem ser retirados do registro.
prop tem o seguinte formato:
Estas funções são de uso exclusivo dos módulos do usuário.
int SysModManager_UGetFunctionInfoIndex(SysModManager_Imp *imp, unsigned int index, SysModManager_FunctionInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre a função index da implementação imp.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_UGetImpInfoIndex(SysModManager_Interface *interface, unsigned int index, SysModManager_ImpInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre a implementação index da interface interface.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
SysModManager_Interface *SysModManager_UGetInterID(const char *interface);
Do usuário.
Esta função obtém o identificador da interface interface.
interface não pode ser NULL.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
int SysModManager_UGetInterInfo(SysModManager_Interface *interface, SysModManager_InterInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre a interface interface.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_UGetInterInfoIndex(unsigned int index, SysModManager_InterInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre a interface index.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_UGetModuleInfo(SysModManager_Module *module, SysModManager_ModuleInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre o módulo module.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.
int SysModManager_UGetModuleInfoIndex(unsigned int index, SysModManager_ModuleInfo *info, void *data, unsigned int size);
Do usuário.
Esta função obtém informações sobre o módulo index.
index começa em zero e deve ser incrementado a cada chamada da função.
Os campos de tamanho variável (como o nome, por exemplo) são armazenados em data que tem o tamanho size. Não mais do que size bytes serão armazenados em data.
Em caso de sucesso, info conterá as informações.