正确使用memcpy

时间:2016-06-03 07:46:19

标签: c++ arrays memcpy


我对我正在做的项目有一些问题。
基本上我只是以错误的方式使用memcpy。我知道指针/数组/引用的理论,应该知道如何做到这一点,但我现在花了两天没有任何进展。

我尝试给出一个简短的代码概述,也许有人看到了错误!我会非常感激。

设置:我使用ATSAM3x微控制器和uC进行信号采集。我通过SPI接收数据。

每当uC有可用数据时,我都有一个中断接收数据。然后将数据存储在缓冲区(int32_t buffer [1024或2048])中。有一个计数器从0到缓冲区大小-1计数,并确定存储数据点的位置。目前,我收到了uC内部生成的测试信号  

//ch1: receive 24 bit data in 8 bit chunks -> store in an int32_t
ch1=ch1|(SPI.transfer(PIN_CS, 0x00, SPI_CONTINUE)<<24)>>8; 
ch1=ch1|(SPI.transfer(PIN_CS, 0x00, SPI_CONTINUE)<<16)>>8;
ch1=ch1|(SPI.transfer(PIN_CS, 0x00, SPI_CONTINUE)<<8)>>8;

if(Not Important){
_ch1Buffer[_ch1SampleCount] = ch1;   
_ch1SampleCount++;
if(_ch1SampleCount>SAMPLE_BUFFER_SIZE-1) _ch1SampleCount=0;
}

此ISR始终处于活动状态。由于我需要用于信号处理的原始数据,并且只要有新的数据点,ISR就会更改缓冲区,我想将缓冲区的一部分复制到临时的“存储”中。 />

为此,我有另一个全局计数器,它在ISR内递增。在主循环中,每当计数器达到一定大小时,我调用一个方法获取一些缓冲数据(约30个样本)。

该方法获取缓冲区中的当前位置:

'int ch1Pos = _ch1SampleCount;'

然后,根据该位置,我尝试使用memcpy来获取样本。根据缓冲区中的位置,必须有一个&#34;环绕&#34;获得全套样本:

    if(ch1Pos>=(RAW_BLOCK_SIZE-1)){
        memcpy(&ch1[0],&_ch1Buffer[ch1Pos-(RAW_BLOCK_SIZE-1)] , RAW_BLOCK_SIZE*sizeof(int32_t));        
    }else{
        memcpy(&ch1[RAW_BLOCK_SIZE-1 - ch1Pos],&_ch1Buffer[0],(ch1Pos)*sizeof(int32_t));
        memcpy(&ch1[0],&_ch1Buffer[SAMPLE_BUFFER_SIZE-1-(RAW_BLOCK_SIZE-  ch1Pos)],(RAW_BLOCK_SIZE-ch1Pos)*sizeof(int32_t));          
    }
  • _ch1Buffer是包含原始数据的缓冲区
    • SAMPLE_BUFFER_SIZE是该缓冲区的大小
  • ch1是应该保存样本集的数组
    • RAW_BLOCK_SIZE是该数组的大小
  • ch1Pos是调用此方法时从ISR写入缓冲区的最后一个数据点的位置


从技术上讲,我意识到了这些要求,但显然这还不够;-)。

我知道,SPI接口收到的数据是&#34;正确&#34;。问题是,提取的样本不是这种情况。数据中有很多尖峰表明我已经阅读了一些我不应该阅读的内容。

我经常更改memcpy命令,我完全失去了概述。上面的代码示例是许多版本的一个版本,当您阅读本文时,我确定我已经更改了所有内容。

我很感激每一个提示!

谢谢&amp;问候!

修改
我已经在一张纸上写下了所有内容(并再次)并测试了一些星座。这是memcpy部分的更新代码:

        if(ch1Pos>=(RAW_BLOCK_SIZE-1)){
        memcpy(&ch1[0],&_ch1Buffer[ch1Pos-(RAW_BLOCK_SIZE-1)] , RAW_BLOCK_SIZE*sizeof(int32_t));
    }else{
        memcpy(&ch1[RAW_BLOCK_SIZE-1-ch1Pos],&_ch1Buffer[0],(ch1Pos+1)*sizeof(int32_t));
        memcpy(&ch1[0],&_ch1Buffer[SAMPLE_BUFFER_SIZE-(RAW_BLOCK_SIZE-1-ch1Pos)],(RAW_BLOCK_SIZE-1-ch1Pos)*sizeof(int32_t));
    }
}

这已经使它变得更好了。从所有的变化,一切都搞砸了。现在只有一个错误。
有一个周期性的峰值。我会尝试获取更多信息,但我认为这是一个错误的访问,而环绕。 我已将if(_ch1SampleCount>SAMPLE_BUFFER_SIZE-1) _ch1SampleCount=0;更改为if(_ch1SampleCount>=SAMPLE_BUFFER_SIZE) _ch1SampleCount=0;

编辑II 回答@David Schwartz的问题:

  • SPI.transfer返回单个字节
  • 缓冲区在启动时初始化一次:memset(_ch1Buffer,0,sizeof(int32_t)*SAMPLE_BUFFER_SIZE);

编辑III
很抱歉经常更新,评论部分变得太大了。 我设法通过减少ch1Pos来消除流的开头的一堆零值:&#39; int ch1Pos = _ch1SampleCount;&#39;

现在只有一个周期性的&#34;尖峰&#34; (错误的价值)。它必须是splitted memcpy命令。我会继续寻找。如果有人有想法......: - )

0 个答案:

没有答案