This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6000的线性汇编函数,在C文件中调用有什么限制吗?

我用C语言写了一个IIR 高通滤波器:

void iir_2nd_filter(int *d_x, int *d_y, int *x, int *y,
                int factor1, int factor2, int ch_offset, int step, int nbytes)
{
    int i;
//    y[i]         = (x[i] - x[i-1])
//                 - (x[i-1] - x[i-2])
//                 + y[i-1]
//                 + ((y[i-1]>>10)*factor1 - (y[i-2]>>10)*factor2);
    y[ch_offset] = (x[ch_offset] - d_x[1])
                 - (d_x[1] - d_x[0])
                 + d_y[1]
                 +((d_y[1]>>10)*factor1 - (d_y[0]>>10)*factor2);
    y[step + ch_offset] = (x[step + ch_offset] - x[ch_offset])
                 - (x[ch_offset] - d_x[1])
                 + y[ch_offset]
                 +((y[ch_offset]>>10)*factor1 - (d_y[1]>>10)*factor2);
    nbytes = nbytes/4;

    for(i=step*2+ch_offset;  i<nbytes;  i+=step) {
        y[i] = (x[i] - x[i-step])
             - (x[i-step] - x[i-(step<<1)])
             + y[i-step]
             + ((y[i-step]>>10)*factor1 - (y[i-(step<<1)]>>10)*factor2);
    }
    d_x[0] = x[i-(step<<1)];
    d_x[1] = x[i-step];

    d_y[0] = y[i-(step<<1)];
    d_y[1] = y[i-step];
}

又用线性汇编写了一个功能相同的函数:

;extern void iir_2nd_Assembly(int *d_x, int *d_y, int *x, int *y,
;                			  int factor1, int factor2, int ch_offset, int step, int nbytes);
    .global		iir_2nd_Assembly

;二阶IIR高通滤波器
iir_2nd_Assembly:	.cproc d_x, d_y, x, y, factor1, factor2, ch_offset, step, nbytes  ;线性汇编程序开始
; 变量声明
	.reg	xn,xn1,xn2,yn,yn1
	.reg	sum,tmp1,tmp2

	SHL		ch_offset, 2, ch_offset	;ch_offset = ch_offset*4
	SHL		step, 2, step			;step = step*4

	LDW		*d_x++, xn	;xn  = x[n]
	LDW		*d_x, xn1	;xn1 = x[n+1]
	LDW		*d_y++, yn	;yn  = y[n]
	LDW		*d_y, yn1	;yn1 = y[n+1]

	ADD		x, ch_offset, x	;
	LDW		*x, xn2		;xn2 = x[n+2]

	SUB		xn2, xn1, tmp1		;tmp1 = xn2 - xn1
	SUB		xn1, xn, tmp2		;tmp2 = xn1 - xn
	SUB		tmp1, tmp2, sum		;sum = tmp1 - tmp2	= (xn2-xn1) - (xn1-xn)
	ADD		sum, yn1, sum		;sum = (xn2-xn1) - (xn1-xn) + yn1

	SHR		yn1, 10, tmp1		;tmp1 = yn1>>10
	MPY32	tmp1, factor1, tmp1	;tmp1 = factor1*tmp1 = (yn1>>10)*factor1

	SHR		yn, 10, tmp2		;tmp2 = yn>>10
	MPY32	tmp2, factor2, tmp2	;tmp2 = factor2*tmp2 = (yn>>10)*factor2
	MV		yn1,  yn			;yn = yn1

	SUB		tmp1, tmp2, tmp1	;tmp1 = tmp1 - tmp2	= (yn1>>10)*factor1 - (yn>>10)*factor2
	ADD		sum, tmp1, yn1		;yn1 = sum + tmp1   = (xn2-xn1) - (xn1-xn) + yn1
								;					 + ((yn1>>10)*factor1 - (yn>>10)*factor2)

	ADD		y, ch_offset, y
	STW		yn1, *y				;y[n+2] = yn1

	MV		xn1,  xn	;xn  = x[n+1]
	MV		xn2,  xn1	;xn1 = x[n+2]

	SHR		nbytes, 2, nbytes		;nbytes = nbytes/4
 [nbytes] SUB nbytes, 1, nbytes 	;nbytes -= 1

LOOP3:	.trip	1		;for循环起始位置
	ADD		x, step, x
	LDW		*x, xn2		;xn2 = x[n+2]

	SUB		xn2, xn1, tmp1		;tmp1 = xn2 - xn1
	SUB		xn1, xn, tmp2		;tmp2 = xn1 - xn
	SUB		tmp1, tmp2, sum		;sum = tmp1 - tmp2	= (xn2-xn1) - (xn1-xn)
	ADD		sum, yn1, sum		;sum = (xn2-xn1) - (xn1-xn) + yn1

	SHR		yn1, 10, tmp1		;tmp1 = yn1>>10
	MPY32	tmp1, factor1, tmp1	;tmp1 = factor1*tmp1 = (yn1>>10)*factor1

	SHR		yn, 10, tmp2		;tmp2 = yn>>10
	MPY32	tmp2, factor2, tmp2	;tmp2 = factor2*tmp2 = (yn>>10)*factor2
	MV		yn1,  yn			;yn = yn1

	SUB		tmp1, tmp2, tmp1	;tmp1 = tmp1 - tmp2	= (yn1>>10)*factor1 - (yn>>10)*factor2
	ADD		sum, tmp1, yn1		;yn1 = sum + tmp1   = (xn2-xn1) - (xn1-xn) + yn1
								;					 + ((yn1>>10)*factor1 - (yn>>10)*factor2)

	ADD		y, step, y
	STW		yn1, *y				;y[n+2] = yn1

	MV		xn1,  xn	;xn  = x[n+1]
	MV		xn2,  xn1	;xn1 = x[n+2]

 [nbytes] SUB nbytes, 1, nbytes 	; nbytes -= 1
 [nbytes] B LOOP3 					; if (nbytes!=0) goto loop ;for循环结束位置

	STW		xn1, *d_x--
	STW		xn,  *d_x
	STW		yn1, *d_y--
	STW		yn,  *d_y

    .endproc											; 线性汇编程序结束

C文件中的测试函数如下:

#define Tn  1024

// IIR 输入
int IIR_In[Tn+4];
// IIR 输出
int IIR_Out[Tn+4];

// IIR 输入延迟
int delay_x[2] = {0,0};
// IIR 输出延迟
int delay_y[2] = {0,0};

extern void iir_2nd_Assembly(int *d_x, int *d_y, int *x, int *y,
                             int factor1, int factor2, int ch_offset, int step, int nbytes);

int iir_lowcut_test(void)
{
    unsigned int bytes_read = 0, bytes_writed = 0;
    int res = FR_OK;

    res = f_open(&rec_file_ch1,"FileIn.wav", FA_READ);
    res |= f_lseek(&rec_file_ch1, 44); //文件指针指向第一个音频数据的位置

    if (FR_OK != res) {
        return res;
    }

    res |= rec_wav_file_create("FileOut.wav", &rec_file_ch2, 48000, 32, 1);

    if (FR_OK != res) {
        return res;
    }
    while(!f_eof(&rec_file_ch1)) {

        res = f_read(&rec_file_ch1, IIR_In, Tn*4, &bytes_read);
#if 1
        iir_2nd_filter(delay_x, delay_y, IIR_In, IIR_Out, 967, 969, 0, 1, Tn*4);
#else
        iir_2nd_Assembly(delay_x, delay_y, IIR_In, IIR_Out, 967, 969, 0, 1, Tn*4);
#endif
        res |= f_write(&rec_file_ch2, IIR_Out, Tn*4, &bytes_writed);
        if (FR_OK != res) {
            break;
        }
    }
    f_close(&rec_file_ch1);
    rec_wav_file_close(&rec_file_ch2);
    return res;
}

注:FileIn.wav是一个单声道音频文件,采样参数为48k/32bit。

967和969是二阶IIR高通滤波器参数,对应Fs=48kHz,Fs=300Hz。

测试函数iir_lowcut_test()对iir_2nd_filter()和iir_2nd_Assembly()的调用结果相同。

但是,我在产品程序的SWI中调用iir_2nd_Assembly()则出现异常,而调用iir_2nd_filter()没有问题。

我的问题是,线性汇编函数,在C文件中调用有什么限制吗?