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.

求助啊,C6748 ,main函数调用子文件时,出现一个很奇怪的问题



我使用的是带SYS/BIOS的工程,含有两个TASK,现在出现一个很奇怪的问题

1、我在main.c中,调用一个计算旋转因子的函数void gen_twiddle_fft_sp (float *w, int n)(供给以后的FFT使用),这个函数的定义我放在了calculate.c的子文件          中,而且debug时,可以看到这个函数可以运行通过,但是之后,程序却无法进入两个task之中。

2、去掉这个函数之后,一切正常,可以进入两个TASK,甚至当函数内容为空时(内容注释掉),也可以进入接下来的两个TASK

3、当这个函数的定义直接放在main.c时(不放在calculate.c中),即使这个函数的定义有内容,程序也能进入两个TASK。

4、我检查了这个函数的声明,确实是extern型,甚至它的实参,我也设置成了extern型,但是只要它被定义到calculate.c的子文件中,同时它的内容不为空时,程       序就无法进入接下来的TASK,当函数内容为空时,又能进入两个TASK了

请问,这个是怎么回事啊?

main.c中也包含了fft_calculate.h文件,同时也定义了变量w_sp,和WN,这里没有列出,总之,语法应该没有问题。不知道问题究竟出在哪里?

  • 你的函数gen_twiddle_fft_sp (float *w, int n)把程序搞挂了呗,栈设的不够大吧。不要把问题想复杂了,没有什么trick的事情。

  • 这里有好几个栈,

    这里是我的关于几个堆栈的设置

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x200000;

    task0Params.stackSize = 204800;

    task1Params.stackSize = 204800;

    之前发生过栈溢出的问题,现在上面这几个栈我感觉设置的已经不小了,难道 还有那个栈我没有设置么?

  • 你就在BIOS_start处打断点,然后看前面函数运行后对W数组的访问有没有越界。

    这里还没进任务,跟任务stack无关。

  • 不好意思,不太理解越界是啥意思,对W数组的访问有没有越界?没弄明白。。

  • 你这个函数里不就是对*W进行运算操作的么。意思是说假如W长度是100,你运算之中里有没有访问到100外头去了。

     gen_twiddle_fft_sp (float *w, int n)

    很简单,你把这个函数换成别的函数看有没有问题,就知道是不是这个函数有问题了。

  • Tony Tang 说:

    你这个函数里不就是对*W进行运算操作的么。意思是说假如W长度是100,你运算之中里有没有访问到100外头去了。

     gen_twiddle_fft_sp (float *w, int n)

    很简单,你把这个函数换成别的函数看有没有问题,就知道是不是这个函数有问题了。

    我现在开始感觉,也许原因可能不是出在这个函数身上,因为没有这个函数,程序有时也进不去后面的任务了,有时可以,有时不可以。

    现在我对这里的栈有一些困惑,特别是如何设置栈的大小;

    下面是转载的关于堆和栈一个解释:

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 
    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
    
    

    C6748这里面,好象有两种栈:

    一个Program.stack,还有一种taskParams.stackSize

    1、我的程序里面除了代码,占用空间最多的就是全局变量,Program.stack和taskParams.stackSize跟全局变量的数量没有关系吧?
    2、而我在每个任务(共两个)里面定义的一些变量,都只占用了很少的字节,这个应该算在各自的task stacksize里面吧?
    3、每个任务里面都使用了前面定义的很多全局变量,我想这个应该不会额外的增加各自的task stacksize吧?
    4、即使每个任务task的代码再多,调用再多的函数,只要没有很多的变量(不算全局变量),所用的栈的大小都不会显著增加吧?
    
    
    这里好像只有一种堆:BIOS.heapSize
    5、这个heap应该不区分任务task,HWI和swi,是大家共用的吧?
    6、像手动malloc和new分配的才会放到这里面?
    
    
    以上的这些,有点儿迷茫这个栈的大小应该如何分配,还请指点?非常非常感谢!
  • 你理解的都对。全局变量在.bss或.far段跟stack没关系。

    你的程序是跑在DDR上还是片上内存?是不是内存不稳定。都放到片上内存能跑不。

  • Tony Tang 说:

    你理解的都对。全局变量在.bss或.far段跟stack没关系。

    你的程序是跑在DDR上还是片上内存?是不是内存不稳定。都放到片上内存能跑不。

    是跑在DDR上面的。

    现在我怀疑是不是全局变量设的太多了,估计都有几十K了,我想问下,这个全局变量最多能搞多少个?

  • baokun hu 说:
    现在我怀疑是不是全局变量设的太多了,估计都有几十K了,我想问下,这个全局变量最多能搞多少个?

    不用当心这个,bss段最大为32KB,不是所有全局变量都放在BSS的,数组之类的是放在.far段的,而且超出范围编译器会报错的

  • Tony Tang 说:

    现在我怀疑是不是全局变量设的太多了,估计都有几十K了,我想问下,这个全局变量最多能搞多少个?

    不用当心这个,bss段最大为32KB,不是所有全局变量都放在BSS的,数组之类的是放在.far段的,而且超出范围编译器会报错的

    [/quote]原因好像找到了,我设置了定时器,定时器周期为5us,自动模式,BIOS_start()之后,应该是先启动了定时器,然后接下来的两个任务就不知道怎么出问题了,这也验证了上面说的,有时任务可以进去运行,有时就不行(起初我还以为是gen_twiddle_fft_sp函数的问题)。我把这个定时器屏蔽掉之后就好了,但是这个定时器是必须要用的,而它现在却好像影响了我任务的调度。

    1、定时器工作会让任务无法进入?原因是啥,难道是周期太短?

    2、这个定时器还必须用,我该怎么办?

  • 麻烦把你的程序流程介绍清楚好吗,你前面提供的截图里哪有配置timer,配置中断的代码?

    问问题就把问题说清楚,而不是说自己怎么做的都没有问题,那么就是这个东西是有问题的。

    就如你上面说的定时器,你这么问难道是说BIOS不能用定时器吗?

    首先你要明白一定是你配置上出了问题。那么请你把你怎么配的,在哪里配的说清楚。

  • 嗯,不好意思,是我的错,我之前也一直没有想到这个会是定时器的问题,所以就没贴出定时器的配置,之前在CFG文件中定时器的配置,StartMode_AUTO模式

    现在定时器运行改成了StarMode_USER

    然后在进入任务后,才开启定时器

    然后问题好像就解决了(起码到目前为止一直还没出毛病),现在任务可以运行,同时定时器也可以工作。

    我现在也不明白为什么在CFG文件中(或者BIOS吧)不能配置定时器为自动模式,这样会影响TASK的调度?

  • 收回上面说的,虽然任务进去了,定时器有时还是会影响任务运行,我先想想,先不用回答

    程序的结构

    while(1)

    {

         FFT();

         Printf();

    }

    反复执行FFT,然后反复打印FFT的结果,如果没有定时器,Console会不停打印结果

    有了定时器中断,Console打印一会儿,说不定循环多少次,就不往console输出打印信息了,我想可能是定时器把Task打乱了,定时器执行完,TASK可能回不来了

  • Tony Tang 说:

    麻烦把你的程序流程介绍清楚好吗,你前面提供的截图里哪有配置timer,配置中断的代码

    问问题就把问题说清楚,而不是说自己怎么做的都没有问题,那么就是这个东西是有问题的。

    就如你上面说的定时器,你这么问难道是说BIOS不能用定时器吗?

    首先你要明白一定是你配置上出了问题。那么请你把你怎么配的,在哪里配的说清楚。

    Tony Tang

    你说的很有道理,我没把问题说清楚,也没有把问题的原因贴出来(主要也是没找到问题出在哪了),坑到你了。这次,我根据你说的可能情况,又前后思考了一番,终于找到原因了。不是最初怀疑的堆栈问题,也不是后来怀疑的定时器问题,而是我的定时器中断服务程序出了了问题

    现在定时器CFG文件重新改回StartMode_AUTO模式,也没问题。

    问题错在我在中断服务里面操作了一个GPIO的句柄。

    gpio0是定义在main.c文件中的一个Gpio_Handle类型,全局变量。

    Gpio_Handle     gpio0;

    int  main()

    {

    **************

    **************

    /* open the GPIO driver to get a handle to it */
    gpio0 = Gpio_open(&gpioParams);

    **************

    **************

    }

    在main中拿到了GPIO的handle,同时在Timer.c文件的中断服务程序Timer2Isr中进行了引用,然后就出现了问题。

    其实我就想在定时器服务程序里面干一件事,就是打开GPIO bank0的中断,于是引用了函数Gpio_bankInterruptEnable(gpio0,GPIO_BANK0)

    现在看来不能这样搞,那么改成直接操作寄存器就没问题了。

    所以,为什么在定时器服务程序里面不能这样做,有什么说法么?

  • 定时器 中断 周期 5uS 即便是 主频 500MHz

    5uS 能 容纳下 多少条 指令 呢 ??是否够?