- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello i am newbie ,please help me.
i have following error. i am using four task for displaying leds and i am using button as an interrupt,so when i press any switch button it will go to interrupt service routine ,so from there in interupt service routine i am making dma data transfer.But i have problem here- in interrupt service routine dma transfer is not working/or may be it is hanged somhow in interrupt service routine.I do not know why? but if i will use dma function once before the Interrupt service routine comes then i am able to use DMA in interrupt service routine. this time there is not blocking/hanging why?i do not know please help me . I am using full-featured cyclone-EP1c20 with nios 2. # include <stdio.h># include "board_diag.h"# include "alt_types.h"# include <unistd.h># include "system.h"# include "sys/alt_irq.h"# include "altera_avalon_pio_regs.h"# include <stdlib.h># include "sys/alt_dma.h" alt_u8 led,q; volatile int edge_capture; static volatile int rx_done = 0; /* Callback function that obtains notification that the data has * been received. */ static void done (void* handle, void* data) { rx_done++; } int dma () { int rc; alt_dma_txchan txchan; alt_dma_rxchan rxchan; alt_u32 length=32; void* tx_data = (void*) 0x2000010; /* pointer to data to send */ void* rx_buffer = (void*) 0x2010000; /* pointer to rx buffer */ /* Create the transmit channel */ if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) { led = 0x07; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(4000000); exit (1); } /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) { led = 0x0f; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(4000000); exit (1); } /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan, tx_data, length, NULL, NULL)) < 0) { led = 0x1f; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(4000000); exit (1); } /* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan,rx_buffer,length,done,NULL)) < 0) { led = 0x3f; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(4000000); exit (1); } /* wait for transfer to complete */ while (!rx_done); led = 0x40; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(4000000); /*printf ("Transfer successful!\n");*/ return 0; } static void Task1(void) { led = 0x1; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(2000000); } static void Task2(void) { led = 0x2; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(2000000); } static void Task3(void) { led = 0x4; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(2000000); } static void Task4(void) { led = 0x8; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(2000000); } # ifdef BUTTON_PIO_BASE static void handle_button_interrupts(void* context, alt_u32 id) { /* Cast context to edge_capture's type. It is important that this be * declared volatile to avoid unwanted compiler optimization. */ volatile int* edge_capture_ptr = (volatile int*) context; /* Store the value in the Button's edge capture register in *context. */ *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE); led = 0x20; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); usleep(2000000); /* Reset the Button's edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0); /*call for dma transfer*/; q=dma(); } /* Initialize the button_pio. */ static void init_button_pio() { /* Recast the edge_capture pointer to match the alt_irq_register() function * prototype. */ void* edge_capture_ptr = (void*) &edge_capture; /* Enable all 4 button interrupts. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); /* Reset the edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0); /* Register the interrupt handler. */ alt_irq_register( BUTTON_PIO_IRQ, edge_capture_ptr, handle_button_interrupts ); }# endif int main() { /* Initialize the button pio. */ int q;# ifdef BUTTON_PIO_BASE init_button_pio();# endif q=dma(); while(1) { Task1(); Task2(); Task3(); Task4(); } return(0); }Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Nirav.
In my opinion your problem comes from using the DMA API calls from inside an ISR. The following excerpt from the Nios II SW programmer manual, chapter 6 should help you in understanding: Restricted Environment ISRs run in a restricted environment. A large number of the HAL API calls are not available from ISRs. For example, accesses to the HAL file system are not permitted. As a general rule, when writing your own ISR, never include function calls that can block waiting for an interrupt. In addition, you should be careful when calling ANSI C standard library functions inside of an ISR. No calls should be made using the C standard library I/O API, because calling these functions can result in deadlock within the system, i.e., the system can become permanently blocked within the ISR. In particular, you should not call printf() from within an ISR without careful consideration. If stdout is mapped to a device driver that uses interrupts for proper operation, the printf() call can deadlock the system waiting for an interrupt that never occurs because interrupts are disabled. You can use printf() from within ISRs safely, but only if the device driver does not use interrupts. Hope this helps. Maurizio- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
but dma transfer is working fine in ISR,when i will use the dma transfer once before the
interrupt comes, NIrav --- Quote Start --- originally posted by mpaolini@Jan 17 2006, 12:14 PM hi, nirav.
in my opinion your problem comes from using the dma api calls from inside an isr. the following excerpt from the nios ii sw programmer manual, chapter 6 should help you in understanding:
restricted environment
isrs run in a restricted environment. a large number of the hal api
calls are not available from isrs. for example, accesses to the hal file
system are not permitted. as a general rule, when writing your own isr,
never include function calls that can block waiting for an interrupt.
in addition, you should be careful when calling ansi c standard library
functions inside of an isr. no calls should be made using the c standard
library i/o api, because calling these functions can result in deadlock
within the system, i.e., the system can become permanently blocked
within the isr. in particular, you should not call printf() from within
an isr without careful consideration. if stdout is mapped to a device
driver that uses interrupts for proper operation, the printf() call can
deadlock the system waiting for an interrupt that never occurs because
interrupts are disabled. you can use printf() from within isrs safely,
but only if the device driver does not use interrupts.
hope this helps.
maurizio
<div align='right'><{post_snapback}> (index.php?act=findpost&pid=12246)
--- quote end ---
--- Quote End ---

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page