ZYNQ中FreeRTOS中使用定时器

使用普通的Timer中断方式时,Timer中断可以正常运行,但是UDP通信进程无法启动。其中TimerIntrHandler是中断服务程序,打印程序运行时间与从BRAM中读取的数据。

void SetupInterruptSystem(XScuGic *GicInstancePtr,XScuTimer *TimerInstancePtr, u16 TimerIntrId)
{
	XScuGic_Config *IntcConfig; //GIC config
	Xil_ExceptionInit();
	//initialise the GIC
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
	IntcConfig->CpuBaseAddress);
	//connect to the hardware
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,GicInstancePtr);
	//set up the timer interrupt
	XScuGic_Connect(GicInstancePtr, TimerIntrId,(Xil_ExceptionHandler)TimerIntrHandler,	(void *)TimerInstancePtr);
	//enable the interrupt for the Timer at GIC
	XScuGic_Enable(GicInstancePtr, TimerIntrId);
	//enable interrupt on the timer
	XScuTimer_EnableInterrupt(TimerInstancePtr);
	// Enable interrupts in the Processor.
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	}


static void TimerIntrHandler(void *CallBackRef)
{
	static int sec = 0; //计数
	XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
	XScuTimer_ClearInterruptStatus(TimerInstancePtr);
	sec++;
	int rev = Xil_In32(XPAR_BRAM_1_BASEADDR);
	xil_printf( "The data at %x is %x \r",XPAR_BRAM_1_BASEADDR,rev);
	printf("Current program run for %d seconds\n\r",sec); //每秒打印输出一次
}


void timer_init()
{
    //Timer test
    printf("Timer test...\r\n");
    XScuTimer_Config *TMRConfigPtr; //timer config
    //printf("------------START-------------\n");
    //私有定时器初始化
    TMRConfigPtr = XScuTimer_LookupConfig(0);//TIMER_DEVICE_ID);
    XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr->BaseAddr);
    XScuTimer_SelfTest(&Timer);
    //加载计数周期, 私有定时器的时钟为 CPU 的一般, 为 333MHZ,如果计数 1S,加载值为1sx(333x1000x1000)(1/s)-1=0x13D92D3F
    XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE);
    //自动装载
    XScuTimer_EnableAutoReload(&Timer);
    //启动定时器
    XScuTimer_Start(&Timer);
    //set up the interrupts
    SetupInterruptSystem(&Intc,&Timer,TIMER_IRPT_INTR);
}

改为进程定时器的方式后,UDP通信进程可以正常启动。DELAY_10_SECONDS与DELAY_1_SECOND是中断时间设置。

#define TIMER_ID	1
#define DELAY_10_SECONDS	10000UL
#define DELAY_1_SECOND		1000UL
#define TIMER_CHECK_THRESHOLD	9
static TimerHandle_t xTimer = NULL;

int main()
{
	sys_thread_new("main_thread", (void(*)(void*))main_thread, 0,
			THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);

	//sleep(10);
	const TickType_t x1second = pdMS_TO_TICKS( DELAY_1_SECOND );
	xTimer = xTimerCreate( (const char *) "Timer",x1second,pdTRUE,(void *) TIMER_ID,TimerIntrHandler);
	configASSERT( xTimer );
	xTimerStart( xTimer, 0 );

	vTaskStartScheduler();
	while(1);
	return 0;
}

 

使用Zynq芯片和FreeRTOS操作系统来点亮LED时,你可以按照以下步骤进行操作: 1. 首先,确保你已经正确配置了启动模式。根据引用\[1\]的描述,选择正确的启动模式,例如“qspi_dual_parallel”,以确保能够成功下载并加载程序。 2. 在应用程序,你可以使用队列来传递LED的控制信息。根据引用\[2\]的代码片段,当接收到控制LED的命令时,将LED的控制信息写入队列。确保在写入队列时使用取地址符号`&`。 3. 在综合、布局布线并生成bit流后,导出硬件。根据引用\[3\]的描述,你需要在Vivado完成综合、布局布线,并生成bit流文件。 4. 在SDK创建一个新的应用工程,选择适合你的Vivado和SDK版本的OS Platform平台,例如freertos10_xilinx。选择“FreeRTOS lwIP Echo Server”作为模板。 5. 在应用工程,根据你的需求编写代码来控制LED。你可以使用队列来接收来自前面步骤的队列的LED控制信息,并根据接收到的信息来点亮LED。 请注意,以上步骤仅提供了一个大致的指导,具体的实现细节可能因为你的具体硬件和软件环境而有所不同。建议你参考相关的文档和资料,以确保正确地使用ZynqFreeRTOS来点亮LED。 #### 引用[.reference_title] - *1* *2* *3* [ZC706千兆网测试(ZYNQFreeRTOS,Echo,消息队列,QSPI启动,FSBL固化,lwIP,TCP,RGMII,Xilinx)](https://blog.csdn.net/DengFengLai123/article/details/113790744)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值