Consulta magia C

104 views
Skip to first unread message

Carlos Pantelides

unread,
Oct 10, 2022, 6:01:55 PM10/10/22
to Embebidos32
Hola,

tengo estos macros:

#define LEDS        *((volatile uint32_t *) 0x00010000)
#define BUTTONS     *((volatile uint32_t *) 0x00010004)

perfecto, sirve para poder leer y escribir en esas posiciones, por ejemplo, puedo hacer:

LEDS = ~BUTTONS;

Anda perfecto, siguiente, querría dado:

#define SEQUENCER   *((volatile uint32_t *) 0x00010030)

poder hacer algo así como:

uint32_t idx= 0;
SEQUENCER[idx] = 0x1;
++idx;
SEQUENCER[idx] = 0x7;
++idx;
SEQUENCER[idx] = 0x2;

pero mi conocimiento de C es en el mejor de los casos intermedio y de punteros y casting, no hace falta que diga nada...

Intenté ayudarme con https://cdecl.org/, pero no entiende.

Plan B:

Luego, pensando un poquito llegué a que esto podría funcionar:

          *((volatile uint32_t *) 0x00010030     ) = 0x3;
          *((volatile uint32_t *) 0x00010030 +  1) = 0x3;
          *((volatile uint32_t *) 0x00010030 +  2) = 0x3;
          *((volatile uint32_t *) 0x00010030 +  3) = 0x3;

pero se pierde la homogeneidad con el resto del código y queda ese número hardcodeado.

Plan C,

una variante, probablemente la mejor:

#define SEQUENCER   0x00010030

          *((volatile uint32_t *) SEQUENCER     ) = 0x3;
          *((volatile uint32_t *) SEQUENCER  +  1) = 0x3;
          *((volatile uint32_t *) SEQUENCER  +  2) = 0x3;
          *((volatile uint32_t *) SEQUENCER0 + 3) = 0x3;

.

Plan D:

Luego, pensando un poquito más, horrible, IDX es global y no hay indicación en la sintaxis de que esté recorriendo una array:

uint32_t IDX = 0;
#define SEQUENCER   *((volatile uint32_t *) 0x00010030 + IDX)

          SEQUENCER = 0x3;
          ++IDX;
          SEQUENCER = 0x7;

Los Planes B en adelante compilan, no sé si realmente funcionan pues aún no hice el hardware, pero bueno, apostemos a que sí.

Entiendo que tendría que prestar especial atención si va de uno en uno o de cuatro en cuatro, pero eso vendrá luego..


Si alguien me tirara alguna pista u opinión, le estaría muy agradecido. Debe haber un patrón para esto pero no sé qué palabras usar para buscarlo.

Estas son las variantes que he probado para el Plan A:

programs/fulldemo/../memmap.h:13:21: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
   13 | #define SEQUENCER   *((volatile uint32_t *) 0x00010030)
programs/fulldemo/main.c:234:11: note: in expansion of macro 'SEQUENCER'
  234 |           SEQUENCER[sequencer_size] = 0x1;
      |           ^~~~~~~~~
programs/fulldemo/../memmap.h:13:21: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
   13 | #define SEQUENCER   *((volatile uint32_t *) 0x00010030)
programs/fulldemo/main.c:235:12: note: in expansion of macro 'SEQUENCER'
  235 |           *SEQUENCER[sequencer_size] = 0x1;
      |            ^~~~~~~~~
programs/fulldemo/main.c:236:12: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
  236 |           (*SEQUENCER)[sequencer_size] = 0x1;
In file included from programs/fulldemo/main.c:19:
programs/fulldemo/../memmap.h:13:21: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
   13 | #define SEQUENCER   *((volatile uint32_t *) 0x00010030)
programs/fulldemo/main.c:237:11: note: in expansion of macro 'SEQUENCER'
  237 |           SEQUENCER[sequencer_size] = 0x1;
      |           ^~~~~~~~~
programs/fulldemo/main.c:238:38: error: lvalue required as left operand of assignment
  238 |           SEQUENCER + sequencer_size = 0x1;
      |                                      ^
programs/fulldemo/main.c:239:40: error: lvalue required as left operand of assignment
  239 |           (SEQUENCER + sequencer_size) = 0x1;
      |                                        ^
programs/fulldemo/main.c:240:12: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
  240 |           (*SEQUENCER + sequencer_size) = 0x1;
programs/fulldemo/main.c:241:12: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
  241 |           (*(SEQUENCER) + sequencer_size) = 0x1;
      |            ^~~~~~~~~~~~
programs/fulldemo/main.c:242:11: error: invalid type argument of unary '*' (have 'uint32_t' {aka 'long unsigned int'})
  242 |           *(SEQUENCER + sequencer_size) = 0x1;
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Gracias y saludos

Jorge Grana

unread,
Oct 10, 2022, 6:51:46 PM10/10/22
to embeb...@googlegroups.com
Carlos :

 

voy a tratar de ayudar...

cuando escribis :

LEDS = ~BUTTONS;

en realidad estás escribiendo :

   *((volatile uint32_t *) 0x00010000)  = ~   *((volatile uint32_t *) 0x00010004)

Ahora cuando escribes  :

SEQUENCER[idx] = 0x1;

Generaria esto :

 *((volatile uint32_t *) 0x00010030) [idx] = 0x1;

Lo que nunca probé y no sé si tiene algún sentido.

A las macros le podes poner parámetros :


tal ves esto te sirva para hacer lo que vos quieras.

Saludos

Jorge

--
-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es
---
Has recibido este mensaje porque estás suscrito al grupo "Embebidos32" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a embebidos32...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/embebidos32/6606c4ee-5fec-4ce5-a9a1-206f26bb9d36n%40googlegroups.com.

Catedra Electronica

unread,
Oct 10, 2022, 7:42:55 PM10/10/22
to embeb...@googlegroups.com
una alternativa para aproximarse a tu primera opción (con paréntesis en vez de corchetes) es plantearlo como macro:
#define SEQUENCER(x)   *((volatile uint32_t *) 0x00010030+x)
Luego
uint32_t idx= 0;
SEQUENCER(idx) = 0x1;
++idx;
SEQUENCER(idx) = 0x7;
++idx;
SEQUENCER(idx) = 0x2;
Saludos
Eduardo

--

Mirko Serra

unread,
Oct 10, 2022, 8:59:19 PM10/10/22
to embeb...@googlegroups.com
Sencillamente remové el * de desreferencia de SEQUENCER.

Si hacés 
#define SEQUENCER   *((volatile uint32_t *) 0x00010030)

SEQUENCER es un uint32_t. Podés asignarlo. Pero de la misma manera que 
uint32_t SEQUENCER;
SEQUENCER[0] = 1;
no funciona, no va a funcionar tu ejemplo.

En cambio:
#define SEQUENCER   ((volatile uint32_t *) 0x00010030)

SEQUENCER es ahora una variable de tipo puntero y hacer
SEQUENCER[0] = 1;
Es válido.


Saludos,
Mirko Serra.


--

Carlos Pantelides

unread,
Oct 11, 2022, 6:53:55 AM10/11/22
to Embebidos32
Excelente, muchas gracias, no bien haga funcionar la pieza aviso

Has recibido este mensaje porque estás suscrito a un tema del grupo "Embebidos32" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/embebidos32/RVP2Xm2XrFg/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a embebidos32...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/embebidos32/CAOCjbm_FyOb4U%2BUX%3DjaTcWw%3DiNT%2BF0m%3DfHOPhm_2V29Qeuas_w%40mail.gmail.com.

Carlos Pantelides

unread,
Oct 11, 2022, 8:46:02 PM10/11/22
to Embebidos32
Hola,

Confirmo que las tres formas funcionaron ok.

        *((volatile uint32_t *) SEQUENCER_BASE  + SEQUENCER_START_STOP_PORT  ) = 0x11111111;

        SEQUENCER_PARAM(SEQUENCER_SPEED_PORT) = SEQUENCER_MAX_SPEED;

        SEQUENCER_IDX[SEQUENCER_START_STOP_PORT ] = 0x00000000;



En un rato voy a tirar una moneda para usar la dos o la tres, probablemente me quede con la última.

Muchísimas gracias
Reply all
Reply to author
Forward
0 new messages