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.

[参考译文] TM4C1294NCPDT:任务可以阻止堆栈溢出,也可以毫无理由地获得堆栈溢出

Guru**** 2546490 points
Other Parts Discussed in Thread: SYSBIOS

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1075352/tm4c1294ncpdt-task-blocks-or-gets-stack-overflow-without-apparent-reason

部件号:TM4C1294NCPDT
“线程”中讨论的其它部件:SysBIOSTM4C123

你好

我的系统有几个任务,有时 是控制 ADC 转换(具有第二高优先级)的附带任务,这些任务没有任何原因。

而在其他一些情况下,报告堆栈溢出时,程序启动后 Micro 会直接进入错误处理程序。

从该问题中恢复的唯一方法是在删除所有任务代码的情况下再次构建系统,然后在还原代码的情况下再次构建系统。

通过执行此操作,代码将运行。

Semaphore_Handle Adc_sem;
void Adc_ctrl_task(UArg a0, UArg a1)
{
    Error_Block eb;
    Semaphore_Handle Adc_sem;

    Error_init(&eb);
    Adc_sem = Semaphore_create(0, NULL, &eb);

    assert(Adc_sem != NULL);

    HAL_adc_initialize();
    
    while (FOREVER())
    {
        HAL_adc_conversion_start();
        Task_sleep(1);
    }
}

我们正在使用 CCS v10.4.0.00006,

SysBIOS 6.37.3.35

XDCTOOLS 3.25.6.96

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编辑:

    ADC 中断的延迟为零,但仍在发布信号。 这会导致奇怪的行为吗? 就像任务永远阻止堆栈损坏一样?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

     我看到您创建了信号量 ADC_SEM,但我看不到它在您的任务中被使用。 通常,您会在 while 循环中插入信号灯暂停(ADC_SEM)。 它将一直阻止,直到在 ISR 中收到信号灯柱(ADC_SEM)。  

     下面是 TM4C123使用信号技术的示例,但想法相同。 LedToggle 任务在 信号灯暂停(LEDSem,BIOS_WAK_Forever)上处于挂起状态,因此一直处于阻止状态,直到计时  器生成一个中断,发出信号灯柱(LEDSem)以解除对 LedToggle 任务的阻止。  

    //----------------------------------------
    // BIOS header files
    //----------------------------------------
    #include <xdc/std.h>  						//mandatory - have to include first, for BIOS types
    #include <ti/sysbios/BIOS.h> 				//mandatory - if you call APIs like BIOS_start()
    #include <xdc/runtime/Log.h>				//needed for any Log_info() call
    #include <xdc/cfg/global.h> 				//header file for statically defined objects/handles
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/hal/Hwi.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>
    
    
    
    //------------------------------------------
    // TivaWare Header Files
    //------------------------------------------
    #include <stdint.h>
    #include <stdbool.h>
    
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "inc/hw_ints.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/timer.h"
    
    
    //----------------------------------------
    // Prototypes
    //----------------------------------------
    void hardware_init(void);
    void ledToggle(void);
    void Timer_ISR(void);
    
    
    //---------------------------------------
    // Globals
    //---------------------------------------
    volatile int16_t i16ToggleCount = 0;
    Semaphore_Handle LEDSem;
    
    
    //---------------------------------------------------------------------------
    // main()
    //---------------------------------------------------------------------------
    void main(void)
    {
    
        Task_Params TaskParams;
        Task_Handle LedToggleTask;
        Error_Block eb;
        /* Initialize error block and TaskParams to default values */
        Error_init(&eb);
        Task_Params_init(&TaskParams);
        TaskParams.stackSize = 2096;
        TaskParams.priority = 1;
        LedToggleTask = Task_create((Task_FuncPtr)ledToggle, &TaskParams, &eb);
        if (LedToggleTask == NULL) {
        System_abort("Task create failed");
        }
    
        /*
        * Create semaphore with initial count = 0 and default params
        */
        LEDSem = Semaphore_create(0, NULL, &eb);
        if (LEDSem == NULL) {
        System_abort("Semaphore create failed");
        }
    
    
       hardware_init();							// init hardware via Xware
    
       BIOS_start();
    
    }
    
    
    //---------------------------------------------------------------------------
    // hardware_init()
    //
    // inits GPIO pins for toggling the LED
    //---------------------------------------------------------------------------
    void hardware_init(void)
    {
    	uint32_t ui32Period;
    
    	//Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
    	// ADD Tiva-C GPIO setup - enables port, sets pins 1-3 (RGB) pins for output
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
    	// Turn on the LED
    	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4);
    
    	// Timer 2 setup code
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);			// enable Timer 2 periph clks
    	TimerConfigure(TIMER2_BASE, TIMER_CFG_PERIODIC);		// cfg Timer 2 mode - periodic
    
    	ui32Period = (SysCtlClockGet() /2);						// period = CPU clk div 2 (500ms)
    	TimerLoadSet(TIMER2_BASE, TIMER_A, ui32Period);			// set Timer 2 period
    
    	TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);		// enables Timer 2 to interrupt CPU
    
    	TimerEnable(TIMER2_BASE, TIMER_A);						// enable Timer 2
    
    }
    
    
    //---------------------------------------------------------------------------
    // ledToggle()
    //
    // toggles LED on Tiva-C LaunchPad
    //---------------------------------------------------------------------------
    void ledToggle(void)
    {
    
    	while(1)
    	{
    		Semaphore_pend(LEDSem, BIOS_WAIT_FOREVER);				// wait for Sem from ISR
    
    		// LED values - 2=RED, 4=BLUE, 8=GREEN
    		if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
    		{
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
    		}
    		else
    		{
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
    		}
    
    		i16ToggleCount += 1;									// keep track of #toggles
    
    		Log_info1("LED TOGGLED [%u] TIMES",i16ToggleCount);		// send toggle count to UIA
    
    	}
    
    }
    
    
    //---------------------------------------------------------------------------
    // Timer ISR - called by BIOS Hwi (see app.cfg)
    //
    // Posts Swi (or later a Semaphore) to toggle the LED
    //---------------------------------------------------------------------------
    void Timer_ISR(void)
    {
        TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT);			// must clear timer flag FROM timer
    
    	Semaphore_post(LEDSem);										// post LEDSwi
    }

    以下是 TI-RTOS 培训的链接。 https://training.ti.com/sites/default/files/docs/TI_RTOS_Kernel_Workshop_Student_Guide_rev4.00.pdf。 希望您会发现它很有用。

    另一个评论是,您似乎有一个旧的 XDCtools 和 TI-RTOS。 推荐的 TI-RTOS 版本为  2.16.00.08。您可以从 http://downloads.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/tirtos/index.html 下载。 与 TI-RTOS 版本2.16.00.08一起使用的推荐 XDCtools 是 XDCtools 版本3.32.00.06,您可以从 http://downloads.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_32_00_06/index_FDS.html 下载

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复,但这不是问题所在。

    信号灯在其他地方使用,并由 ISR 发布,该任务仅每1毫秒触发一次。

    不包括使用信号的代码。  

    关键是,任务不应永久阻止在 Task_Sleep (1)上执行。

    ISR 优先级错误可能会打乱计划程序?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    ~引用 userid="414888" url="支持/微控制器/基于 ARM 的微控制器-组/基于 ARM 的微控制器/f/基于 ARM 的微控制器-论坛/1075352/tm4c1294ncpdt-task-blocks -或 Get-stack-overflow-overflow-without -probusion-reason"],代码将运行[/quot]。

     在您的原始帖子中,您撰写了上述内容,然后是代码片段。 我认为你们展示的是工作代码。 或者,您表示该代码不能与 Task_Sleep (1)一起使用。  

    [引用 userid="414888" url="~/support/icles/arm-based 微处理器组/基于 ARM 的微控制器/f/arm-based 微控制器-forum/1075352/tm4c1294ncpdt-task-blocks 或 Get-stack-overflow-without -probus-reason/3980109#3980109"任务栏[引用任务栏],任务栏不应永久显示任务栏1 [引用任务栏]

     我同意 Task_Sleep (1)应将任务从运行状态更改为已阻止状态仅1毫秒。 您如何处理中断? 您是否使用 Hwi 管理中断? 中断必须由 TI-RTOS Hwi 管理。 否则,系统可能会挤压。 希望这不是问题的原因。 请参阅此帖子。 https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/849627/faq-can-i-update-the-vector-table-with-intregister-when-using-ti-rtos?tisearch=e2e-sitesearch&keymatch=faq%3Atrue

     对于实验,如果您将 Task_Sleep ()更改为更长时间,是否会有影响? 可能尝试 Task_Sleep (10)或 Task_Sleep (100)。

      您是否也尝试过增加任务堆栈大小? 当堆栈溢出时,ROV 会显示哪项任务?  

    [引用 userid="414888" url="~/support/icles/arm-based 微处理器组/基于 ARM 的微控制器/f/arm-based 微控制器-forum/1075352/tm4c1294ncpdt-task-blocks 或 Get-stack-overflow-without -probus-reason/3980109#3980109"[引用错误的 ISR]计划程序来说明优先级?]

    Hwi 的优先级始终高于 Swi 和 THEN 任务。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    显示的代码有时会永久阻塞或似乎会产生堆栈溢出。

    中断是通过 Hwi 管理的,但据我了解,在 ARM 上,低于32的优先级会使其零延迟,因此不受操作系统控制。

    堆栈大小已翻了一番,翻了四番,但有时问题会不时再次出现。


    将 ISR 优先级从1提高到100 似乎已解决了问题,但我想确保这可能是自一开始就出现的问题: 不在操作系统控制下的 ISR 会破坏计划程序。
    情况可能是这样吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    [引用 userid="414888" url="~/support/icles/arm-based 微处理器组/基于 ARM 的微控制器/f/arm-based 微控制器-forum/1075352/tm4c1294ncpdt-task-blocks 或 latit-gost-stack-overflow-without 明显原因/3980194#3980194”命令,但不受 Hwi32的控制,因此不能通过其在任何中断控制下[以零/wi32的方式管理]。

    我 不是 TI-RTOS 专家,老实说,优先级32将使其零延迟对我来说是新的。 我不知道您如何创建零延迟中断。 下面是我在 TI-RTOS 培训中找到的内容以及我在前面的回复中发送的链接。  

    从 TI-RTOS 配置看,我发现 Hwi-disable()的优先级如下:32。 我不知道我们是否在谈论同样的事情。  

     我还发现以下关于零延迟的陈述。 零延迟中断不受操作系统控制,这是正确的。  

    CC13x0的 HWi 模块还支持 零延迟中断这些中断不会通过 TI-RTOS Hwi 调度程序,因此响应速度比标准中断快,但此功能禁止其中断服务例程直接调用任何 TI-RTOS 内核 API。 ISR 应保留自己的上下文,以防止其干扰内核的调度程序。