Estoy tratando de escribir el código más pequeño posible para extraer el firmware de microcontrolador XMC4500 de Infineon .
El código debe caber en un búfer de bytes 30 que me permite tener 15 instrucciones de la máquina usando el conjunto de instrucciones del pulgar de 16 bits.
Comenzando con C, mi intento es volcar la memoria flash a través de un solo pin GPIO (vea la pregunta original) siguiendo este truco ingenioso.
Básicamente, lo que estoy haciendo es:
- Configure las direcciones de los pines GPIO para la salida
- Blink LED1 (pin 1.1) con un reloj (reloj serial SPI)
- Blink LED2 (pin 1.0) con bits de datos (SPI MOSI)
- Olfatear pines con un analizador lógico
EDIT:
- ACTUALIZAR BLOQUE DE CÓDIGO C
- AGREGAR EL BLOQUE DEL CÓDIGO DE ASAMBLEA
#include "XMC4500.h"
void main() {
// start dumping at memory address 0x00000000
unsigned int* p = (uint32_t *)(0x0u);
// configure port1 output (push-pull)
PORT1->IOCR0 = 0x8080u;
for(;;) {
int i = 32;
int data = *(p++);
do {
// clock low
PORT1->OUT = 0x0;
// clock high with data bits
PORT1->OUT = 0x2u | data;
data >>= 1;
} while (--i > 0);
}
}
main:
; PORT1->IOCR0 = 0x8080UL
ldr r1, =0x48028100 ; load port1 base address to R1
movw r2, #0x8080 ; move 0x8080 to R2
str r2, [r1, #0x10]
main_1:
; start copying at address 0x00000000
; R12 is known to be zeroed
ldr.w r2, [r12], #0x4 ; int data = *(p++)
movs r3, #32 ; int i = 32
main_2:
; PORT1->OUT = 0x0
; clock low
; R12 is known to be zeroed
str r12, [r1]
; PORT1->OUT = 0x2 | data
; clock high with data bits
orr r4, r2, #0x2
str r4, [r1]
asrs r2, r2, #0x1 ; data >>= 1
subs r3, r3, #0x1 ; i--
bne.n main_2 ; while (--i > 0)
b.n main_1 ; while(true)
Sin embargo, el tamaño del código sigue siendo demasiado grande para cumplir mis requisitos.
¿Hay algo que pueda hacer para reducir aún más mi código? ¿Algo que pueda optimizarse o dejarse fuera?