【分享】 Xilinx SDK 2018.2,修改xttcps_intr_example.c,支持任意ttc设备

作者:hankf,Xilinx Employee

SDK里带有xttcps_intr_example.c,可以产生时钟中断和PWM方波。MPSoC有四个TTC,总共12个timer。xttcps_intr_example.c缺省使用 12个中的第0个和第1个,TTC0和TTC1。如果修改为其它TTC timer, xttcps_intr_example.c运行出现异常。

原始的C代码:
#define TTC_TICK_DEVICE_ID XPAR_XTTCPS_1_DEVICE_ID
#define TTC_TICK_INTR_ID XPAR_XTTCPS_1_INTR

#define TTC_PWM_DEVICE_ID XPAR_XTTCPS_0_DEVICE_ID
#define TTC_PWM_INTR_ID XPAR_XTTCPS_0_INTR
#define TTCPS_CLOCK_HZ XPAR_XTTCPS_0_CLOCK_HZ

异常工程的C代码:
#define TTC_TICK_DEVICE_ID XPAR_XTTCPS_4_DEVICE_ID
#define TTC_TICK_INTR_ID XPAR_XTTCPS_4_INTR

#define TTC_PWM_DEVICE_ID XPAR_XTTCPS_3_DEVICE_ID
#define TTC_PWM_INTR_ID XPAR_XTTCPS_3_INTR
#define TTCPS_CLOCK_HZ XPAR_XTTCPS_3_CLOCK_HZ

TTC死机位置
在SetupTicker()里,执行XScuGic_Connect()后死机,应该进入了异常。

/*
* Connect to the interrupt controller
* Hang after here for ttc3/ttc4(ttc1-0, ttc1-1)
*/
Status = XScuGic_Connect(&InterruptController, TTC_TICK_INTR_ID,
(Xil_ExceptionHandler)TickHandler, (void *)TtcPsTick);
if (Status != XST_SUCCESS) {
xil_printf("%s: %d\n\r", __func__, __LINE__ );
return XST_FAILURE;
}

死机后,可能在XScuGic_Connect()
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(Int_Id Xil_AssertNonvoid(Handler != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

死机后,也可能在
.org (VBAR + 0x200)
b SynchronousInterruptHandler

TTC死机原因之XTtcPs结构体

例子代码只定义了2个XTtcPs结构体,可是使用ttc的设备号作为数组的索引来取XTtcPs结构体。于是当设备号大于1时,访问非法地址。系统最多有12个TTC,因此定义12个XTtcPs结构体。
static XTtcPs TtcPsInst[12]; /* Two timer counters */

TTC死机原因之SettingsTable结构体

TTC 例子代码只定义了2个SettingsTable结构体,可是使用ttc的设备号作为数组的索引来取SettingsTable结构体,于是当设备号大于1时,访问非法地址。
// SettingsTable: ticker timer: 0, PWM timer: 1
static TmrCntrSetup SettingsTable[2] = {
{100, 0, 0, 0}, /* Ticker timer counter initial setup, only output freq */
{200, 0, 0, 0}, /* PWM timer counter initial setup, only output freq */
};

ticker定时器的配置是第0项,PWM定时器的配置是第1项。因此在代码里,取ticker定时器的配置时总使用第0项,取PWM定时器的配置时总使用1项。

SetupTicker( )的代码。
// int SetupTicker(void)
// SettingsTable: ticker timer: 0, PWM timer: 1
TimerSetup = &(SettingsTable[0]);

SetupPWM( )的代码。
//int SetupPWM(void)
// SettingsTable: ticker timer: 0, PWM timer: 1
TimerSetup = &(SettingsTable[1]); // TTC_PWM_DEVICE_ID

所有引用SettingsTable的地方都需要做更改。
修改XTtcPs结构体和SettingsTable后,虚拟机0使用ttc-0-1;虚拟机1使用ttc-3-4;虚拟机0使用ttc-6-7;虚拟机0使用ttc-9-10;多个虚拟机同时运行,都正常。
这个问题和Letter一起解决。

测试工具是Xilinx SDK 2018.2.

推荐阅读