完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好!我的CAN中断处理程序功能太慢,我必须优化它。CAN缓冲区在DMA RAM中,因为它应该是这样,所以DMA不会锁定SRAM。问题是:编译器生成一个很长的代码,我在其中将DMA ram(它是_u eds_space的一部分)复制到普通数据空间。(PIC24EP512GP806,Windows7,MpalabX 3.30,XC16 1.26)。本评论的最后是关键部分的拆卸:20个asm指令长循环,循环14次,用于将7个单词从ram复制到ram。那太疯狂了。我用XC16 1.26编译。优化级别1加上我试着添加附加的moptimize-page设置选项,也尝试了XC16 1.25。我试过各种变通方法,但是生成的代码长度相应地保持不变。我确信这可以用更短的代码完成,但我不想编写内联程序集。我能用C代码缩短这个拷贝吗?在这个例子中,我展示了CAN发送函数,但是我对CAN接收函数.typedef结构{unsigned int DmaBuf[7];}DMA_BUF;...unsigned int CAN_SendMsg(...)有同样的问题。,u eds_unsigned int*pDmaBuff)//u eds_unsigned int*pDmaBuff:指向DMA读取的CAN发送缓冲区,{volatile DMA_BUF DmaBufOnStack;//我在堆栈上的正常SRAM中构建消息,因此我可以单独处理_u eds_问题...(构建消息)...373: *(u eds_BufOnStack;)。DMA_BUF*)pDmaBuff = DmaBufpDmaBufpDmaBufOnStack;00A692EB0000CLRW000A000000000000000000A694 370013BRA0XA6A6B694646464646464646464646464646464646464646464646464646464646464646464646464646464646464646464646BRLSRW0,#15,W500500A698W500A6988888888888888780200MOVW0 W0,#15,W500500A69W500A698W500A698W500A69878020008W500A6987802000000000000000000000000042 BSET SR,#100A6A4 498285 ADDC W3,W5,W500A6A6 A90042BCLR SR,000A6A8AE2042BTSS SR,000A6A8AE2042BTSS SR,100A6AAA80042BSETSR,100A6A6A6AAAAAAAAAAA800A800A800AAA80040042BSETSR,100A6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6,[W4]00A6B8 8801A1MOV W1,DSWPAG00A6BA E80000 INC W0,W000A6BC 500FEE亚W0,α0xE,[W15] 900A6BE 39 FFEBB文胸NC,0xA696…}
以上来自于百度翻译 以下为原文 Hi! My CAN interrupt handler function is too slow, and I have to optimize it. The CAN buffer is in the DMA ram, as it should be, so the DMA won't lock the SRAM ever. The issue is: the compiler generates a very long code where I copy from the DMA ram (which is part of the __eds__ space) to the normal data space. (PIC24EP512GP806, windows7, MpalabX 3.30, XC16 1.26 ). The end of this comment is the disassembly for the critical part: 20 asm instruction long loop, looped 14 times for copying 7 words from ram to ram. That's crazy. I compile with XC16 1.26. Optimization level1 plus I tried adding additionally -moptimize-page-setting option and I tried XC16 1.25 also. I tried various workarounds, but the generated code length relevantly remained the same. I am sure this can be done with shorter code, but I don't want to write in-line assembly. Can I make this copy shorter with C only code? In this example I show the CAN send function, but I have the same issue with the CAN receive function. typedef struct { unsigned int DmaBuf[ 7 ]; }DMA_BUF; ... unsigned int CAN_SendMsg( ... , __eds__ unsigned int *pDmaBuff ) //__eds__ unsigned int *pDmaBuff: points to the CAN sending buffer, which the DMA reads from. { volatile DMA_BUF DmaBufOnStack; //I build up the message in normal SRAM on the stack, so I can handle the __eds__ issue separately ... (building the message) ... 373: *(__eds__ DMA_BUF * )pDmaBuff = DmaBufOnStack; 00A692 EB0000 CLR W0 00A694 370013 BRA 0xA6BC 00A696 DE02CF LSR W0, #15, W5 00A698 780200 MOV W0, W4 00A69A A1F004 BCLR W4, #15 00A69C D00082 SL W2, W1 00A69E D00304 SL W4, W6 00A6A0 408206 ADD W1, W6, W4 00A6A2 A82042 BSET SR, #1 00A6A4 498285 ADDC W3, W5, W5 00A6A6 A90042 BCLR SR, #0 00A6A8 AE2042 BTSS SR, #1 00A6AA A80042 BSET SR, #0 00A6AC D38204 RRC W4, W4 00A6AE 5000EE SUB W0, #0xE, W1 00A6B0 78C36F MOV.B [W15+W1], W6 00A6B2 8001A1 MOV DSWPAG, W1 00A6B4 8801A5 MOV W5, DSWPAG 00A6B6 784A06 MOV.B W6, [W4] 00A6B8 8801A1 MOV W1, DSWPAG 00A6BA E80000 INC W0, W0 00A6BC 500FEE SUB W0, #0xE, [W15] 00A6BE 39FFEB BRA NC, 0xA696 ... } |
|
相关推荐
6个回答
|
|
|
|
|
|
尝试使用指针而不是移动数据。在某些时候,我必须将数据放入CAN DMA缓冲区,这不能用指针完成,并且在Tx中断之前也不能完成。
以上来自于百度翻译 以下为原文 >>Try using pointers instead of moving the data. At some point I have to put the data to the CAN DMA buffer, that can't be done with pointers and that can't be done before the Tx interrupt. |
|
|
|
最简单的方法是直接在缓冲区中构建消息。否则,您可以编写汇编代码来进行复制。通过“重复”指令,它被复制了两行代码和OnECU PyCurPrWord。
以上来自于百度翻译 以下为原文 The easiest way is to build the message directly in the buffer. Otherwise, you can write an assembler code to do the copying. With the "repeat" instruction, it's two lines of code and one CPU cycle per word copied. |
|
|
|
如果我直接构建到缓冲区,而不是消息编译编译成一个非常长的代码。也许我会做汇编代码,但如果任何人只有C的解决方案,比请张贴它!
以上来自于百度翻译 以下为原文 If I build directly to the buffer than the message build compiles to a very long code. Maybe I will do the assembler code, but if anyone have a solution with only C, than please post it! |
|
|
|
对于类似的问题,我省略了前导_EDS_修饰符(它使指向符号的指针成为胖指针),并手动设置dsrpag/dswpag,这样即使优化级别很低,我也可以使用16位的指针。缓冲区的处理是相当本地的。
以上来自于百度翻译 以下为原文 For a similar issue, I left off the leading __EDS__ modifier (that makes pointers to the symbol a fat pointer), and set dsrpag/dswpag manually, so that I can work with 16-bit pointers even with low optimization levels. The handling of the buffer is fairly local though. |
|
|
|
我在汇编程序中写下了整个事情:无符号int ChansSeNMSG(…,u eds_unsigned in t*pDmaBuff){//W2:pDmaBuff static DMA_BUF DmaBufOnStatic;//我在普通SRAM中以静态方式构建消息,因此它不影响堆栈指针...asm(“push W0”);asm(“push W1”);asm(“push W3”);asm(“push W4”);asm(“push W5”);asm(“push W6”);asm(“push W7”);asm(“push W7”);asmasm(“push W8”);asm(“push W9”);asm(“push DSRPAG”);asm(“push DSRPAG”);WREG0=(U16)& DmaBufOnStatic;asm(“mov#0,W1,W1”);asm(“mov\#0,W1,W1”);asm(“mov W1 W1,W1#0,W1”);asm(“mov W1,W1,W1,W1,W1”);asm(“mov,W1,W1,W1,DSRPAG”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”+],W6”;asm(“mov[W0++],W7”);asm(“mov[W0++],W8”)asm(“mov[W0+],W9”);WREG2=(U16)pDmaBuff;asm(“mov#1,W1”);asm(“mov W1,W1,W1”);asm(“mov#1,W1”);asm(“mov#1,W1#1,W1”);asm(“mov W1 W1,W1,W1,W1 W1,DSRPAG”);asm(“nop”);asm(“nop”);asm(“mov W3,W3,[W2++]],W2+]”);asm(“mov W3,W3,W3,[W2+++]]]]”);asm(“mov W3,W3,[W2++[W2+];asm(“mov W8,[W2++]”);asm(“mov W9,[W2++]”);asm(“pop Dasm(“nop”);asm(“pop W9”);asm(“pop W8”);asm(“pop W7”);asm(“pop W6”);asm(“pop W5”);asm(“pop W4”);asm(“pop W3”);asm(“pop W1”);asm(“pop W0”);
以上来自于百度翻译 以下为原文 I wrote the whole thing in assembler: unsigned int CAN_SendMsg( ... , __eds__ unsigned int *pDmaBuff ) { //W2: pDmaBuff static DMA_BUF DmaBufOnStatic; //I build up the message in normal SRAM in static, so it don't affect the stack pointer ... asm( "push W0" ); asm( "push W1" ); asm( "push W3" ); asm( "push W4" ); asm( "push W5" ); asm( "push W6" ); asm( "push W7" ); asm( "push W8" ); asm( "push W9" ); asm( "push DSRPAG"); WREG0 = ( U16 )&DmaBufOnStatic; asm( "mov #0, W1" ); asm( "mov W1, DSRPAG" ); asm( "nop" ); asm( "mov [W0++], W3" ); asm( "mov [W0++], W4" ); asm( "mov [W0++], W5" ); asm( "mov [W0++], W6" ); asm( "mov [W0++], W7" ); asm( "mov [W0++], W8" ); asm( "mov [W0++], W9" ); WREG2 = ( U16 )pDmaBuff; asm( "mov #1, W1" ); asm( "mov W1, DSRPAG" ); asm( "nop" ); asm( "mov W3, [W2++]" ); asm( "mov W4, [W2++]" ); asm( "mov W5, [W2++]" ); asm( "mov W6, [W2++]" ); asm( "mov W7, [W2++]" ); asm( "mov W8, [W2++]" ); asm( "mov W9, [W2++]" ); asm( "pop DSRPAG"); asm( "nop" ); asm( "pop W9" ); asm( "pop W8" ); asm( "pop W7" ); asm( "pop W6" ); asm( "pop W5" ); asm( "pop W4" ); asm( "pop W3" ); asm( "pop W1" ); asm( "pop W0" ); |
|
|
|
只有小组成员才能发言,加入小组>>
5244 浏览 9 评论
2035 浏览 8 评论
1955 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3209 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2260 浏览 5 评论
779浏览 1评论
672浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
598浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
682浏览 0评论
579浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 09:21 , Processed in 1.396249 second(s), Total 88, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号