Presentation is loading. Please wait.

Presentation is loading. Please wait.

Embedded System Lab. II DMA Programming in Linux 경희대학교 컴퓨터공학과 조 진 성.

Similar presentations


Presentation on theme: "Embedded System Lab. II DMA Programming in Linux 경희대학교 컴퓨터공학과 조 진 성."— Presentation transcript:

1 Embedded System Lab. II DMA Programming in Linux 경희대학교 컴퓨터공학과 조 진 성

2 Embedded System Lab. II 2 주요내용 DMA 기본 소개 PXA255 에서의 DMA 제어기 DMA 프로그래밍 예제 PXA255 DMA 관련 레지스터 주요 내용

3 Embedded System Lab. II 3 Direct memory access Buffering Temporarily storing data in memory before processing Data accumulated in peripherals commonly buffered Microprocessor could handle this with ISR Storing and restoring microprocessor state inefficient Regular program must wait DMA controller more efficient Separate single-purpose processor Microprocessor relinquishes control of system bus to DMA controller Microprocessor can meanwhile execute its regular program  No inefficient storing and restoring state due to ISR call  Regular program need not wait unless it requires the system bus  Harvard archictecture – processor can fetch and execute instructions as long as they don’t access data memory – if they do, processor stalls

4 Embedded System Lab. II 4 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) 1(a): μP is executing its main program.1(b): P1 receives input data in a register with address 0x8000. 2: P1 asserts Int to request servicing by the microprocessor. 3: After completing instruction at 100, μP sees Int asserted, saves the PC’s value of 100, and asserts Inta. 5(a): μP jumps to the address on the bus (16). The ISR there reads data from 0x8000 and then writes it to 0x0001, which is in memory. 6: The ISR returns, thus restoring PC to 100+1=101, where μP resumes executing. 5(b): After being read, P1 deasserts Int. Time 4: P1 detects Inta and puts interrupt address vector 16 on the data bus.

5 Embedded System Lab. II 5 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) 1(a):  P is executing its main program 1(b): P1 receives input data in a register with address 0x8000. μP P1 System bus 0x8000 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x0001, R0 19: RETI # ISR return ISR 100: 101:instruction... Main program... Program memory PC Data memory 0x00000x0001 16 Int Inta instruction

6 Embedded System Lab. II 6 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) 3: After completing instruction at 100,  P sees Int asserted, saves the PC’s value of 100, and asserts Inta. μP P1 System bus 0x8000 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x0001, R0 19: RETI # ISR return ISR 100: 101:instruction... Main program... Program memory PC Data memory 0x00000x0001 16 Int Inta instruction 100 Inta 1 100

7 Embedded System Lab. II 7 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) 4: P1 detects Inta and puts interrupt address vector 16 on the data bus. μP P1 System bus 0x8000 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x0001, R0 19: RETI # ISR return ISR 100: 101:instruction... Main program... Program memory PC Data memory 0x00000x0001 16 Int Inta instruction 100 16 System bus

8 Embedded System Lab. II 8 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) μP P1 System bus 0x8000 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x8001, R0 19: RETI # ISR return ISR 100: 101:instruction... Main program... Program memory PC Data memory 0x00000x0001 16 Int instruction Inta 5(a):  P jumps to the address on the bus (16). The ISR there reads data from 0x8000 and then writes it to 0x0001, which is in memory. 5(b): After being read, P1 de-asserts Int. 100 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x8001, R0 19: ISR 100: 101:instruction... Main program... instruction RETI # ISR return System bus 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x0001, R0 19: ISR 100: 101:instruction... Main program... instruction RETI # ISR return 0x8000 P1 Data memory 0x0001 Int 0

9 Embedded System Lab. II 9 Peripheral to memory transfer (DMA 없이 vectored interrupt 사용 ) μP P1 System bus 0x8000 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x8001, R0 19: RETI # ISR return ISR 100: 101:instruction... Main program... Program memory PC Data memory 0x00000x0001 16 Int instruction Inta 6: The ISR returns, thus restoring PC to 100+1=101, where  P resumes executing. 100 +1 16:MOV R0, 0x8000 17:# modifies R0 18:MOV 0x0001, R0 19: ISR 100: 101:instruction... Main program... instruction RETI # ISR return

10 Embedded System Lab. II 10 DMA 를 이용한 Peripheral to memory transfer(1) 1(a): μP is executing its main program. It has already configured the DMA ctrl registers. 1(b): P1 receives input data in a register with address 0x8000. 2: P1 asserts req to request servicing by DMA ctrl. 7(b): P1 de-asserts req. Time 3: DMA ctrl asserts Dreq to request control of system bus. 4: After executing instruction 100, μP sees Dreq asserted, releases the system bus, asserts Dack, and resumes execution. μP stalls only if it needs the system bus to continue executing. 5: (a) DMA ctrl asserts ack (b) reads data from 0x8000 and (b) writes that data to 0x0001. 6:. DMA de-asserts Dreq and ack completing handshake with P1. 7(a): μP de-asserts Dack and resumes control of the bus.

11 Embedded System Lab. II 11 DMA 를 이용한 Peripheral to memory transfer(2) 1(a):  P is executing its main program. It has already configured the DMA ctrl registers 1(b): P1 receives input data in a register with address 0x8000. Data memory μP DMA ctrlP1 System bus 0x8000 101: instruction... Main program... Program memory PC 100 Dreq Dack 0x00000x0001 100: No ISR needed! 0x0001 0x8000 ack req

12 Embedded System Lab. II 12 DMA 를 이용한 Peripheral to memory transfer(3) 2: P1 asserts req to request servicing by DMA ctrl. 3: DMA ctrl asserts Dreq to request control of system bus Data memory μP DMA ctrlP1 System bus 0x8000 101: instruction... Main program... Program memory PC 100 Dreq Dack 0x00000x0001 100: No ISR needed! 0x0001 0x8000 ack req 1 P1 Dreq 1 DMA ctrlP1

13 Embedded System Lab. II 13 DMA 를 이용한 Peripheral to memory transfer(4) 4: After executing instruction 100,  P sees Dreq asserted, releases the system bus, asserts Dack, and resumes execution,  P stalls only if it needs the system bus to continue executing. Data memory μP DMA ctrlP1 System bus 0x8000 101: instruction... Main program... Program memory PC 100 Dreq Dack 0x00000x0001 100: No ISR needed! 0x0001 0x8000 ack req Dack 1

14 Embedded System Lab. II 14 DMA 를 이용한 Peripheral to memory transfer(5) Data memory μP DMA ctrlP1 System bus 0x8000 101: instruction... Main program... Program memory PC 100 Dreq Dack 0x00000x0001 100: No ISR needed! 0x0001 0x8000 ack req Data memory DMA ctrlP1 System bus 0x8000 0x00000x0001 0x8000 ack req 5: DMA ctrl (a) asserts ack, (b) reads data from 0x8000, and (c) writes that data to 0x0001. (Meanwhile, processor still executing if not stalled!) ack 1

15 Embedded System Lab. II 15 DMA 를 이용한 Peripheral to memory transfer(6) 6: DMA de-asserts Dreq and ack completing the handshake with P1. Data memory μP DMA ctrlP1 System bus 0x8000 101: instruction... Main program... Program memory PC 100 Dreq Dack 0x00000x0001 100: No ISR needed! 0x0001 0x8000 ack req ack 0 Dreq 0

16 Embedded System Lab. II 16 Arbitration: Priority arbiter Consider the situation where multiple peripherals request service from single resource (e.g., microprocessor, DMA controller) simultaneously - which gets serviced first? Priority arbiter Single-purpose processor Peripherals make requests to arbiter, arbiter makes requests to resource Arbiter connected to system bus for configuration only Micro- processor Priority arbiter Peripheral1 System bus Int 3 5 7 Inta Peripheral2 Ireq1 Iack2 Iack1 Ireq2 22 6

17 Embedded System Lab. II 17 Arbitration using a priority arbiter 1. Microprocessor is executing its program. 2. Peripheral1 needs servicing so asserts Ireq1. Peripheral2 also needs servicing so asserts Ireq2. 3. Priority arbiter sees at least one Ireq input asserted, so asserts Int. 4. Microprocessor stops executing its program and stores its state. 5. Microprocessor asserts Inta. 6. Priority arbiter asserts Iack1 to acknowledge Peripheral1. 7. Peripheral1 puts its interrupt address vector on the system bus 8. Microprocessor jumps to the address of ISR read from data bus, ISR executes and returns (and completes handshake with arbiter). 9. Microprocessor resumes executing its program. Micro- processor Priority arbiter Peripheral1 System bus Int 3 5 7 Inta Peripheral2 Ireq1 Iack2 Iack1 Ireq2 22 6

18 Embedded System Lab. II 18 Arbitration: Priority arbiter Types of priority Fixed priority  each peripheral has unique rank  highest rank chosen first with simultaneous requests  preferred when clear difference in rank between peripherals Rotating priority (round-robin)  priority changed based on history of servicing  better distribution of servicing especially among peripherals with similar priority demands

19 Embedded System Lab. II 19 Arbitration: Daisy-chain arbitration Arbitration done by peripherals Built into peripheral or external logic added  req input and ack output added to each peripheral Peripherals connected to each other in daisy-chain manner One peripheral connected to resource, all others connected “upstream” Peripheral’s req flows “downstream” to resource, resource’s ack flows “upstream” to requesting peripheral Closest peripheral has highest priority PP System bus Int Inta Peripheral1 Ack_inAck_out Req_outReq_in Peripheral2 Ack_inAck_out Req_outReq_in Daisy-chain aware peripherals 0

20 Embedded System Lab. II 20 Arbitration: Daisy-chain arbitration Pros/cons Easy to add/remove peripheral - no system redesign needed Does not support rotating priority One broken peripheral can cause loss of access to other peripherals Micro- processor Priority arbiter Peripheral 1 System bus Int Inta Peripheral 2 Ireq1 Iack2 Iack1 Ireq2 PP System bus Int Inta Peripheral1 Ack_inAck_out Req_outReq_in Peripheral2 Ack_inAck_out Req_outReq_in Daisy-chain aware peripherals 0

21 Embedded System Lab. II 21 DMA Controller(DMAC) - PXA255 DMAC 는 내부 및 외부 주변장치에 의해 발생된 요청에 대한 응답으로 메 인 메모리로 혹은 메인 메모리로부터 데이터를 전달 DMAC 는 16 개의 DMA channels 지원 DMAC 는 flow-through transfers 만을 지원 Flow-through data 는 데이터가 목적지에 저장되기 전에 DMAC 를 통해 전 달됨 DMAC 는 flow-through transfers 를 이용해서 memory-to-memory moves 를 수행할 수 있음 DMAC Channels 각 채널은 4 개의 32-bit registers 에 의해 제어 각 채널은 내부 / 외부 장치중의 하나를 서비스하도록 구성 Each channel is serviced in increments of the peripheral device’s burst size Each channel is delivered in the granularity appropriate to that device’s port width.

22 Embedded System Lab. II 22 DMA Channel The burst size and port width for each device is programmed in the channel registers and is based on the device’s FIFO depth and bandwidth needs. When multiple channels are actively executing, the DMAC services each channel is serviced with a burst of data. After the data burst is sent, the DMAC may perform a context switch to another active channel. The DMAC performs context switches based on a channel’s activity, whether its target device is currently requesting service, and where that channel lies in the priority scheme. Channel information must be maintained on a per-channel basis and is contained in the DMAC registers see in Table 5-13, “DMA Controller Registers” on page 5-28. The DMAC supports two methods of loading the DMAC register, No- Descriptor and Descriptor Fetch Modes. Software must ensure cache coherency when it configures the DMA channels.

23 Embedded System Lab. II 23 DMAC Block Diagram Memory Controller System Bus(internal) Control Register DMA Controller 16 DMA Channels DREQ[1:0] (external) PREQ[37:0] (internal) Peripheral Bus(internal) DMA_IRQ (internal) Channel 0 Channel 15 DDADR 0 DSADR 0 DTADR 0 DCMD 0 DINT DRCMR 0 DSCR 0

24 Embedded System Lab. II 24 DMA Signal Descriptions The DREQ[1:0], PREQ[37:0] and DMA_IRQ signals are controlled by the DMAC The DREQ[1:0] signal must remain asserted for four MEMCLKs to allow the DMA to recognize the 0 to 1 transition. When the DREQ[1:0] signals are deasserted, they must remain deasserted for at least four MEMCLKs. The DMAC registers the transition from 0 to 1 to identify a new request. The external companion chip must not assert another DREQ until the previous DMA data transfer starts

25 Embedded System Lab. II 25 DMA Signal Descriptions The DREQ[1:0], PREQ[37:0] and DMA_IRQ signals are controlled by the DMAC

26 Embedded System Lab. II 26 DMA_IRQ Signal The application processor has 16 IRQ signals, one for each DMA channel. Each DMA IRQ can be read in the DINT register. The user can mask some bits that cause interrupts on a channel, such as ENDIRQEN, STARTIRQEN, and STOPIRQEN. When DMA interrupt occurs, it is visible in Pending Interrupt Register Bit. When a pending interrupt becomes active, it is sent to the CPU if its corresponding ICMR mask Bit.

27 Embedded System Lab. II 27 DMA Channel Priority Scheme The DMA channel priority scheme allows peripherals that require high bandwidth to be serviced more often than those requiring less bandwidth. The DMA channels are internally divided into four sets. Each set contains four channels. The channels get a round-robin priority in each set. Set zero has the highest priority. Set 1 has higher priority than sets two and three. Sets two and three are low priority sets. High bandwidth peripherals must be programmed in set zero. Memory-to-memory moves and low bandwidth peripherals must be programmed in set two or three. When all channels are running concurrently, set zero is serviced four times out of any eight consecutive channel servicing instances. Set one is serviced twice and sets two and three are each serviced once.

28 Embedded System Lab. II 28 DMA Channel Priority Scheme(2) If all channels request data transfers, the Sets are prioritized in following order: Set zero -> Set one -> Set zero -> Set two -> Set zero -> Set one -> Set zero -> Set three

29 Embedded System Lab. II 29 DMA Descriptors DMAC 동작모드 Descriptor Fetch Mode 와 No-Descriptor Fetch Mode 모드는 DCSRx[NODESCFETCH] bit 에 의해 결정 모드는 각 채널에 대해 독립적으로 동시에 사용 가능 각 채널은 동작모드를 바꿀 때는 일단 정지해야만 함

30 Embedded System Lab. II 30 No-Descriptor Fetch Mode DDADRx is reserved. Software must not write to the DDADRx and must load the DSADRx, DTADRx, and DCMDx registers. When the Run bit is set, the DMAC immediately begins to transfer data The channel stops when it finishes the transfer.

31 Embedded System Lab. II 31 No-Descriptor Fetch Mode 1. The channel is in an uninitialized state after reset. 2. The DCSR[RUN] bit is set to a 0 and the DCSR[NODESCFETCH] bit is set to a 1. 3. The software writes a source address to the DSADR register, a target address to the DTADR register, and a command to the DCMD register. The DDADR register is reserved in this No-Descriptor Fetch Mode and must not be written. 4. The software writes a 1 to the DCSR[RUN] bit and the No-Descriptor fetches are performed. 5. The channel waits for the request or starts the data transfer, as determined by the DCMD[FLOW] source and target bits. 6. The channel transmits a number of bytes equal to the smaller of DCMD[SIZE] and DCMD[LENGTH]. 7. The channel waits for the next request or continues with the data transfer until the DCMD[LENGTH] reaches zero. 8. The DDADR[STOP] is set to a 1 and the channel stops.

32 Embedded System Lab. II 32 Descriptor Fetch Mode DMAC registers are loaded from DMA descriptors in main memory. Multiple DMA descriptors can be chained together in a list. The descriptor’s protocol design allows descriptors to be added efficiently to the descriptor list of a running DMA stream.

33 Embedded System Lab. II 33 Descriptor Fetch Mode 1. The channel is in an uninitialized state after reset. 2. The software writes a descriptor address (aligned to a 16-byte boundary) to the DDADR register. 3. The software writes a 1 to the DCSR[RUN] bit. 4. The DMAC fetches the four-word descriptor from the memory indicated by DDADR. 5. The four-word DMA descriptor, aligned on a 16-byte boundary in main memory, loads the following registers: a. Word [0] -> DDADRx register and a single flag bit. Points to the next four-word descriptor. b. Word [1] -> DSADRx register for the current transfer. c. Word [2] -> DTADRx register for the current transfer. d. Word [3] -> DCMDx register for the current transfer.

34 Embedded System Lab. II 34 Descriptor Fetch Mode 6. The channel waits for the request or starts the data transfer, as determined by the DCMD[FLOW] source and target bits. 7. The channel transmits a number of bytes equal to the smaller of DCMD[SIZE] and DCMD[LENGTH]. 8. The channel waits for the next request or continues with the data transfer until the DCMD[LENGTH] reaches zero. 9. The channel stops or continues with a new descriptor fetch from the memory, as determined by the DDADR[STOP] bit. Software must set the DCSR[RUN] bit to 1 after it loads the DDADR. The channel descriptor fetch does not take place unless the DDADR register is loaded and the DCSR[RUN] bit is set to a 1. The DMAC priority scheme does not affect DMA descriptor fetches. The next descriptor is fetched immediately after the previous descriptor is serviced

35 Embedded System Lab. II 35 Byte Transfer Order The DCMD[ENDIAN] bit indicates the byte ordering in a word when data is read from or written to memory. The DCMD[ENDIAN] bit must be set to 0, which is little endian transfers. If data is being transferred from an internal device to memory, DCMD[ENDIAN] is set to a 0, and DCMD[SIZE] is set to a 1, the memory receives the data in the following order:  1. Byte[0]  2. Byte[1]  3. Byte[2]  4. Byte[3]

36 Embedded System Lab. II 36 Byte Transfer Order(2)

37 Embedded System Lab. II 37 Servicing Internal Peripherals The DMAC provides the DMA Request to Channel Map Registers (DRCMRx) that contain four bits used to assign a channel number for each possible DMA request. An internal peripheral can be mapped to any of the 16 available channels.

38 Embedded System Lab. II 38 Using Flow-Through DMA Read Cycles to Service Internal Peripherals A flow-through DMA read for an internal peripheral begins when the internal peripheral sends a request, via the PREQ bus, to a DMAC channel that is running and configured for a flow-through read. The number of bytes to be transferred is specified with DCMDx[SIZE]. When the request is the highest priority request, the following process begins: 1. The DMAC sends the memory controller a request to read the number of bytes addressed by DSADRx[31:0] into a 32-byte staging buffer in the DMAC. 2. The DMAC transfers the data to the I/O device addressed in DTADRx[31:0]. DCMD[WIDTH] specifies the width of the internal peripheral to which the data is transferred. 3. At the end of the transfer, DSADRx is increased by the smaller value of DCMDx[LENGTH] and DCMD[SIZE]. DCMDx[LENGTH] is decreased by the same value.

39 Embedded System Lab. II 39 Using Flow-Through DMA Read Cycles to Service Internal Peripherals For a flow-through DMA read to an internal peripheral, use the following settings for the DMAC register bits: DSADR[SRCADDR] = external memory address DTADR[TRGADDR] = internal peripheral’s address DCMD[INCSRCADDR] = 1 DCMD[FLOWSRC] = 0 DCMD[FLOWTRG] = 1

40 Embedded System Lab. II 40 Using Flow-Through DMA Write Cycles to Service Internal Peripherals A flow-through DMA write for an internal peripheral begins when the internal peripheral sends a request, via the PREQ bus, to a DMAC channel that is running and configured for a flow-through write. The number of bytes to be transferred are specified with DCMDx[SIZE]. When the request is the highest priority request, the following process begins: 1. The DMAC transfers the required number of bytes from the I/O device addressed by DSADRx[31:0] to the DMAC write buffer. 2. The DMAC transfers the data to the memory controller via the internal bus. DCMD[WIDTH] specifies the width of the internal peripheral to which the transfer is being made. 3. At the end of the transfer, DTADRx is increased by the smaller value of DCMDx[LENGTH] and DCMD[SIZE]. DCMDx[LENGTH] is decreased by the same number.

41 Embedded System Lab. II 41 Using Flow-Through DMA Write Cycles to Service Internal Peripherals For a flow-through DMA write to an internal peripheral, use the following settings for the DMAC register bits: DSADR[SRCADDR] = internal peripheral address DTADR[TRGADDR] = external memory address DCMD[INCTRGADDR] = 1 DCMD[FLOWSRC] = 1 DCMD[FLOWTRG] = 0

42 Embedded System Lab. II 42 Using Flow-Through DMA Write Cycles to Service Internal Peripherals A flow-through DMA read for an external peripheral begins when the external peripheral sends a request, via the DREQ[1:0] bus, to a DMAC channel that is running and configured for a flow-through read. DCMDx[SIZE] specifies the number of bytes to be transferred. When the request is the highest priority request, the follow process begins. 1. The DMAC sends a request to the memory controller to read the number of bytes addressed by DSADRx[31:0] into a 32-byte staging buffer in the DMAC. 2. The DMAC transfers the data in the buffer to the external device addressed in DTADRx[31:0]. 3. At the end of the transfer, DSADRx is increased by the smaller value of DCMDx[LENGTH] and DCMD[SIZE]. DCMDx[LENGTH] is decreased by the same value. Note: The process shown for a flow-through DMA read to an external peripheral indicates that the external address increases. Some external peripherals, such as FIFOs, do not require an increment in the external address.

43 Embedded System Lab. II 43 Using Flow-Through DMA Read Cycles to Service External Peripherals For a flow-through DMA read to an external peripheral, use the following settings for the DMAC register bits: DSADR[SRCADDR] = external memory address DTADR[TRGADDR] = companion chip’s address DCMD[INCSRCADDR] = 1 DCMD[INCTRGADDR] = 0 DCMD[FLOWSRC] = 0 DCMD[FLOWTRG] = 1

44 Embedded System Lab. II 44 Using Flow-Through DMA Write Cycles to Service External Peripherals A flow-through DMA write to an external peripheral begins when the external peripheral sends a request, via the DREQ bus, to a DMAC channel that is running and configured for a flow-through write. DCMDx[SIZE] specifies the number of bytes to be transferred. When the request is the highest priority request, the following process begins: 1. The DMAC transfers the required number of bytes from the I/O device addressed by DSADRx[31:0] to the DMAC write buffer. 2. The DMAC transfers the data to the memory controller via the internal bus. 3. At the end of the transfer, DTADRx is increased by the smaller value of DCMDx[LENGTH] and DCMD[SIZE]. DCMDx[LENGTH] is decreased by the same number. Note:The process shown for a flow-through DMA write to an external peripheral indicates that the external address increases. Some external peripherals, such as FIFOs, do not require an increment in the external address.

45 Embedded System Lab. II 45 Using Flow-Through DMA Write Cycles to Service External Peripherals For a flow-through DMA write to an external peripheral, use the following settings for the DMAC register bits: DSADR[SRCADDR] = companion chip address DTADR[TRGADDR] = external memory address. DCMD[INCSRCADDR] = 0 DCMD[INCTRGADDR] = 1 DCMD[FLOWSRC] = 1 DCMD[FLOWTRG] = 0

46 Embedded System Lab. II 46 Memory-to-Memory Moves Memory-to-memory moves do not involve the DREQ and PREQ request signals. The processor writes to the DCSR[RUN] bit and a channel is configured for a memory-to-memory move. The DCMDx[FLOWSRC] and the DCMD[FLOWTRG] bits must be set to 0. If DCMD[IRQEN] is set to a 1, a DMA interrupt is requested at the end of the last cycle associated with the byte that caused DCMDx[LENGTH] to decrease from 1 to 0.

47 Embedded System Lab. II 47 Memory-to-Memory Moves A flow-through DMA memory-to-memory read or write goes through the following steps: 1. The processor writes to the DCSR[RUN] register bit and starts the memory-to-memory moves. 2. If the application processor is in the Descriptor Fetch Mode, the channel configured for the move fetches the four-word descriptor. The channel transfers data without waiting for PREQ or DREQ to be asserted. The smaller value of DCMDx[SIZE] or DCMDx[LENGTH] specifies the number of bytes to be transferred. 3. The DMAC sends a request to the memory controller to read the number of bytes addressed by DSADRx[31:0] into a 32-byte staging buffer in the DMAC. 4. The DMAC generates a write cycle to the location addressed in DTADRx[31:0]. 5. At the end of the transfer, DSADRx and DTADRx are increased by the smaller value of DCMD[SIZE] and DCMDx[LENGTH]. If DCMD[SIZE] is smaller than DCMDx[LENGTH], DCMDx[LENGTH] is decreased by DCMD[SIZE]. If DCMD[SIZE] is equal to or larger than DCMDx[LENGTH], DCMDx[LENGTH] is zero.

48 Embedded System Lab. II 48 Memory-to-Memory Moves For a memory-to-memory read or write, use the following settings for the DMAC registers: DSADR[SRCADDR] = external memory address DTADR[TRGADDR] = external memory address DCMD[INCSRCADDR] = 1 DCMD[INCTRGADDR] = 1 DCMD[FLOWSRC] = 0 DCMD[FLOWTRG] = 0 DCSR[RUN] =1

49 Embedded System Lab. II 49 Using Flow-Through DMA Write Cycles to Service External Peripherals For a flow-through DMA write to an external peripheral, use the following settings for the DMAC register bits: DSADR[SRCADDR] = companion chip address DTADR[TRGADDR] = external memory address. DCMD[INCSRCADDR] = 0 DCMD[INCTRGADDR] = 1 DCMD[FLOWSRC] = 1 DCMD[FLOWTRG] = 0

50 Embedded System Lab. II 50 DMA 예제 프로그램 기본적인 DMA 동작을 이해하기 위한 프로그램 작성 Memory-to-Memory Data transfer 를 위한 sample code 작성

51 Embedded System Lab. II 51 DMA sample code(1) /* dma_driver.c - driver module */ /* DMA Example : DMA Memory-To-Memory Data Transfer Programmed by Yoo, Sangshin(Sungkonghoe University). */ #include #include // consistent_alloc, consistent_free

52 Embedded System Lab. II 52 DMA sample code(2) #define DEVICE_NAME "DMA" #define DMA_LENGTH 2000 #define DCMD_MEMTOMEM (DCMD_INCSRCADDR | DCMD_INCTRGADDR | DCMD_BURST32 | DCMD_WIDTH4) /* Global Variables */ static int s_nMajor = 0; MODULE_LICENSE("GPL"); /* Device Operations */ static void dma_irq(int ch, void *dev_id, struct pt_regs *regs); static ssize_t dma_read(struct file *filp, char *buf, size_t count, loff_t *l); static int dma_open(struct inode *inode, struct file *filp); int dma_release(struct inode *inode, struct file *pfile); static struct file_operations device_fops = { read:dma_read, open:dma_open, release:dma_release, };

53 Embedded System Lab. II 53 DMA sample code (3) dma_addr_t dma_A_phys; dma_addr_t dma_B_phys; char *dma_A; char *dma_B; static u_int ch; static DECLARE_WAIT_QUEUE_HEAD(wait_queue); /* Module startup/cleanup */ int init_module(void) { printk(DEVICE_NAME " : Loading DMA Memory-To-Memory Copy Module\n"); if ((s_nMajor = register_chrdev(0, DEVICE_NAME, &device_fops)) < 0) { printk(DEVICE_NAME " : Device registration failed (%d)\n", s_nMajor); return s_nMajor; } printk(DEVICE_NAME " : Device registered with Major Number = %d\n", s_nMajor); return 0; }

54 Embedded System Lab. II 54 DMA sample code (4) void cleanup_module(void){ int nRetCode; printk(DEVICE_NAME " : Unloading DMA Memory-To-Memory Copy Module\n"); if ((nRetCode = unregister_chrdev(s_nMajor, DEVICE_NAME)) < 0) printk(DEVICE_NAME " : Device unregistration failed (%d)\n", nRetCode); } static void dma_irq(int ch, void *dev_id, struct pt_regs *regs){ u_int dcsr; dcsr = DCSR(ch); DCSR(ch) = dcsr & ~DCSR_STOPIRQEN; if (dcsr & DCSR_BUSERR) printk(DEVICE_NAME " : M-to-M DMA: bus error on channel %d\n", ch); if (dcsr & DCSR_ENDINTR) printk(DEVICE_NAME " : M-to-M DMA: ENDINTR error on channel %d\n", ch); if (dcsr & DCSR_STOPIRQEN) printk(DEVICE_NAME " : M-to-M DMA: STOPIRQEN error on channel %d\n", ch); if (dcsr & DCSR_STOPSTATE) printk(DEVICE_NAME " : M-to-M DMA: STOPSTATE error on channel %d\n", ch); wake_up_interruptible(&wait_queue); } DMA 동작이 정상적으로 완료 되면 해당 인터럽트 발생

55 Embedded System Lab. II 55 DMA sample code (5) static ssize_t dma_read(struct file *filp, char *buf, size_t count, loff_t *l) { DCSR(ch) = DCSR_NODESC; DSADR(ch) = dma_A_phys; // physical address required DTADR(ch) = dma_B_phys; DCMD(ch) = DCMD_MEMTOMEM | DCMD_ENDIRQEN | DMA_LENGTH; DCSR(ch) |= DCSR_RUN; interruptible_sleep_on(&wait_queue); if (!strncmp(dma_A, dma_B, DMA_LENGTH)) copy_to_user(buf, "sucess", sizeof("sucess")); else copy_to_user(buf, "fail", sizeof("fail")); return 0; } DMA 를 동작시키기 위한 레지 스터 설정 - 순서와 값은 앞 부 분에 설명된 DMAC 참조

56 Embedded System Lab. II 56 DMA sample code (6) static int dma_open(struct inode *inode, struct file *filp) { ch = pxa_request_dma(DEVICE_NAME, DMA_PRIO_HIGH, dma_irq, 0); if (ch < 0 ){ printk(DEVICE_NAME " : dma request failed (%d)\n", s_nMajor); return -1; } printk(DEVICE_NAME " : dma request success (%d)\n", ch); dma_A =(char*)consistent_alloc(GFP_KERNEL, DMA_LENGTH, &dma_A_phys); if(!dma_A){ printk(DEVICE_NAME " : dma_A Memory allocation error\n"); if (ch){ pxa_free_dma(ch); return -1; } dma_B = (char*)consistent_alloc(GFP_KERNEL, DMA_LENGTH, &dma_B_phys); if(!dma_B){ printk(DEVICE_NAME " : dma_B Memory allocation error\n"); if (ch) pxa_free_dma(ch); consistent_free(dma_A, DMA_LENGTH, (dma_addr_t)&dma_A_phys); return -1; } No-cached 메모리 할당

57 Embedded System Lab. II 57 DMA sample code (7) printk(DEVICE_NAME " : Memory allocation Sucess\n"); printk(DEVICE_NAME " : Source Adress - 0x%x\n", dma_A_phys); printk(DEVICE_NAME " : Target Adress - 0x%x\n", dma_B_phys); memset(dma_A, 'A', DMA_LENGTH); memset(dma_B, 'B', DMA_LENGTH); MOD_INC_USE_COUNT; return 0; } int dma_release(struct inode *inode, struct file *pfile){ MOD_DEC_USE_COUNT; if(ch) pxa_free_dma(ch); consistent_free(dma_A, DMA_LENGTH, (dma_addr_t)&dma_A_phys); consistent_free(dma_B, DMA_LENGTH, (dma_addr_t)&dma_B_phys); return 0; }

58 Embedded System Lab. II 58 DMA test 응용 프로그램 #include /* dma_test.c */ #include static int dev; int main(void){ char buff[12]; dev = open("/dev/dma",O_RDWR); if(dev < 0) { printf( "Device Open ERROR!\n"); exit(1); } read(dev, buff, sizeof(buff)); printf("\nDMA Memory-To-Memory Copy Result\n"); if (!strcmp(buff, "sucess")) printf(" : Sucess!\n"); else printf(" : Fail!\n"); close(dev); return 0; }

59 Embedded System Lab. II 59 Makefile 작성 # DMA module Makefile /* Makefile */ CC = arm-linux-gcc # PXA255-Pro KERNELDIR = /root/PXA255-Pro/Kernel/linux-2.4.19-pxa255 INCLUDEDIR = $(KERNELDIR)/include CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR) OBJS = dma_driver.o dma_test.o all : $(OBJS) dma_test dma_test : dma_test.o $(CC) -o $@ $^ clean : rm -f dma_test *.o *~

60 Embedded System Lab. II 60 DMA sample 실행 (1) DMA 모듈 컴파일 방법 DMA 모듈 실행 방법 생성된 dma_driver.o, dma_test 파일을 타겟 보드로 전송 chmod 755 dma_test 로 실행권한 설정 insmod 로 dma_driver 모듈을 커널에 loading mknod /dev/dma c 253 0 실행./dma_test 실행 실행결과 확인 rmmod 로 dma_driver 모듈을 커널에 unloading # make

61 Embedded System Lab. II 61 DMA sample 실행 (2) DMA 모듈 컴파일

62 Embedded System Lab. II 62 DMA sample 실행 (3) DMA sample 실행

63 Embedded System Lab. II 63 DINT(DMA Interrupt Register) RESERVED Read ad unknown and must be written as zero CHLINTRx Channel ‘x’ Interrupt (read-only). 0 = no interrupt 1= interrupt 0000 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

64 Embedded System Lab. II 64 DCSRx(DMA Channel Control/status Register)(1) RUN Run bit(read/write) 0 : stops the channel 1 : starts the channel NODESCFETCH No-Descriptor Fetch(read/write) 0 : Descriptor Fetch Mode 1 : No-Descriptor Fetch Mode STOPIRQEN Stop Interrupt Enable(read/write) 0 : No Interrupt 1 : Enable an Interrupt RESERVED Read ad unknown and must be written as zero REQPEND Request Pending(read-only) 0 : no pending request 1 : the channel has a pending request Reserved RESERVED STOPSTATE STARTINTR ENDINTR STOPIRQEN NODESCFETCH RUN REQPEND 0000 1000 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28 BUSERRINTR

65 Embedded System Lab. II 65 DCSRx(DMA Channel Control/status Register)(2) RESERVED Read ad unknown and must be written as zero STOPSTATE Stop State(read-only) 0 : channel is running 1 : channel is in uninitialized or stopped state ENDINT End Interrupt(read/write) 0 : no interrupt 1 : interrupt caused because the current transaction was successfully completed and DCMD[LENGTH]=0 STARINTR Start Interrupt(read/write) 0 : no interrupt 1 : interrupt caused due to successful descriptor fetch BUSERRINTR Bus Interrupt(read/write) 0 : no interrupt 1 : bus error caused interrupt Reserved RESERVED STOPSTATE STARTINTR BUSERRINTR ENDINTR STOPIRQEN RUN REQPEND 0000 1000 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

66 Embedded System Lab. II 66 DRCMRx(DMA Request to Channel Map Registers) RESERVED Read ad unknown and must be written as zero MAPVLD Map Valid (read / write). 0 = Request is unmapped 1 = Request is mapped to a channel indicated by DRCMRx[3:0] Determines whether the request is mapped to a channel or not. If the bit is set to a 1, the request is mapped to a channel indicated in DRCMRx[3:0]. If the bit is 0, the request is unmapped. This bit can also be used to mask the request. CHLNUM Channel Number (read / write). Indicates the channel number if DRCMR[MAPVLD] is set to a 1. Do not map two active requests to the same channel. It produces unpredictable results. Refer to “DMA Channel Priority Scheme” to review the channel priority scheme. CHLNUM MAPVLD Reserved 0000 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

67 Embedded System Lab. II 67 DDADRx(DMA Descriptor Address Register) STOP STOP(read/write) 0 : Run channel 1 : Stop channel RESERVED Read as unknown and must be written as zero DESCRIPTOR ADDRESS Address of next descriptor(read/write) DESCRIPTOR ADDRESSRESERVED STOP ???? ???0 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

68 Embedded System Lab. II 68 DSADRx(DMA Source Address Register) RESERVED Read as unknown and must be written as zero SRCADDR Source Address (read / write). Address of the internal peripheral or address of a memory location. Address of a memory location for companion -chip transfer SRCADDR Source Address Bit 2 RESERVED if DSADR.SrcAddr is an external memory location Not reserved if DSADR.SrcAddr is an internal peripheral (read / write). SRCADDR(SOURCE ADDRESS) RESERVED ???? ??00 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

69 Embedded System Lab. II 69 DTADRx(DMA Target Address Register) RESERVED Read as unknown and must be written as zero TRGADDR Target Address (read / write): Address of the on chip peripheral or the address of a memory location Address of a memory location for companion chip transfer TRGADDR Target Address Bit 2 RESERVED if DTADR.TrgAddr is an external memory location Not reserved if DTADR.trgAddr is an internal peripheral (read / write). TRGADDR(TARGET ADDRESS) RESERVED ???? ??00 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

70 Embedded System Lab. II 70 DCMDx(DMA Command Register)(1) INCSRCADDR Source Address Increment Setting. (read / write). 0 = Do not increment Source Address 1 = Increment Source Address at the end of each internal bus transaction initiation by DCMD[SIZE] If the source address is an internal peripheral’s FIFO address or external IO address, the address is not incremented on each successive access. In this case, this bit must be 0. INCTRGADDR Target Address Increment Setting. (read / write). 0 = Do not increment Target Address 1 = Increment Target Address at the end of each internal bus transaction initiated by DCMD[SIZE] If the target address is an internal peripheral’s FIFO address or external IO address, the address is incremented on each successive access. In this cases the bit must be 0. FLOWSRC Flow Control by the source. (read / write). 0 = Start the data transfer immediately. 1 = Wait for a request signal before initiating the data transfer. Indicates the flow control of the source. This bit must be ‘1’ if the source is an onchip or external peripheral. If either the DCMD[FLOWSRC] or DCMD[FLOWTRG] bit is set, the current DMA does not initiate a transfer until it receives a request. Do not set both the DCMD[FLOWTRG] and DCMD[FLOWSRC] bit to1. 0000 3 2 1 07 6 5 411 10 9 815 14 13 1219 18 17 1623 22 21 2027 26 25 2431 30 29 28

71 Embedded System Lab. II 71 DCMDx(DMA Command Register)(2) FLOWTRG Flow Control by the target. (read / write). 0 = Start the data transfer immediately. 1 = Wait for a request signal before initiating the data transfer. Indicates the Flow Control of the target. This bit must be ‘1’ if the target is an onchip or external peripheral. If either the DCMD[FLOWSRC] or DCMD[FLOWTRG] bit is set, the current DMA does not initiate a transfer until it receives a request. Do not set both the DCMD[FLOWTRG] and DCMD[FLOWSRC] bit to 1. STARTIRQEN Start Interrupt Enable (read / write), Reserved for the No-Descriptor Fetch Mode 0 = no interrupt is generated. 1 = Allow interrupt to pass when the descriptor (i.e., 4 words) for the channel are loaded. Sets DCSR[StartIntr] interrupt for the channel when this descriptor is loaded. ENDIRQEN End Interrupt Enable (read / write). 0 = no interrupt is generated. 1 = set DCSR[EndIntr] interrupt for the channel when DCMD[LENGTH] is decreased to zero. Indicates that the interrupt is enabled as soon as the data transfer is completed. RESERVED Read ad unknown and must be written as zero

72 Embedded System Lab. II 72 DCMDx(DMA Command Register)(3) ENDIAN Device Endian-ness. (read / write). 0 = Byte ordering is little endian 1 = RESERVED SIZE Maximum Burst Size of each data transferred (read / write). 00 = RESERVED, 01 = 8 Bytes 10 = 16 Bytes11 = 32 Bytes If DCMDx[LENGTH] is less than DCMDx[SIZE] the data transfer size equals DCMDx[LENGTH]. WIDTH Width of the on-chip peripheral. (read / write/). 00 = Reserved01 = 1 byte 10 = HalfWord (2 bytes)11 = Word (4 Bytes) Must be programmed 00 for memory-to-memory moves or companion-chip related operations. LENGTH Length of transfer in bytes. (read / write). Indicates the length of transfer in bytes. DCMD[LENGTH] = 0 means zero bytes for Descriptor Fetch Mode only. DCMD[LENGTH] = 0 is an invalid setting for the No-Descriptor Fetch Mode. The maximum transfer length is (8K-1) bytes. If the transfer involves any of the internal peripherals, the length of the transfer must be an integer multiple of the width of that peripheral.


Download ppt "Embedded System Lab. II DMA Programming in Linux 경희대학교 컴퓨터공학과 조 진 성."

Similar presentations


Ads by Google