我正在尝试编写尽可能小的代码来提取英飞凌XMC4500微控制器的固件。
该代码必须适合到一个30字节的缓冲区,使我有15个机器指令使用拇指16位指令集。
从C开始,我尝试通过一个GPIO引脚(see original question)来转储闪存,下面是这个漂亮的技巧。
基本上我在做的是:
1.设置GPIO引脚输出方向
- LED1(引脚1.1) Flink ,带有时钟(SPI串行时钟)
- Flink LED2(引脚1.0),带数据位(SPI MOSI)
1.用逻辑分析仪嗅探引脚
编辑:
1.更新C代码块
1.添加装配代码块
#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)
但是代码的大小仍然太大,无法满足我的要求。
有什么我可以做的来进一步缩减我的代码吗?有什么可以优化或省略的吗?
2条答案
按热度按时间gab6jxml1#
如果Port1的高位在此过程中没有改变,并且您可以确保在时钟变为高电平后稍微读取数据位,则可以尝试以下操作:
这将删除三个端口读取、一个端口写入和一个条件。
在一个函数中完成所有这些以避免任何调用开销。我将从为此生成的程序集开始,看看您可以做些什么来改进它。
6gpjuf902#
16条指令并不多我不期望C编译器能够产生足够有效的代码来进行内存转储。如果你对输出位模式不太挑剔,我认为32字节就足够了,使用如下代码:
每个字节将作为高脉冲输出,随后是8个可能为高或低的位时间(取决于数据读取),随后是始终为零的位时间,以确保下一个高脉冲的上升沿可见。基本上类似于异步串行通信,但电平相反。