Porting FreeRTOS on F28M35x (Cortex m3), the program flies after instruction svc # 0

I am a college student and a beginner in operating system porting. This problem has been bothering me for a long time, and I cannot find a solution before seeking your help. Thank you all!

 My environment is CCS
FreeRTOSConfig.h have these lines:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

the priority of the SVC exception. It is 0x00.

I think my problem may lie with VTOR,
4a87af517ae0a646a0ec01c369a5909
I think this register should be related to the startup file and link file, as follows:


1 Like

What happens when you hit svc 0? Can you break the code in the debugger and see what it is doing?

1 Like

Break at address “0x10050b0” with no debug information available, or outside of program code.

1 Like

You may be right. Note that FreeRTOS 11 uses configASSERT() to verify vector installation (and VTOR) for Cortex M ports by default, so if you are able to upgrade to that version it might help prove your theory.

The correct value for SCB->VTOR can be tricky to determine. For you the correct value seems to be the origin address of the INTVECS section in your linker file. Be sure to look in the linker file you are actually using, whether that’s F28M35x_ge…3_FLASH.cmd or F28M35x_g…M3_RAM.cmd.

To set SCB->VTOR, put a statement like this at the beginning of main():

SCB->VTOR = 0x20000000; // change value as needed to match linker file

2 Likes

I have modified the register according to your suggestion.There have been some changes now, and when SVC # 0 is reached, it will enter the IntDefault Handler (void) of the startup file,I don’t seem to be able to find the problem anymore

//###########################################################################
// FILE: startup_ccs.c
// TITLE: Startup code for use with TI’s Code Composer Studio.
//###########################################################################
// $TI Release: F28M35x Support Library v220 $
// $Release Date: Tue Sep 26 15:35:11 CDT 2017 $
// $Copyright: Copyright (C) 2011-2017 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
#include <stdio.h>
#include “inc/hw_ints.h”
#include “inc/hw_memmap.h”
#include “inc/hw_nvic.h”
#include “inc/hw_gpio.h”
#include “inc/hw_types.h”
#include “inc/hw_sysctl.h”
#include “board_drivers/set_pinout_f28m35x.h”
#include “driverlib/debug.h”
#include “driverlib/interrupt.h”
#include “driverlib/sysctl.h”
#include “driverlib/gpio.h”
#include “driverlib/flash.h”
/* Kernel includes. /
#include “FreeRTOS.h”
#include “task.h”
#include “semphr.h”
//
****************************************************************************
// Forward declaration of the default fault handlers.
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);

//*****************************************************************************
// External declaration for the reset handler that is to be called when the
// processor is started
//*****************************************************************************
extern void _c_int00(void);
extern void vPortSVCHandler(void);
extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
//*****************************************************************************
// Linker variable that marks the top of the stack.
//*****************************************************************************
extern unsigned long __STACK_END;

//*****************************************************************************
// External declarations for the interrupt handlers used by the application.
//*****************************************************************************

//*****************************************************************************
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000 or at the start of
// the program if located at a start address other than 0.
//*****************************************************************************
#pragma DATA_ALIGN(g_pfnVectors, 512)
#pragma DATA_SECTION(g_pfnVectors, “.intvecs”)

void (* const g_pfnVectors)(void) =
{
(void (*) (void))((unsigned long)&__STACK_END),

// The initial stack pointer
ResetISR,                               // The reset handler
NmiSR,                                  // The NMI handler
FaultISR,                               // The hard fault handler
IntDefaultHandler,                      // The MPU fault handler
IntDefaultHandler,                      // The bus fault handler
IntDefaultHandler,                      // The usage fault handler
0,                                      // Reserved
0,                                      // Reserved
0,                                      // Reserved
vPortSVCHandler,                      // SVCall handler
   IntDefaultHandler,                      // Debug monitor handler
   0,                                      // Reserved
   xPortPendSVHandler,                      // The PendSV handler
   xPortSysTickHandler,                     // The SysTick handler
IntDefaultHandler,                      // GPIO Port A
IntDefaultHandler,                      // GPIO Port B
IntDefaultHandler,                      // GPIO Port C
IntDefaultHandler,                      // GPIO Port D
IntDefaultHandler,                      // GPIO Port E
IntDefaultHandler,                      // UART0 Rx and Tx
IntDefaultHandler,                      // UART1 Rx and Tx
IntDefaultHandler,                      // SSI0 Rx and Tx
IntDefaultHandler,                      // I2C0 Master and Slave
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Watchdog timer
IntDefaultHandler,                      // Timer 0 subtimer A
IntDefaultHandler,                      // Timer 0 subtimer B
IntDefaultHandler,                      // Timer 1 subtimer A
IntDefaultHandler,                      // Timer 1 subtimer B
IntDefaultHandler,                      // Timer 2 subtimer A
IntDefaultHandler,                      // Timer 2 subtimer B
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // System Control
IntDefaultHandler,                      // FLASH Control
IntDefaultHandler,                      // GPIO Port F
IntDefaultHandler,                      // GPIO Port G
IntDefaultHandler,                      // GPIO Port H
IntDefaultHandler,                      // UART2 Rx and Tx
IntDefaultHandler,                      // SSI1 Rx and Tx
IntDefaultHandler,                      // Timer 3 subtimer A
IntDefaultHandler,                      // Timer 3 subtimer B
IntDefaultHandler,                      // I2C1 Master and Slave
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // EMAC
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // USB0
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // uDMA Software Transfer
IntDefaultHandler,                      // uDMA Error
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // External Peripheral Interface
IntDefaultHandler,                      // GPIO Port J
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // SSI2
IntDefaultHandler,                      // SSI3
IntDefaultHandler,                      // UART3
IntDefaultHandler,                      // UART4
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // CAN0 INT0
IntDefaultHandler,                      // CAN0 INT1
IntDefaultHandler,                      // CAN1 INT0
IntDefaultHandler,                      // CAN1 INT1
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // ADCINT1
IntDefaultHandler,                      // ADCINT2
IntDefaultHandler,                      // ADCINT3
IntDefaultHandler,                      // ADCINT4
IntDefaultHandler,                      // ADCINT5
IntDefaultHandler,                      // ADCINT6
IntDefaultHandler,                      // ADCINT7
IntDefaultHandler,                      // ADCINT8
IntDefaultHandler,                      // CTOMIPC1
IntDefaultHandler,                      // CTOMIPC2
IntDefaultHandler,                      // CTOMIPC3
IntDefaultHandler,                      // CTOMIPC4
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // Reserved
IntDefaultHandler,                      // RAM Single Error
IntDefaultHandler,                      // System/USB PLL Out of Lock
IntDefaultHandler,                      // M3 Flash Single Error
IntDefaultHandler                       // Reserved

};

//*****************************************************************************
// This is the code that gets called when the processor first starts execution
// following a reset event. Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called. Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//*****************************************************************************
#pragma CODE_SECTION(ResetISR, “.resetisr”)
void
ResetISR(void)
{
// Jump to the CCS C Initialization Routine.
__asm(" .global _c_int00\n"
" b.w _c_int00");
}

//*****************************************************************************
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//*****************************************************************************
static void
NmiSR(void)
{
// Enter an infinite loop.
while(1)
{
}
}

//*****************************************************************************
// This is the code that gets called when the processor receives a fault
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//*****************************************************************************
static void
FaultISR(void)
{
// Enter an infinite loop.
while(1)
{
}
}

//*****************************************************************************
// This is the code that gets called when the processor receives an unexpected
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//*****************************************************************************
static void
IntDefaultHandler(void)
{
// Go into an infinite loop.
while(1)
{

}

}

Can you upgrade to FreeRTOS 11? That will help us rule out any issues with the interrupt vectors.

Do you have configASSERT() defined?

My FreeRTOS version is FreeRTOSv202212.00
My FreeRTOSconfig.h file is defined as follows:
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

Assuming you are using FreeRTOS/FreeRTOS, as suggested by @jefftenney, can you update the FreeRTOS-Kernel submodule pointer to the version 11 or to the latest main branch?

Forgive my foolishness, where can I check for downloads or use the FreeRTOS Kernel submodule pointer you mentioned? I didn’t seem to have followed it before. Thank you for your question

If you are using the FreeRTOS/FreeRTOS repo, you can switch to the kernel directory and checkout main branch:

cd FreeRTOS/Source
git checkout main
git pull

If that is not the case, you can clone the FreeRTOS-Kernel repo:

git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git

I have upgraded freertos to 11, but it doesn’t seem to trigger assert.
I randomly selected a code snippet with an assert and intentionally modified it to an error value. It is capable of triggering the assertion and entering the loop.

Thank you, I have found and completed the upgrade

In that case, you may have an error in your task code or in the size of the stack you provide it. Can you set a breakpoint at the beginning of your highest priority task to see if control reaches your task code?

Can you also confirm your symptom is that you end up stuck in the default handler – but not the fault ISR?

I think I have encountered a difficult bone to gnaw on
I set a breakpoint at the beginning of my task but did not reach it
The next step after SVC 0 is to enter the default handler

IntDefaultHandler is installed for a number of interrupts. Can you install separate handlers for all the interrupts to find out which interrupt is happening? Something like the following:

NmiSR,                                  // The NMI handler
FaultISR,                               // The hard fault handler
IntDefaultHandler_MPU,                  // The MPU fault handler
IntDefaultHandler_Bus,                  // The bus fault handler
IntDefaultHandler_Usage,                // The usage fault handler
0,                                      // Reserved
static void IntDefaultHandler_MPU( void )
{
    while( 1 ) {}
}

static void IntDefaultHandler_Bus( void )
{
    while( 1 ) {}
}

static void IntDefaultHandler_Usage( void )
{
    while( 1 ) {}
}

Your suggestion is correct. I have found the reason that triggered it, which is the Debug monitor handler. Where did the interrupt go wrong?


Are you enabling this Debug Monitor exception somehow - Documentation – Arm Developer? The tools you are using may also do that. Are you able to run a bare metal application without FreeRTOS?