Análise de abstração : um belo desafio..

Programação C em geral

Moderadores: 51, guest2003

Mensagempor jeanfernandes » 20 Dez 2008 17:24

Eu fiz um primeiro approach de uma coisa que to montando (para fins de estudo mermo)....

ainda nao ta como o assunto que estamos falando, mas pelo menos ja eh um passo acima do "pé de chinelo"...

fifo-001.c

eu queria fazer
(void *) foo (int task, void *msg)
para devolver qq coisa

mas nao consegui ainda

(atualizando...)
fiz em bar...
parece estranho mais num é
tava dando cagada pois dentro de bar
as variaveis de retorno tem que ser do tipo static
se nao nao vira....

Degrau pra cima...


:lol:

Mas tamo no caminho....
Pelo menos ja encapsulou....
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor msamsoniuk » 22 Dez 2008 13:33

uma coisa que vc pode fazer eh usar um union para eliminar a necessidade de ponteiros no caso de dados simples:

Código: Selecionar todos
typedef union
{
  unsigned char  b;
  unsigned short w;
  unsigned long  l;
  void          *p;
}
super;

super foo(char method, super msg)
{
  static struct *rtc = NULL;
  static struct r;
  static char flag;
  static super ret;
  static unsigned count;

  switch(method)
  {
    case GET_FLAG:
      ret.b = flag;
      break;
    case SET_FLAG;
      flag = msg.b;
    case GET_COUNT:
      ret.l = count;
    case SET_COUNT:
      count = msg.l;
      break;
    case GET_RTC:
      ret.p = rtc;
      break;
  }
  return ret;
}


alguma coisa assim (eu nao testei). dae vc nao precisa passar ponteiros no caso de tipos curtos, pode usar eles diretamente e isso agiliza um pouco as coisas.

vc pode pensar como uma regra de otimizacao: se dos dados tem comprimento menor ou igual ao comprimento de um ponteiro, eh mais rapido copiar os dados diretamente. se eles tem comprimento variavel ou sao maiores que um ponteiro, eh mais lucro copiar apenas o ponteiro.

bom, se vc for analisar, o seu esquema eh um equivalente sincrono a mensagens via stack, ao inves de via queue! eu ia implementar desta forma, mas os mcus pequenos possuem stack meio limitada :)
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor jeanfernandes » 23 Dez 2008 19:42

É em tese funciona tb....
mas fica mais dependente de ter mensagens locais....

fabim

Eu só acho que fica mais oneroso de passar uma estrutura do tipo st_msg que em tese ocupa 4 bytes (por conta do u32) la...
e o fato de voce passar 4 bytes SEMPRE ai nao faz diferenca.

Ficou a duvida nessa questao.
Se é uma union e voce faz um cast antes de passar o parametro ...ganha alguma coisa em termos de alocacao de recurso na stack ?

tipo

st_msg coisa;

funcao (task, (u08) coisa)
funcao (task, coisa)


Cambio...
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor msamsoniuk » 23 Dez 2008 23:02

acho que a diferenca eh apenas performance... veja que a diferenca eh entre:

foo(void *bar)
{
dead = bar->beef;
}

e

foo(super bar)
{
dead = bar.beef;
}

no primeiro caso, eh empilhado na stack um ponteiro base e entao feita uma operacao tipo:

[sp]->bar_register
[bar_register+beef_offset]->dead_register (de acordo com size de beef)

no segundo caso:

[sp]->bar_register
bar_register->dead_register (de acordo com size de beef)

ou seja, no primeiro caso vc tem na stack o endereco de onde o operando alvo esta e depois precisa de um acesso adicional para buscar ele. no segundo caso vc tem na stack o proprio operando.

tem vantagens e desvantagens: o primeiro processo eh por referencia, entao vc referencia o operando diretamente. no segundo caso eh por copia, entao vc referencia apenas uma copia do operando.

no primeiro caso vc pode fazer:

foo(void *bar)
{
bar->beef = dead;
}

no segundo caso nao.

vantagens e desvantagens, analisando assim mais profundamente acho que passar o ponteiro eh realmente mais flexivel, mas pode depender do caso neh.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor jeanfernandes » 26 Dez 2008 20:46

Corrigido !... as maneiras que tentei estavam certas, era uma escrita no registro Write Protec, depois de fazer o burst na RAM do DS1302 ...eheheheheh eu coloquei o microcosmo corrigido lá embaixo...mas depois tem um codigo do write protect que omiti, aqui, mas ficou joinha eheheheh

Duvidazinhas que tao me tirando o sono.
ipc

Código: Selecionar todos
typedef union
{
  struct stb {
    u08 h;
    u08 l;
  } nb;
  u08   b;
  u16   w;
  void *p;
} un_ipc;



Um dos construtores que to testando....

Código: Selecionar todos
typedef union
{
  struct st_ds1302 {
    u08 e;  // error state
    u08 s;  // second
    u08 n;  // minute
    u08 h;  // hour
    u08 d;  // day
    u08 m;  // month
    u08 w;  // day of week
    u08 y;  // year
  } resource;
  u08 buffer[DS1302_DATA_SIZE];
} un_ds1302;


E a funcao....

Código: Selecionar todos
void
ds1302(u08 task, un_ipc *msg)
{
  static un_ds1302  device;

  u08 count;
  u08 frame;
  u08 value;

  switch (task)
  {
     ....
  }

}



Vejamos duas funcoes
un_ipc *msg;

ds1302(DS1302_CLK_INIT, msg);

nessa ae acima ....
eu inicializo device e depois retorno

msg->p = &device;

ok ? foi que eu fiz...atribui o endereco de device ao ponteiro p
da mensagem.

ds1302(DS1302_CLK_WRITE, msg);

bom como msg->p ja aponta para device la dentro
uma solucao de pegar o valor via ponteiro eh fazer o que ?

value = ((u08 *)msg->p)[count];

por exemplo, se count = 5, eu estaria em tese fazendo value = device.buffer[5], ou device.resource.m ok ?

Pois eh ......essa xit num ta virando...e olhe que ja mandei printar valor na serial (e ta printando certo) eheheheheheh tem alguma coisa errada ae ?

veja o snipe code no microcosmo do codigo

Código: Selecionar todos
      ((u08 *)msg->p)++; // increment to point to first byte (ignoring device.resource.e)
      for (frame = DS1302_CLK_SIZE_RTC;frame;frame--)
      {
        // bin2bcd
        value = *((u08 *)msg->p);
        value = ((value/10)<<4) + (value%10);
        ((u08 *)msg->p)++;
        for (count = DS1302_BITS_BLOCK;count;count--)
        {
          DS1302_SCL_OFF;
          DS1302_SDA_PIN = value & 0x01;
          DS1302_SCL_ON;
          value >>=1;
        }
      }

Editado pela última vez por jeanfernandes em 27 Dez 2008 01:35, em um total de 1 vez.
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor msamsoniuk » 26 Dez 2008 23:12

bom, se:

msg->p = &device;

entao vc pode tentar:

value = (un_ds1302 *)msg->p)->resource.m;

deveria funcionar... se funcionar eh pq na verdade a forma que vc fez deve estar desalinhada em funcao de um problema de justificacao no union.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor jeanfernandes » 27 Dez 2008 08:44

#define RTC_GET_TIME(x) ds1302(DS1302_CLK_READ, x)
#define RTC_SET_TIME(x) ds1302(DS1302_CLK_WRITE, x)
#define RTC(y,x) *((u08 *)(y.ptr) + x)

ehehehehe

agora ta ficando mais legível...

Código: Selecionar todos
  for(;;)
  {
    P1_0 = OFF;
    RTC_GET_TIME(&msg);
    P1_0 = ON;
    cmsc51_uart_send_byte(RTC(msg,RTC_HOUR));
    cmsc51_uart_send_byte(RTC(msg,RTC_MIN));
    cmsc51_uart_send_byte(RTC(msg,RTC_SEC));
    cmsc51_uart_send_byte(RTC(msg,RTC_DAY));
    cmsc51_uart_send_byte(RTC(msg,RTC_MONTH));
    cmsc51_uart_send_byte(RTC(msg,RTC_YEAR));
    cmsc51_uart_send_byte(RTC(msg,RTC_DOW));
    cmsc51_uart_send_byte('\n');

    cmsc51_delayms(1000);
  }

Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Anterior

Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x