1
0
Эх сурвалжийг харах

Modify the interrupt interface implementations, changes in the part of the parameter definition.

weety 12 жил өмнө
parent
commit
b21028474b

+ 21 - 20
bsp/at91sam9260/at91_mci.c

@@ -49,8 +49,6 @@ struct at91_mci {
 	rt_uint32_t current_status;
 };
 
-static struct at91_mci *at_mci;
-
 /*
  * Reset the controller and restore most of the state
  */
@@ -592,8 +590,9 @@ static void at91_mci_completed_command(struct at91_mci *mci, rt_uint32_t status)
 /*
  * Handle an interrupt
  */
-static void at91_mci_irq(int irq)
+static void at91_mci_irq(int irq, void *param)
 {
+	struct at91_mci *mci = (struct at91_mci *)param;
 	rt_int32_t completed = 0;
 	rt_uint32_t int_status, int_mask;
 
@@ -635,13 +634,13 @@ static void at91_mci_irq(int irq)
 		if (int_status & AT91_MCI_TXBUFE) 
 		{
 			mci_dbg("TX buffer empty\n");
-			at91_mci_handle_transmitted(at_mci);
+			at91_mci_handle_transmitted(mci);
 		}
 
 		if (int_status & AT91_MCI_ENDRX) 
 		{
 			mci_dbg("ENDRX\n");
-			at91_mci_post_dma_read(at_mci);
+			at91_mci_post_dma_read(mci);
 		}
 
 		if (int_status & AT91_MCI_RXBUFF) 
@@ -668,7 +667,7 @@ static void at91_mci_irq(int irq)
 		if (int_status & AT91_MCI_BLKE) 
 		{
 			mci_dbg("Block transfer has ended\n");
-			if (at_mci->req->data && at_mci->req->data->blks > 1) 
+			if (mci->req->data && mci->req->data->blks > 1) 
 			{
 				/* multi block write : complete multi write
 				 * command and send stop */
@@ -684,7 +683,7 @@ static void at91_mci_irq(int irq)
 			rt_mmcsd_signal_sdio_irq(host->mmc);*/
 
 		if (int_status & AT91_MCI_SDIOIRQB)
-			sdio_irq_wakeup(at_mci->host);
+			sdio_irq_wakeup(mci->host);
 
 		if (int_status & AT91_MCI_TXRDY)
 			mci_dbg("Ready to transmit\n");
@@ -695,7 +694,7 @@ static void at91_mci_irq(int irq)
 		if (int_status & AT91_MCI_CMDRDY) 
 		{
 			mci_dbg("Command ready\n");
-			completed = at91_mci_handle_cmdrdy(at_mci);
+			completed = at91_mci_handle_cmdrdy(mci);
 		}
 	}
 
@@ -703,7 +702,7 @@ static void at91_mci_irq(int irq)
 	{
 		mci_dbg("Completed command\n");
 		at91_mci_write(AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-		at91_mci_completed_command(at_mci, int_status);
+		at91_mci_completed_command(mci, int_status);
 	} 
 	else
 		at91_mci_write(AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
@@ -791,7 +790,7 @@ static const struct rt_mmcsd_host_ops ops = {
 	at91_mci_enable_sdio_irq,
 };
 
-void at91_mci_detect(int irq)
+void at91_mci_detect(int irq, void *param)
 {
 	rt_kprintf("mmcsd gpio detected\n");
 }
@@ -819,7 +818,7 @@ static void mci_gpio_init()
 rt_int32_t at91_mci_init(void)
 {
 	struct rt_mmcsd_host *host;
-	//struct at91_mci *mci;
+	struct at91_mci *mci;
 
 	host = mmcsd_alloc_host();
 	if (!host) 
@@ -827,14 +826,14 @@ rt_int32_t at91_mci_init(void)
 		return -RT_ERROR;
 	}
 
-	at_mci = rt_malloc(sizeof(struct at91_mci));
-	if (!at_mci) 
+	mci = rt_malloc(sizeof(struct at91_mci));
+	if (!mci) 
 	{
 		rt_kprintf("alloc mci failed\n");
 		goto err;
 	}
 
-	rt_memset(at_mci, 0, sizeof(struct at91_mci));
+	rt_memset(mci, 0, sizeof(struct at91_mci));
 
 	host->ops = &ops;
 	host->freq_min = 375000;
@@ -846,7 +845,7 @@ rt_int32_t at91_mci_init(void)
 	host->max_blk_size = 512;
 	host->max_blk_count = 4096;
 
-	at_mci->host = host;
+	mci->host = host;
 
 	mci_gpio_init();
 	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI); //enable MCI clock
@@ -855,14 +854,16 @@ rt_int32_t at91_mci_init(void)
 	at91_mci_enable();
 
 	/* instal interrupt */
-	rt_hw_interrupt_install(AT91SAM9260_ID_MCI, at91_mci_irq, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_MCI, at91_mci_irq, 
+							(void *)mci, "MMC");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_MCI);
-	rt_hw_interrupt_install(gpio_to_irq(AT91_PIN_PA7), at91_mci_detect, RT_NULL);
+	rt_hw_interrupt_install(gpio_to_irq(AT91_PIN_PA7), 
+							at91_mci_detect, RT_NULL, "MMC_DETECT");
 	rt_hw_interrupt_umask(gpio_to_irq(AT91_PIN_PA7));
 
-	rt_timer_init(&at_mci->timer, "mci_timer", 
+	rt_timer_init(&mci->timer, "mci_timer", 
 		at91_timeout_timer, 
-		at_mci, 
+		mci, 
 		RT_TICK_PER_SECOND, 
 		RT_TIMER_FLAG_PERIODIC);
 
@@ -870,7 +871,7 @@ rt_int32_t at91_mci_init(void)
 
 	//rt_sem_init(&mci->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO);
 
-	host->private_data = at_mci;
+	host->private_data = mci;
 
 	mmcsd_change(host);
 

+ 17 - 11
bsp/at91sam9260/board.c

@@ -92,9 +92,10 @@ struct rt_device uart4_device;
 /**
  * This function will handle serial
  */
-void rt_serial_handler(int vector)
+void rt_serial_handler(int vector, void *param)
 {
 	int status;
+	struct rt_device *dev = (rt_device_t)param;
 
 	switch (vector) 
 	{
@@ -105,7 +106,7 @@ void rt_serial_handler(int vector)
 		{
 			return;
 		}
-		rt_hw_serial_isr(&uart1_device);
+		rt_hw_serial_isr(dev);
 		break;
 	#endif
 	#ifdef RT_USING_UART1
@@ -115,7 +116,7 @@ void rt_serial_handler(int vector)
 		{
 			return;
 		}
-		rt_hw_serial_isr(&uart2_device);
+		rt_hw_serial_isr(dev);
 		break;
 	#endif
 	#ifdef RT_USING_UART2
@@ -125,7 +126,7 @@ void rt_serial_handler(int vector)
 		{
 			return;
 		}
-		rt_hw_serial_isr(&uart3_device);
+		rt_hw_serial_isr(dev);
 		break;
 	#endif
 	#ifdef RT_USING_UART3
@@ -135,7 +136,7 @@ void rt_serial_handler(int vector)
 		{
 			return;
 		}
-		rt_hw_serial_isr(&uart4_device);
+		rt_hw_serial_isr(dev);
 		break;
 	#endif
 	default: break;
@@ -176,7 +177,8 @@ void rt_hw_uart_init(void)
 	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5));
 	uart_port_init(AT91SAM9260_BASE_US0);
 	/* install interrupt handler */
-	rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, 
+							(void *)&uart1_device, "UART0");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_US0);
 #endif
 #ifdef RT_USING_UART1
@@ -188,7 +190,8 @@ void rt_hw_uart_init(void)
 	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7));
 	uart_port_init(AT91SAM9260_BASE_US1);
 	/* install interrupt handler */
-	rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, 
+							(void *)&uart2_device, "UART1");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_US1);
 #endif
 #ifdef RT_USING_UART2
@@ -200,7 +203,8 @@ void rt_hw_uart_init(void)
 	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9));
 	uart_port_init(AT91SAM9260_BASE_US2);
 	/* install interrupt handler */
-	rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, 
+							(void *)&uart3_device, "UART2");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_US2);
 #endif
 #ifdef RT_USING_UART3
@@ -212,7 +216,8 @@ void rt_hw_uart_init(void)
 	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<10)|(1<<11));
 	uart_port_init(AT91SAM9260_BASE_US3);
 	/* install interrupt handler */
-	rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, 
+							(void *)&uart4_device, "UART3");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_US3);
 	
 #endif
@@ -246,7 +251,7 @@ static rt_uint32_t pit_cnt;		/* access only w/system irq blocked */
 /**
  * This function will handle rtos timer
  */
-void rt_timer_handler(int vector)
+void rt_timer_handler(int vector, void *param)
 {
 	#ifdef RT_USING_DBGU
 	if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) {
@@ -309,7 +314,8 @@ static void at91sam926x_pit_init(void)
  	at91sam926x_pit_init();
 
 	/* install interrupt handler */
-	rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, RT_NULL);
+	rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, 
+							RT_NULL, "system");
 	rt_hw_interrupt_umask(AT91_ID_SYS);
 
  }

+ 4 - 3
bsp/at91sam9260/macb.c

@@ -103,9 +103,9 @@ static void udelay(rt_uint32_t us)
         for (len = 0; len < 10; len++ );
 }
 
-static void rt_macb_isr(int irq)
+static void rt_macb_isr(int irq, void *param)
 {
-	struct rt_macb_eth *macb = &macb_device;
+	struct rt_macb_eth *macb = (struct rt_macb_eth *)param;
 	rt_device_t dev = &(macb->parent.parent);
 	rt_uint32_t status, rsr, tsr;
 
@@ -412,7 +412,8 @@ static rt_err_t rt_macb_init(rt_device_t dev)
 			      | MACB_BIT(HRESP)));
 	
 	/* instal interrupt */
-	rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, RT_NULL);
+	rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, 
+							(void *)macb, "emac");
 	rt_hw_interrupt_umask(AT91SAM9260_ID_EMAC);
 
 	rt_timer_init(&macb->timer, "link_timer", 

+ 2 - 2
include/rthw.h

@@ -42,8 +42,8 @@ void rt_hw_interrupt_init(void);
 void rt_hw_interrupt_mask(int vector);
 void rt_hw_interrupt_umask(int vector);
 void rt_hw_interrupt_install(int               vector,
-                             rt_isr_handler_t  new_handler,
-                             rt_isr_handler_t *old_handler);
+                             rt_isr_handler_t  handler,
+                             void *param, char *name);
 void rt_hw_interrupt_handle(int vector);
 
 rt_base_t rt_hw_interrupt_disable(void);

+ 1 - 1
include/rtthread.h

@@ -425,7 +425,7 @@ void rt_module_unload_sethook(void (*hook)(rt_module_t module));
 /*
  * interrupt service
  */
-typedef void (*rt_isr_handler_t)(int vector);
+typedef void (*rt_isr_handler_t)(int vector, void *param);
 
 /*
  * rt_interrupt_enter and rt_interrupt_leave only can be called by BSP

+ 51 - 11
libcpu/arm/at91sam926x/interrupt.c

@@ -14,13 +14,15 @@
 
 #include <rtthread.h>
 #include "at91sam926x.h"
+#include "interrupt.h"
 
 #define MAX_HANDLERS	(AIC_IRQS + PIN_IRQS)
 
 extern rt_uint32_t rt_interrupt_nest;
 
 /* exception and interrupt handler table */
-rt_isr_handler_t isr_table[MAX_HANDLERS];
+struct rt_irq_desc irq_desc[MAX_HANDLERS]; 
+
 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
 rt_uint32_t rt_thread_switch_interrupt_flag;
 
@@ -79,15 +81,16 @@ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = {
 void rt_hw_interrupt_mask(int irq);
 void rt_hw_interrupt_umask(int irq);
 
-rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
+rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
 {
 	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
 	return RT_NULL;
 }
 
-rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector)
+rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param)
 {
 	rt_uint32_t isr, pio, irq_n;
+	void *parameter;
 
 	if (vector == AT91SAM9260_ID_PIOA) 
 	{
@@ -111,7 +114,8 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector)
 	{
 		if (isr & 1) 
 		{
-			isr_table[irq_n](irq_n);
+			parameter = irq_desc[irq_n].param;
+			irq_desc[irq_n].isr_handle(irq_n, parameter);
 		}
 		isr >>= 1;
 		irq_n++;
@@ -160,13 +164,22 @@ void at91_aic_init(rt_uint32_t *priority)
 
 static void at91_gpio_irq_init()
 {
+	int i, idx;
+	char *name[] = {"PIOA", "PIOB", "PIOC"};
+	
 	at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff);
 	at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff);
 	at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff);
 
-	isr_table[AT91SAM9260_ID_PIOA] = (rt_isr_handler_t)at91_gpio_irq_handle;
-	isr_table[AT91SAM9260_ID_PIOB] = (rt_isr_handler_t)at91_gpio_irq_handle;
-	isr_table[AT91SAM9260_ID_PIOC] = (rt_isr_handler_t)at91_gpio_irq_handle;
+	idx = AT91SAM9260_ID_PIOA;
+	for (i = 0; i < 3; i++)
+	{
+		rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, name[i]);
+		irq_desc[idx].isr_handle = (rt_isr_handler_t)at91_gpio_irq_handle;
+		irq_desc[idx].param = RT_NULL;
+		irq_desc[idx].interrupt_cnt = 0;
+		idx++;
+	}
 
 	rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA);
 	rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB);
@@ -192,7 +205,10 @@ void rt_hw_interrupt_init(void)
 	/* init exceptions table */
 	for(idx=0; idx < MAX_HANDLERS; idx++)
 	{
-		isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle;
+		rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, "default");
+		irq_desc[idx].isr_handle = (rt_isr_handler_t)rt_hw_interrupt_handle;
+		irq_desc[idx].param = RT_NULL;
+		irq_desc[idx].interrupt_cnt = 0;
 	}
 
 	at91_gpio_irq_init();
@@ -292,12 +308,14 @@ void rt_hw_interrupt_umask(int irq)
  * @param new_handler the interrupt service routine to be installed
  * @param old_handler the old interrupt service routine
  */
-void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, char *name)
 {
 	if(vector < MAX_HANDLERS)
 	{
-		if (old_handler != RT_NULL) *old_handler = isr_table[vector];
-		if (new_handler != RT_NULL) isr_table[vector] = new_handler;
+		rt_snprintf(irq_desc[vector].irq_name, RT_NAME_MAX - 1, "%s", name);
+		irq_desc[vector].isr_handle = (rt_isr_handler_t)handler;
+		irq_desc[vector].param = param;
+		irq_desc[vector].interrupt_cnt = 0;
 	}
 }
 
@@ -335,3 +353,25 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
 	at91_sys_write(AT91_AIC_SMR(irq), smr | srctype);
 	return 0;
 }
+
+#ifdef RT_USING_FINSH
+void list_irq(void)
+{
+	int irq;
+	
+	rt_kprintf("number\tcount\tname\n");
+	for (irq = 0; irq < MAX_HANDLERS; irq++)
+	{
+		if (rt_strncmp(irq_desc[irq].irq_name, "default", sizeof("default")))
+		{
+			rt_kprintf("%02ld: %10ld  %s\n", irq, irq_desc[irq].interrupt_cnt, irq_desc[irq].irq_name);
+		}
+	}
+}
+
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(list_irq, list system irq);
+
+#endif
+
+

+ 11 - 0
libcpu/arm/at91sam926x/interrupt.h

@@ -0,0 +1,11 @@
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+struct rt_irq_desc {
+	char irq_name[RT_NAME_MAX];
+	rt_isr_handler_t isr_handle;
+	void *param;
+	rt_uint32_t interrupt_cnt;
+};
+
+#endif

+ 7 - 3
libcpu/arm/at91sam926x/trap.c

@@ -16,6 +16,7 @@
 #include <rthw.h>
 
 #include "at91sam926x.h"
+#include "interrupt.h"
 
 /**
  * @addtogroup AT91SAM926X
@@ -138,12 +139,13 @@ void rt_hw_trap_resv(struct rt_hw_register *regs)
 	rt_hw_cpu_shutdown();
 }
 
-extern rt_isr_handler_t isr_table[];
+extern struct rt_irq_desc irq_desc[];
 
 void rt_hw_trap_irq()
 {
 	rt_isr_handler_t isr_func;
 	rt_uint32_t irqstat, irq, mask;
+	void *param;
 	//rt_kprintf("irq interrupt request\n");
 	/* get irq number */
 	irq = at91_sys_read(AT91_AIC_IVR);
@@ -158,11 +160,13 @@ void rt_hw_trap_irq()
 	//at91_sys_write(AT91_AIC_EOICR, 0x55555555);
 	
 	/* get interrupt service routine */
-	isr_func = isr_table[irq];
+	isr_func = irq_desc[irq].isr_handle;
+	param = irq_desc[irq].param;
 
 	/* turn to interrupt service routine */
-	isr_func(irq);
+	isr_func(irq, param);
 	at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt
+	irq_desc[irq].interrupt_cnt++;
 }
 
 void rt_hw_trap_fiq()