Compilador Keil e variáveis

Programação C em geral

Moderadores: 51, guest2003

Compilador Keil e variáveis

Mensagempor vtrx » 07 Fev 2022 14:17

Estou tentando achar um 'bug' num projeto portado.
Compilador Keil 5 com opção C99,ja que os sources usam definição de variáveis dentro do corpo das rotinas.
Em um trecho de rotina,uma parte das variéveis esta definido assim:
Código: Selecionar todos
void ApplyDirection(TEffectState effect, int32_t force, int32_t* axes)

Esta variável recebe de retorno os argumentos:
Código: Selecionar todos
      axes[0] += (int32_t)(FfbCos(angle) * fForce);
      axes[1] += (int32_t)(FfbSin(angle) * fForce);


Minha dúvida é como a variável axes é carregada.
axes[0] representa a parte alta(dois bytes) da variavel,tipo.xxxxxxxx xxxxxxxx 00000000 00000000 ?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor andre_luis » 08 Fev 2022 19:48

Tem de ver como foi definido a variavel usada no argumento axes quando instancia a função ApplyDirection. Certamente foi declarada como um array de duas ou mais variaveis int32_t. Nesse caso axes[0] representaria o valor total carregado.
Se estiver sendo feito diferente disso (ex.: axes declarado como int16_t) não é usual misturar tipos.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Compilador Keil e variáveis

Mensagempor cfreund » 09 Fev 2022 09:18

vtrx escreveu:
Código: Selecionar todos
void ApplyDirection(TEffectState effect, int32_t force, int32_t* axes)

Esta variável recebe de retorno os argumentos:
Código: Selecionar todos
      axes[0] += (int32_t)(FfbCos(angle) * fForce);
      axes[1] += (int32_t)(FfbSin(angle) * fForce);


Minha dúvida é como a variável axes é carregada.
axes[0] representa a parte alta(dois bytes) da variavel,tipo.xxxxxxxx xxxxxxxx 00000000 00000000 ?


axes aponta para uma variável de 32bits. Se você está passando um vetor int32_t de pelo menos 2 posições na chamada da função, tá tudo certo.

Vai acontecer o seguinte:

Suponhamos que a variável int32_t myAxes[2] está no endereço de memória 0x1000 e que se trata de um microcontrolador de 32bit:

Você chama ApplyDirection(effet, force, myAxes);

A função ApplyDirection vai modificar o conteúdo do endereço 0x1000 e 0x1001. axes[0] vai apontar para 0x1000 e axes[1] vai apontar para 0x1001.

---------------------------------

Se, myAxes, em vez de int32_t, for definida como int16_t e tiver apenas duas posições, teu BUG está aí - se for int16_t myAxes[4] tá tudo certo. ApplyDirection vai continuar modificando 0x1000 e 0x1001 e cagando pro que você fez lá na chamada.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Compilador Keil e variáveis

Mensagempor vtrx » 09 Fev 2022 23:22

Obrigado a vcs.
To fazendo com calma.
Mandei um email para um dos autores do projeto,que é do final de 2016,e ele me retornou que não chegou a terminar completamente a versão em C,mas me orientou a verificar uma versão final em C#.
Se para mim é longo ler o código em C++,imagine em C#.
O principal trecho a analisar é este relacionado a esta rotina.
Mais uma;
int16_t p_axis[2] = {0,0};,deve guardar dois valores entre 0 e 255,seria eixo X e eixo Y.
Vejam se a definição esta correta.
p_axis[0] = 255
p_axis[1] = 127
Isso carrega a parte alta e a parte baixa correto?
Esse valores são passados para a rotina abaixo:
Código: Selecionar todos
void FfbGetFeedbackValue(int16_t* axisPosition, int32_t* out)
{
   int32_t x_y_force[2] = {0,0};
...etc

A função é chamada assim:
FfbGetFeedbackValue(&p_axis[0],forces_data);
Como faço para passar os dois bytes(p_axis[0] e [1]) para a função?
Do modo que fiz acho que só vai uma parte,o compilador não aceita somente p_axis

PS:aproveitando,se a variável for int16_t ,o compilador aceitará que eu carregue a parte alta com um valor entre 0 e 255 e a parte baixa com 0 ou 255 ou seguirá a regra de um numero negativo?
Caso negativo,deixarei p_axis como sem sinal e extrairei a parte alta e baixa separadamente.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor cfreund » 12 Fev 2022 17:26

Código abaixo deve imprimir "12345678".

Código: Selecionar todos
#include <stdio.h>
#include <stdint.h>

void FfbGetFeedbackValue(int16_t* axisPosition, int32_t* out)
{
    *out   = 0;
    *out   = axisPosition[0];
    *out <<= 16;
    *out  |= axisPosition[1];
}

int main()
{
    int16_t p_axis[2] = {0x1234,0x5678};
    int32_t forces_data;
   
    FfbGetFeedbackValue(p_axis, &forces_data);
   
    printf("%x", forces_data);

    return 0;
}
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Compilador Keil e variáveis

Mensagempor xultz » 14 Fev 2022 08:55

Ó, faz tempo que não programo em C, e eu nem tentei compilar o código abaixo, mas eu faria algo semelhante a isto:

Código: Selecionar todos
#include <stdio.h>
#include <stdint.h>

void FfbGetFeedbackValue(int16_t* axisPosition, int32_t* out)
{
((unsigned char *)&out)[0] = ((unsigned char *)&axisPosition[0])[0];
((unsigned char *)&out)[1] = ((unsigned char *)&axisPosition[0])[1];
((unsigned char *)&out)[2] = ((unsigned char *)&axisPosition[1])[0];
((unsigned char *)&out)[3] = ((unsigned char *)&axisPosition[1])[1];
}

int main()
{
    int16_t p_axis[2] = {0x1234,0x5678};
    int32_t forces_data;
   
    FfbGetFeedbackValue(p_axis, &forces_data);
   
    printf("%x", forces_data);

    return 0;
}
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: Compilador Keil e variáveis

Mensagempor vtrx » 15 Fev 2022 23:15

No repositório do autor ele deixou o sistema em C#.
Como uso a implementação em C# para programar o STM?
O framework USB que uso é implementado no Keil,não sei como utilizar as rotinas em C#.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor cfreund » 16 Fev 2022 08:09

C sharp não foi feito para microcontroladores. Deve ter algumas "gambiarras" intituladas microframeworks, mas sempre com ressalvas.

Esta tentando portar https://github.com/JakaSimonic/ForceFee ... re-library? Isso foi feito para computador normal. Não acredito que, mesmo tendo um framework que suporte seu STM, esse código irá funcionar.

O caminho é o que você está fazendo: aproveitando a ideia e REESCREVENDO o código calculando as limitações do seu STM. Mas tenha claro o conceito de ponteiros e alocação de memória no C. Isso é requisito básico.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Compilador Keil e variáveis

Mensagempor vtrx » 16 Fev 2022 21:09

cfreund escreveu:C sharp não foi feito para microcontroladores. Deve ter algumas "gambiarras" intituladas microframeworks, mas sempre com ressalvas.

Esta tentando portar https://github.com/JakaSimonic/ForceFee ... re-library? Isso foi feito para computador normal. Não acredito que, mesmo tendo um framework que suporte seu STM, esse código irá funcionar.

O caminho é o que você está fazendo: aproveitando a ideia e REESCREVENDO o código calculando as limitações do seu STM. Mas tenha claro o conceito de ponteiros e alocação de memória no C. Isso é requisito básico.

O repositório é esse,o código é funcional usando Keil e o STM,mas contem erros de calculo.
O autor me indicou a usar como refrencia a implementação em C#:https://github.com/JakaSimonic/VjoyWrapper
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor cfreund » 16 Fev 2022 22:46

Keil compilando código escrito em C#?
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Compilador Keil e variáveis

Mensagempor vtrx » 18 Fev 2022 11:42

cfreund escreveu:Keil compilando código escrito em C#?

Não,o Keil compila o exemplo em C,que roda com erros de calculo,que não afeta o teste final.
A parte em C#,foi o autor do código em C que me indicou a verificar para tentar corrigir o código em C.
Não mandei mais email para ele porque ele pensa que é um projeto comercial e porque também não tenho tanto conhecimento para ficar incomodando ele com perguntas 'repetitivas'.
Mas voltando,consegui portar 90% do código que foi escrito em C++(Arduino) para O keil em C puro,mas estou apanhando em utilizar structs que estão nos Headers,dependendo do trecho o compilador indica 'duplicidade' na refrencia.
Á noite vou montar um questionamento para ver se me ajudam a solucionar a utilização e inicialização destas struct que estão no arquivo .h original,não movi de lugar.
Se alguém também souber C++ utilizado no Arduino,tenho duas rotinas que não sei como transcrever para C,uma inicia com ~ao lado do nome da rotina.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor vtrx » 18 Fev 2022 22:01

Estou apanhando aqui.
1-Inicar valores de um struct.
No inicio de um arquivo header existem duas struct definidas assim:
Código: Selecionar todos
struct Gains{
  uint8_t totalGain         ;
   uint8_t constantGain      ;
   uint8_t rampGain          ;
   uint8_t squareGain        ;
   uint8_t sineGain          ;
   uint8_t triangleGain      ;
   uint8_t sawtoothdownGain  ;
   uint8_t sawtoothupGain    ;
   uint8_t springGain        ;
   uint8_t damperGain        ;
   uint8_t inertiaGain       ;
   uint8_t frictionGain      ;
   uint8_t customGain        ;
};

struct EffectParams{
    int32_t springMaxPosition               ;
    int32_t springPosition                  ;

    int32_t damperMaxVelocity             ;
    int32_t damperVelocity                   ;

    int32_t inertiaMaxAcceleration       ;
    int32_t inertiaAcceleration          ;

    int32_t frictionMaxPositionChange ;
    int32_t frictionPositionChange      ;
};

   //force feedback gain
   struct Gains* m_gains;

   //force feedback effect params
   struct EffectParams* m_effect_params;


No código em C++,os elementos são iniciado diretamente.
Código: Selecionar todos
struct Gains{
    uint8_t totalGain         = FORCE_FEEDBACK_MAXGAIN;
   uint8_t constantGain      = FORCE_FEEDBACK_MAXGAIN;
   uint8_t rampGain          = FORCE_FEEDBACK_MAXGAIN;
   uint8_t squareGain        = FORCE_FEEDBACK_MAXGAIN;
   uint8_t sineGain          = FORCE_FEEDBACK_MAXGAIN;
   uint8_t triangleGain      = FORCE_FEEDBACK_MAXGAIN;
   uint8_t sawtoothdownGain  = FORCE_FEEDBACK_MAXGAIN;
   uint8_t sawtoothupGain    = FORCE_FEEDBACK_MAXGAIN;
   uint8_t springGain        = FORCE_FEEDBACK_MAXGAIN;
   uint8_t damperGain        = FORCE_FEEDBACK_MAXGAIN;
   uint8_t inertiaGain       = FORCE_FEEDBACK_MAXGAIN;
   uint8_t frictionGain      = FORCE_FEEDBACK_MAXGAIN;
   uint8_t customGain        = FORCE_FEEDBACK_MAXGAIN;
};

struct EffectParams{
    int32_t springMaxPosition = 0;
    int32_t springPosition = 0;

    int32_t damperMaxVelocity = 0;
    int32_t damperVelocity = 0;

    int32_t inertiaMaxAcceleration = 0;
    int32_t inertiaAcceleration = 0;

    int32_t frictionMaxPositionChange = 0;
    int32_t frictionPositionChange = 0;
};

Não consigo iniciar no keil,toda tentativa apresenta um erro.
Preciso acessar estas duas struct no Main,mas se eu incluir o header onde elas estão,o compilador apresenta erro de duplicidade entre o Main e outro arquivo .c que precisa de outras structs que o header tem.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: Compilador Keil e variáveis

Mensagempor cfreund » 19 Fev 2022 21:26

Monte o header dessa forma:
Código: Selecionar todos
#ifndef _STRUCTS_FILE_H_
#define _STRUCTS_FILE_H_

typedef struct
{
   uint8_t totalGain         ;
   uint8_t constantGain      ;
   uint8_t rampGain          ;
   uint8_t squareGain        ;
   uint8_t sineGain          ;
   uint8_t triangleGain      ;
   uint8_t sawtoothdownGain  ;
   uint8_t sawtoothupGain    ;
   uint8_t springGain        ;
   uint8_t damperGain        ;
   uint8_t inertiaGain       ;
   uint8_t frictionGain      ;
   uint8_t customGain        ;
} GAINS;

typedef struct
{
   int32_t springMaxPosition         ;
   int32_t springPosition            ;

   int32_t damperMaxVelocity         ;
   int32_t damperVelocity            ;

   int32_t inertiaMaxAcceleration    ;
   int32_t inertiaAcceleration       ;

   int32_t frictionMaxPositionChange ;
   int32_t frictionPositionChange    ;
} EffectParams;

//force feedback gain
GAINS *m_gains;

//force feedback effect params
EffectParams *m_effect_params;

#endif


No arquivo .c:
Código: Selecionar todos
#include structs_file.h

GAINS Gains =
{
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN,
    FORCE_FEEDBACK_MAXGAIN
};

void main()
{

}
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Compilador Keil e variáveis

Mensagempor vtrx » 20 Fev 2022 11:27

Valeu cfreund,mas ficou muito difícil continuar tentando seguir como C++ like.
Peguei todas as rotinas do arquivo.c e mais a estrutura que ele usava e coloquei tudo no main.
Pelo menos ficou tudo resolvido.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01


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

Quem está online

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

x