由ADS1.2中memcpy()想到的<br /><br />作者:owzq<br />邮箱:owzq@163.com<br /><br />在做NANDFLASH底层驱动时,由于数据量很大,想着把外部总线的时序再调紧凑一点,于是想到用memcpy()函数.<br />NANDFLASH写函数中用<br />#define DEV_STORE_PIPEIO ((volatile BYTE*)0x01180000)<br />memcpy( (BYTE*)DEV_STORE_PIPEIO, pbyData, dwSize );<br />当DEV_STORE_PIPEIO地址不是4字节对齐时,数据错误.<br />反汇编后发现核心是ldmcsia/stmcsia,就要4字节对齐,当不对齐的时候,就凑齐.<br />我们仔细看反汇编的代码发现前面大量的语句都是在凑对齐.<br />我们可以肯定,复制数据越多,memcpy()效率越高.如果仅仅拷贝4/8个字节,还是赋值吧.呵呵.<br />memcpy()应用于NANDFLASH这样的数据和地址不是一一对应的硬件时,要对齐.<br /><br />你可以用 <br /> ldmcsia r1!,{r3,r4,r12,r14}<br /> stmcsia r0!,{r3,r4,r12,r14}<br /> ldmcsia r1!,{r3,r4,r12,r14}<br /> stmcsia r0!,{r3,r4,r12,r14}<br />自己打造一个专用的函数.<br /><br />附录:<br />memcpy<br />__rt_memcpy <br /> cmp r2,#3<br /> bls _memcpy_lastbytes<br /> ands r12,r0,#3<br /> beq _memcpy_dest_aligned<br /> ldrb r3,[r1],#1<br /> cmp r12,#2<br /> add r2,r2,r12<br /> ldrlsb r12,[r1],#1<br /> strb r3,[r0],#1<br /> ldrccb r3,[r1],#1<br /> sub r2,r2,#4<br /> strlsb r12,[r0],#1<br /> strccb r3,[r0],#1 <br />_memcpy_dest_aligned <br /> ands r3,r1,#3<br /> beq __rt_memcpy_w<br /> subs r2,r2,#4<br /> bcc _memcpy_lastbytes<br /> ldr r12,[r1,-r3]!<br /> cmp r3,#2<br /> beq _memcpy_src2_loop<br /> bhi _memcpy_src3_loop<br /> <br />_memcpy_src1_loop <br /> mov r3,r12,lsr #8<br /> ldr r12,[r1,#4]!<br /> subs r2,r2,#4<br /> orr r3,r3,r12,lsl #24<br /> str r3,[r0],#4<br /> bcs _memcpy_src1_loop<br /> add r1,r1,#1<br /> b _memcpy_lastbytes<br /> <br />_memcpy_src2_loop <br /> mov r3,r12,lsr #16<br /> ldr r12,[r1,#4]!<br /> subs r2,r2,#4<br /> orr r3,r3,r12,lsl #16<br /> str r3,[r0],#4<br /> bcs _memcpy_src2_loop<br /> add r1,r1,#2<br /> b _memcpy_lastbytes<br /> <br />_memcpy_src3_loop <br /> mov r3,r12,lsr #24<br /> ldr r12,[r1,#4]!<br /> subs r2,r2,#4<br /> orr r3,r3,r12,lsl #8<br /> str r3,[r0],#4<br /> bcs _memcpy_src3_loop<br /> add r1,r1,#3<br /> b _memcpy_lastbytes<br /> <br />__rt_memcpy_w <br /> stmfd r13!,{r4,r14}<br /> subs r2,r2,#0x20<br /> bcc _memcpy_small<br /> <br />_memcpy_aligned_loop <br /> ldmcsia r1!,{r3,r4,r12,r14}<br /> stmcsia r0!,{r3,r4,r12,r14}<br /> ldmcsia r1!,{r3,r4,r12,r14}<br /> stmcsia r0!,{r3,r4,r12,r14}<br /> subcss r2,r2,#0x20<br /> bcs _memcpy_aligned_loop<br /> <br />_memcpy_small <br /> movs r12,r2,lsl #28<br /> ldmcsia r1!,{r3,r4,r12,r14}<br /> stmcsia r0!,{r3,r4,r12,r14}<br /> ldmmiia r1!,{r3,r4}<br /> stmmiia r0!,{r3,r4}<br /> ldmfd r13!,{r4,r14}<br /> movs r12,r2,lsl #30<br /> ldrcs r3,[r1],#4<br /> strcs r3,[r0],#4<br /> moveq pc,r14<br /> <br />_memcpy_lastbytes <br /> movs r2,r2,lsl #31<br /> ldrmib r2,[r1],#1<br /> ldrcsb r3,[r1],#1<br /> ldrcsb r12,[r1],#1<br /> strmib r2,[r0],#1<br /> strcsb r3,[r0],#1<br /> strcsb r12,[r0],#1<br /> mov pc,r14<br /> |