Interrupts on Erika3 and Tricore 29x with iLLD

Forum related to ERIKA Enterprise and RT-Druid version 3

Moderator: paolo.gai

Locked
Alexanderv66

Interrupts on Erika3 and Tricore 29x with iLLD

Post by Alexanderv66 »

I have project based on Erika3, generated by RT-druid and added to it iLLD library.
I using ASCLIN module in usart mode. After Tx, calling interrupt with priority 10, as i sets in OIL and iLLD configuration. The first byte is sent by the microcontroller is normally received by the PC. After that, microcontroller has cycled by " osEE_tc_core0_isr_dummy_entry_10". This dummy entry does not contain a jump instruction to asclin0TxISR.

My question: why is my interrupt handler not called there?

irq10.PNG
irq10.PNG (15.77 KiB) Viewed 5543 times
Interrupt mechanism type is Hardware, by commented define in Ifx_Cfg.h

Code: Select all

//#define IFX_USE_SW_MANAGED_INT
Full OIL file:

Code: Select all


CPU test_application {
	
ALARM AlarmMaster_500ms {
		ACTION = ACTIVATETASK {
			TASK = TaskTempMeasureMaster;
		};
		AUTOSTART = TRUE {
			ALARMTIME = 50;
			CYCLETIME = 50;
		};
		COUNTER = system_timer_master;
	};
	APPDATA tricore_mc {
		APP_SRC = "master.c";
		APP_SRC = "slave1.c";
		APP_SRC = "slave2.c";
	};
	COUNTER system_timer_master {
		CPU_ID = 0x0;
		MINCYCLE = 1;
		MAXALLOWEDVALUE = 2147483647;
		TICKSPERBASE = 1;
		SECONDSPERTICK = 0.01;
		TYPE = HARDWARE {
			PRIORITY = 2;
			DEVICE = "STM_SR0";
			SYSTEM_TIMER = TRUE;
		};
	};
	EVENT RemoteEvent {
		MASK = AUTO;
	};
	ISR asclin0Tx {
		CPU_ID = 0x0;
		CATEGORY = 2;
		SOURCE = "ASCLIN0TX";
		PRIORITY = 10;
		HANDLER = "asclin0TxISR";
	};
	OS EE {
		EE_OPT = "OSEE_DEBUG";
		EE_OPT = "OSEE_ASSERT";
		EE_OPT = "OS_EE_APPL_BUILD_DEBUG";
		EE_OPT = "OS_EE_BUILD_DEBUG";
		STATUS = EXTENDED;
		ERRORHOOK = TRUE;
		USERESSCHEDULER = FALSE;
		USEORTI = TRUE;
		KERNEL_TYPE = OSEK {
			CLASS = ECC1;
			RQ = LL;
		};
		CPU_DATA = TRICORE {
			ID = 0x0;
			CPU_CLOCK = 300.0;
			COMPILER = GCC;
			MULTI_STACK = TRUE {
				IRQ_STACK = FALSE;
				SHARED_STACK = FALSE;
			};
			IDLEHOOK = TRUE {
				HOOKNAME = "idle_hook_core0";
			};
		};
		CPU_DATA = TRICORE {
			ID = 0x1;
			COMPILER = GCC;
			MULTI_STACK = TRUE {
				IRQ_STACK = FALSE;
				SHARED_STACK = FALSE;
			};
			IDLEHOOK = TRUE {
				HOOKNAME = "idle_hook_core1";
			};
		};
		CPU_DATA = TRICORE {
			ID = 0x2;
			COMPILER = GCC;
			MULTI_STACK = TRUE {
				IRQ_STACK = FALSE;
				SHARED_STACK = FALSE;
			};
			IDLEHOOK = TRUE {
				HOOKNAME = "idle_hook_core2";
			};
		};
		BOARD_DATA = NO_BOARD;
		MCU_DATA = TC29X {
			DERIVATIVE = "tc299tf";
			REVISION = "DC";
		};
		USEDYNAMICAPI = FALSE;
		USEEXTENSIONAPI = FALSE;
		STACKMONITORING = FALSE;
	};
	TASK TaskTempMeasureMaster {
		PRIORITY = 7;
		CPU_ID = 0x0;
		ACTIVATION = 1;
		SCHEDULE = FULL;
		AUTOSTART = TRUE;
		STACK = SHARED;
	};
	TASK TaskSlave1 {
		PRIORITY = 8;
		CPU_ID = 0x1;
		ACTIVATION = 1;
		SCHEDULE = FULL;
		AUTOSTART = TRUE;
		STACK = PRIVATE {
			SIZE = 256;
		};
		EVENT = RemoteEvent;
	};
	TASK TaskSlave2 {
		PRIORITY = 9;
		CPU_ID = 0x2;
		ACTIVATION = 1;
		SCHEDULE = FULL;
		AUTOSTART = TRUE;
		STACK = PRIVATE {
			SIZE = 256;
		};
	};
};
iLLD interrupt configuration, defined in one of project C files:

Code: Select all

#define IFX_INTPRIO_ASCLIN0_TX  10
#define IFX_INTPRIO_ASCLIN0_RX  11
#define IFX_INTPRIO_ASCLIN0_ER  12

IFX_INTERRUPT(asclin0TxISR, 0, IFX_INTPRIO_ASCLIN0_TX);
IFX_INTERRUPT(asclin0RxISR, 0, IFX_INTPRIO_ASCLIN0_RX);
IFX_INTERRUPT(asclin0ErISR, 0, IFX_INTPRIO_ASCLIN0_ER);

void asclin0TxISR()
{
	IfxAsclin_Asc_isrTransmit(&asc);
}

void asclin0RxISR()
{
	IfxAsclin_Asc_isrReceive(&asc);
}

void asclin0ErISR()
{
	IfxAsclin_Asc_isrError(&asc);
}

ASCLIN initialisation function:

Code: Select all


// used globally
IfxAsclin_Asc asc;

void initASC0()
{
	// create module config
	IfxAsclin_Asc_Config ascConfig;
	IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0);

	// set the desired baudrate
	ascConfig.baudrate.prescaler = 1;
	ascConfig.baudrate.baudrate = 115200; // FDR values will be calculated in initModule

	// ISR priorities and interrupt target
	ascConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN0_TX;
	ascConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN0_RX;
	ascConfig.interrupt.erPriority = IFX_INTPRIO_ASCLIN0_ER;
	ascConfig.interrupt.typeOfService =   IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());

	// FIFO configuration
	ascConfig.txBuffer = &ascTxBuffer;
	ascConfig.txBufferSize = ASC_TX_BUFFER_SIZE;

	ascConfig.rxBuffer = &ascRxBuffer;
	ascConfig.rxBufferSize = ASC_RX_BUFFER_SIZE;

	// pin configuration
	const IfxAsclin_Asc_Pins pins = {
		NULL,                           IfxPort_InputMode_pullUp,    // CTS pin not used
		&IfxAsclin0_RXB_P15_3_IN,   IfxPort_InputMode_pullUp,    // Rx pin
		NULL,                           IfxPort_OutputMode_pushPull, // RTS pin not used
		&IfxAsclin0_TX_P15_2_OUT,   IfxPort_OutputMode_pushPull, // Tx pin
		IfxPort_PadDriver_cmosAutomotiveSpeed1
	};
	ascConfig.pins = &pins;

	// initialize module
	IfxAsclin_Asc_initModule(&asc, &ascConfig);
}

i used Erika's linker script file "ee_tc_gcc_flash.ld" by Errico Guidieri date 2017
e.guidieri

Re: Interrupts on Erika3 and Tricore 29x with iLLD

Post by e.guidieri »

You are mixing 2 things,

iLLD interrupt support and ERIKA support, ERIKA is not aware of iLLD is doing and iLLD is not aware to run under an ERIKA application.

This means that using IFX_INTERRUPT macro to register interrupts has no use in ERIKA.

In ERIKA everything is configured through OIL, you need to add the ISR configuration there (at the end of the TASKs is the best place)

Code: Select all

ISR ASCLIN0_TX {
  CATEGORY = 1; /* <-- If you need to interact with ERIKA (e.g. ActivateTask) change this to category 2 */
  PRIORITY = 10;
  HANDLER = "asclin0TxISR"; 
  SOURCE = "ASCLIN_ASCLIN0_TX"; /* <-- This is the correct name of the source, but you could use ASCLIN0TX too. */
};

/* You could use as name of the ISR the handler, in this case you don't need to provide the handler field */
ISR asclin0RxISR {
  CATEGORY = 1; /* <-- If you need to interact with ERIKA (e.g. ActivateTask) change this to category 2 */
  PRIORITY = 11;
  SOURCE = "ASCLIN_ASCLIN0_RX"; /* <-- This is the correct name of the source, but you could use ASCLIN0RX too. */
};

/* You could use as name of the ISR the handler, in this case you don't need to provide the handler field */
ISR asclin0ErISR {
  CATEGORY = 1; /* <-- If you need to interact with ERIKA (e.g. ActivateTask) change this to category 2 */
  PRIORITY = 12;
  SOURCE = "ASCLIN_ASCLIN0_ERR"; /* <-- This is the correct name of the source, but you could use ASCLIN0ERR too. */
}
e.guidieri

Re: Interrupts on Erika3 and Tricore 29x with iLLD

Post by e.guidieri »

Sorry I saw the ISR2 configuration in the middle of the OIL (I'm not used to search them there so I dind't see it at the beginning).

I tried to generate the code from the OIL with the latest version (GH65) and I'm getting the right code:

erika/obj/ee_tc_intvec.c.s

Code: Select all

       ...
      
	.align  5
	.globl osEE_tc_core0_isr_dummy_entry_9
	osEE_tc_core0_isr_dummy_entry_9:
	j .
/* You configured it as ISR2, so the code goes trought a  wrapper */
[b]	.align  5
	.globl osEE_tc_core0_isr2_entry_10
	osEE_tc_core0_isr2_entry_10:
	svlcx
	mov %d4, 1
	j osEE_tc_isr2_wrapper[/b]
	.align 5
	.globl osEE_tc_core0_isr_dummy_entry_11
	osEE_tc_core0_isr_dummy_entry_11:
	j .

       ...
Which version are you using? Are you sure to flash the right thing?
Alexanderv66

Re: Interrupts on Erika3 and Tricore 29x with iLLD

Post by Alexanderv66 »

I made a few mistakes that caused the problem:
1. I used Eclipse Photon for Erika 3 source code generation via RTDruid embedded into Photon. With this tool it is difficult to integrate iLLD, since Eclipse does not create make-files for iLLD and other sources. In addition, I use a debugger "DAP miniWiggler" that works with UDE from PLC. But UDE is not present in Eclipse Photon. Therefore, to add an iLLD, custom source code and debugging through UDE, I use Free TriCore™ Entry Tool Chain. And I have to transfer the source codes of Erika from Photon into the Free TriCore™ Entry Tool Chain project. I did not transfer all the files, but only the part that was unacceptable
2.I used IFX_INTERRUPT masros in my source code. Now i disable it by preprocessor directive

Code: Select all

#if 0
IFX_INTERRUPT(asclin0TxISR, 0, IFX_INTPRIO_ASCLIN0_TX);
IFX_INTERRUPT(asclin0RxISR, 0, IFX_INTPRIO_ASCLIN0_RX);
IFX_INTERRUPT(asclin0ErISR, 0, IFX_INTPRIO_ASCLIN0_ER);
#endif
3. Now I ordered the interrupt declaration in OIL file

Code: Select all

	...
	...
	TASK TaskSlave2 {
		PRIORITY = 9;
		CPU_ID = 0x2;
		ACTIVATION = 1;
		SCHEDULE = FULL;
		AUTOSTART = TRUE;
		STACK = PRIVATE {
			SIZE = 256;
		};
	};
	ISR asclin0TxISR {
		CPU_ID = 0x0;
		CATEGORY = 2;
		SOURCE = "ASCLIN0TX";
		PRIORITY = 10;
	};
	
	ISR asclin0RxISR {
		CPU_ID = 0x0;
		CATEGORY = 2;
		SOURCE = "ASCLIN0RX";
		PRIORITY = 11;
	};
	
	ISR asclin0ErISR {
		CPU_ID = 0x0;
		CATEGORY = 2;
		SOURCE = "ASCLIN0ERR";
		PRIORITY = 12;
	};
};
After that it works as expected.
Thank you for the accurate and quick response
e.guidieri

Re: Interrupts on Erika3 and Tricore 29x with iLLD

Post by e.guidieri »

Just to let you know,

you can call RT-druid from the command line to have obtained the configuration generation (I usually work in this way).

For the following I suppose that the current directory is placed where the conf.oil is located.

Code: Select all

${RTDRUID_ECLIPSE_HOME}/evidence/generate_code.sh ${RTDRUID_ECLIPSE_HOME} conf.oil .
and then you can just build the library libee.a (that will be generated inside erika/lib)

Code: Select all

make -C erika all
Maybe you can add these commands to yours build scripts inside Free TriCore™ Entry Tool project.

Regards
Locked