Volcar memoria flash a través de un solo pin GPIO

5

Estoy trabajando con el kit de relajación XMC4500 de Infineon y estoy tratando de extraer el firmware a través de un único pin GPIO.

Mi idea muy ingenua es volcar un bit a la vez a través del pin GPIO y de alguna manera "rastrear" los datos con un analizador lógico.

Pseudocódigo:

while(word by word memory copy hasn't finished)
  ...
  register = value;
  temp_value = value AND 0x1;
  pin = temp_value;
  value = value >> 1;
  ...

¿Estoy en el camino correcto? ¿Alguien tiene una mejor idea de cómo archivar esto?

### EDITAR ###

En realidad, un requisito de mi código (shell) sería que debe ser realmente pequeño. Encontré este truco ingenioso sobre cómo volcar el firmware parpadeando los LED.

Sin embargo, estoy luchando para recibir los valores correctos con Saleae Logic Analyzer.

Básicamente, lo que estoy haciendo es:

  1. Configure las direcciones de los pines GPIO para la salida
  2. Blink LED1 (pin 1.1) con un reloj (reloj serial SPI)
  3. Blink LED2 (pin 1.0) con bits de datos (SPI MOSI)
  4. Olfatear pines con un analizador lógico

Aquí está mi código C:

#include "XMC4500.h"

#define DEL 1260

void init() 
{
  // P1.0 output, push pull
  PORT1->IOCR0 = 0x80UL << 0;
  // P1.1 output, push pull
  PORT1->IOCR0 |= 0x80UL << 8;
}

void delay(int i) { 
  while(--i) { 
    asm("nop\n"); 
    asm("nop\n"); 
  } 
}

// Sets a pin to high
// P1.0 = SPI MOSI
// P1.1 = SPI CLOCK
void output_high(int i) {
  // P1.0 high
  if(i == 0) {
    PORT1->OUT |= 0x1UL;  
  }

  // P1.1 high
  if(i == 1) {
    PORT1->OUT |= 0x2UL;
  } 
}

// Sets a pin to low
// P1.0 = SPI MOSI
// P1.1 = SPI CLOCK
void output_low(int i) {
  // P1.0 low
  if(i == 0) {
    PORT1->OUT &= (~0x1UL);
  }

  // P1.1 low
  if(i == 1) {
    PORT1->OUT &= (~0x2UL);
  }
}

// SPI bit banging
void spi_send_byte(unsigned char data)
{
  int i;

  // Send bits 7..0
  for (i = 0; i < 8; i++)
  {
    // Sets P1.1 to low (serial clock)
    output_low(1);

    // Consider leftmost bit
    // Set line high if bit is 1, low if bit is 0
    if (data & 0x80)
      // Sets P1.0 to high (MOSI)
      output_high(0);
    else
      // Sets P1.0 to low (MOSI)
      output_low(0);

    delay(DEL);

    // Sets P1.1 to high (Serial Clock)
    output_high(1);

    // Shift byte left so next bit will be leftmost
    data <<= 1;
  }
}

int main() {
  init();

  while(1) {
    spi_send_byte('t');
    spi_send_byte('e');
    spi_send_byte('s');
    spi_send_byte('t');
  }

  return 0;
}

### 2nd EDIT ###

Finalmente lo resolvió. La memoria flash de descarga funciona bien con el siguiente código:

#include "XMC4500.h"

// SPI bit banging
void spi_send_word(uint32_t data)
{
  int i;

  // LSB first, 32 bits per transfer
  for (i = 0; i < 32; i++)
  {
    // set pin 1.1 to low (SPI clock)
    PORT1->OUT &= (~0x2UL);

    // set line high if bit is 1, low if bit is 0
    if (data & 0x1) {
      // set pin 1.0 to high (SPI MOSI)
      PORT1->OUT |= 0x1UL;
    }
    else {
      // set pin 1.0 to low (SPI MOSI)
      PORT1->OUT &= (~0x1UL);   
    }

    // set pin 1.1 to high (SPI clock)
    PORT1->OUT |= 0x2UL;

    data >>= 1;
  }
}

int main() {
  // start dumping at memory address 0x08000000
  unsigned int *p;
  p = (uint32_t *)(0x08000000u);

  // configure pin 1.0 and pin 1.1 as output (push-pull)
  PORT1->IOCR0 = 0x8080UL;

  while(1) {
    spi_send_word(*p);
    p++;
  }
}
    
pregunta user3696425

3 respuestas

6

El mayor problema que veo con su plan actual es que las series largas de 0 o 1 (múltiples bytes de 0x00 o oxFF) serán difíciles de diferenciar. Aquí hay algunas otras ideas para tener en cuenta.

UART TX con bits modificados

No es terriblemente difícil golpear una línea UART TX. Elija una velocidad en baudios más lenta que divida fácilmente el reloj de su sistema. Seguirá transmitiendo bytes de manera similar a su ejemplo de código, solo con un retardo establecido entre cada bit y un inicio inicial y un bit de parada final para cada byte. Esto tiene la ventaja de poder conectarse directamente a una computadora para recibir todos los datos. Alternativamente, los analizadores lógicos más nuevos generalmente pueden decodificar la transmisión directamente en bytes sin que usted necesite hacer nada a mano.

UNI/O

Microchip tiene un esquema de comunicación de una sola línea llamado UNI / O. Se ejecuta en un rango de velocidades de reloj donde el maestro básicamente cambia la línea a una velocidad determinada unas cuantas veces y luego toda la comunicación tiene lugar a esa velocidad.

Un valor de bit se transmite entonces por el flanco ascendente o descendente que tiene lugar en la mitad del período de reloj. Una transición alta a baja sería un bit cero y una transición baja a alta sería un bit. Puede leer más sobre UNI / O aquí

    
respondido por el Zack
3

Observe las diversas formas en que los datos se pueden transmitir a través de una sola línea (o canal). El problema básico es la temporización: ¿cómo sabe el receptor dónde está el límite entre dos bits? Algunas soluciones simples para este problema son (hay muchas más):

  • asíncrono (también conocido como arranque-parada NRZ, también conocido como UART, a veces - de forma incorrecta - llamado RS232): envíe solo un número limitado de bits en un trozo, separe los trozos por inicio + bits de parada
  • NRZI: codifica cada bit como un cambio o no cambio de la señal en el centro de la celda de bits
  • manchester: codifique cada bit como un borde de bajo a alto o de alto a bajo en el centro de la celda de bits
  • longitud del pulso: codifique 1 y 0 como pulsos de diferente longitud
respondido por el Wouter van Ooijen
2

Si tiene o compra un Bus Pirate , tendrá una amplia gama de protocolos para elegir, de los cuales debería ser más fácil obtener Obtenga datos de su analizador lógico típico. Hay otras respuestas en el protocolo y el bus pirata es compatible con los protocolos de 1 cable, pero si puede obtener un segundo GPIO, SPI podría ser bueno ya que va bastante rápido, puede golpear el procesador y con un pirata del bus, no tiene que preocuparse tanto por hacer coincidir los niveles lógicos de voltaje vs intentar alinear RS232. Aparte de eso, la documentación de piratas de bus y la comunidad de hardware abierto es bastante extensa en cuanto a la configuración.

    
respondido por el Digikata

Lea otras preguntas en las etiquetas