码迷,mamicode.com
首页 > 其他好文 > 详细

Learn ZYNQ(2)

时间:2014-05-30 23:22:27      阅读:890      评论:0      收藏:0      [点我收藏+]

标签:des   c   style   class   blog   code   

AXI HP接口的DMA+GIC编程(参照博客

参照文档:UG873,博客文档

我的Vivado+SDK工程文件打包(60+M)

我的DMA驱动程序(未完成)

Vivado 接线图:

bubuko.com,布布扣

地址分配:

 

bubuko.com,布布扣

standalone代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
#include <stdio.h>
//#include "platform.h"
#include "xaxicdma.h"
#include "xdebug.h"
#include "xil_exception.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xscugic.h"
//包含头文件,不必多言
#define NUMBER_OF_TRANSFERS 2     /* 做两次传输 */
#define DMA_CTRL_DEVICE_ID     XPAR_AXICDMA_0_DEVICE_ID     //DMA控制设备ID号=
#define INTC_DEVICE_ID         XPAR_SCUGIC_SINGLE_DEVICE_ID     //GIC控制设备ID号=
#define DMA_CTRL_IRPT_INTR       XPAR_FABRIC_AXI_CDMA_0_CDMA_INTROUT_INTR      //中断号
volatile static int Done = 0;   /* Dma transfer is done */
volatile static int Error = 0;   /* Dma Bus Error occurs */
static u32 SourceAddr  = 0x10000000;    // =0x10000000
static u32 DestAddr      = 0x18000000;    // = 0x18000000
 
static XAxiCdma AxiCdmaInstance;     /* XAxiCdma  控制对象*/
static XScuGic IntcController;      /* Interrupt Controller  控制对象*/
 
 
static int Array_3[32][16];     //阵列
static int Array_4[32][16];
static int Array_1[32][16];
static int Array_2[32][16];
int const input[16] = {0xb504f33, 0xabeb4a0, 0xa267994, 0x987fbfc, 0x8e39d9c, 0x839c3cc, 0x78ad74c, 0x6d743f4, 0x61f78a8, 0x563e6a8, 0x4a5018c, 0x3e33f2c, 0x31f1704, 0x259020c, 0x1917a64, 0xc8fb2c};
/* Length of the buffers for DMA transfer */
static u32 BUFFER_BYTESIZE   = (XPAR_AXI_CDMA_0_M_AXI_DATA_WIDTH * XPAR_AXI_CDMA_0_M_AXI_MAX_BURST_LEN);      //大小为1024*256/8=32KB,起始就是我们在XPS中设置好的
static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries);//执行传输
static void DisableIntrSystem(XScuGic *IntcInstancePtr , u32 IntrId)//禁止中断
{
              XScuGic_Disable(IntcInstancePtr ,IntrId );
              XScuGic_Disconnect(IntcInstancePtr ,IntrId );
}
//Multiply and Shift
int MUL_SHIFT_30(int x, int y)//实现x*y,但又怕溢出,所以右移30位,除以2^30~1e9
{
 return ((int) (((long long) (x) * (y)) >> 30));
}
void MULT_SHIFT_LOOP(int Value )//生成源数据的函数
{
   int i, j;
   for (i = 0; i < 32; i++) {
      for (j = 0; j < 16; j++) {
             Array_3[i][j] = (int)((MUL_SHIFT_30(input[j],Array_1[j][i])) + Value);
             Array_4[i][j] = (int)((MUL_SHIFT_30(input[j],Array_2[j][i])) + Value);
      }
   }
}
 
void TestPattern_Initialization(void)//生成原始数据
{
        int i, j;
          for (i = 0; i < 32; i++)
          {
             for (j = 0; j < 16; j++)
             {
                    Array_1[i][j] = (int ) ((0xA5A5A5A5 >> 1) * i );
                    Array_2[i][j] = (int ) ((0xA5A5A5A5 << 1) * i );
             }
          }
}
//下面是中断服务函数
static void Cdma_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr)
{
       if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {
              Error = TRUE;
              printf("\r\n--- Transfer Error --- \r\n");//传输出错
       }
 
       if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {
              printf("\r\n--- Transfer Done --- \r\n");
              Done = TRUE;//传输成功
       }
 
}
//设置中断系统,初始化中断控制器
static int SetupIntrSystem(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,
                     u32 IntrId)
 
{
       int Status;
 
 
       /*
        * Initialize the interrupt controller driver
        */
       XScuGic_Config *IntcConfig;
 
 
       /*
        * Initialize the interrupt controller driver so that it is ready to
        * use.
        */
       IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
       if (NULL == IntcConfig) {
              return XST_FAILURE;
       }
 
       Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                                   IntcConfig->CpuBaseAddress);
       if (Status != XST_SUCCESS) {
              return XST_FAILURE;
       }
 
       XScuGic_SetPriorityTriggerType(IntcInstancePtr, IntrId, 0xA0, 0x3);
 
       /*
        * Connect the device driver handler that will be called when an
        * interrupt for the device occurs, the handler defined above performs
        * the specific interrupt processing for the device.
        */
       Status = XScuGic_Connect(IntcInstancePtr, IntrId,
                            (Xil_InterruptHandler)XAxiCdma_IntrHandler,
                            InstancePtr);
       if (Status != XST_SUCCESS) {
              return Status;
       }
 
       /*
        * Enable the interrupt for the DMA device.
        */
       XScuGic_Enable(IntcInstancePtr, IntrId);
 
 
 
 
       Xil_ExceptionInit();
 
       /*
        * Connect the interrupt controller interrupt handler to the hardware
        * interrupt handling logic in the processor.
        */
       Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
                            (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                            IntcInstancePtr);
 
 
       /*
        * Enable interrupts in the Processor.
        */
       Xil_ExceptionEnable();
 
 
       return XST_SUCCESS;
}
 
 
int XAxiCdma_Interrupt(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,
       u16 DeviceId, u32 IntrId)
{
       {
              XAxiCdma_Config *CfgPtr;
              int Status;
              int SubmitTries = 1;             /* Retry to submit */
              int Tries = NUMBER_OF_TRANSFERS;
              int Index;
 
              /* Initialize the XAxiCdma device.
               */
              CfgPtr = XAxiCdma_LookupConfig(DeviceId);
              if (!CfgPtr) {
                     return XST_FAILURE;
              }
 
              Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress);
              if (Status != XST_SUCCESS) {
                     return XST_FAILURE;
              }
 
              /* Setup the interrupt system
               */
              Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId);
              if (Status != XST_SUCCESS) {
                     return XST_FAILURE;
              }
 
              /* Enable all (completion/error/delay) interrupts
               */
              XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK);
 
              for (Index = 0; Index < Tries; Index++) {
                     Status = CDMATransfer(InstancePtr,
                               BUFFER_BYTESIZE, SubmitTries);
 
                     if(Status != XST_SUCCESS) {
                            DisableIntrSystem(IntcInstancePtr, IntrId);
                            return XST_FAILURE;
                     }
              }
 
              /* Test finishes successfully, clean up and return
               */
              DisableIntrSystem(IntcInstancePtr, IntrId);
 
              return XST_SUCCESS;
       }
}
/*****************************************************************************/
/*
*
* This function does CDMA transfer
*
* @param      InstancePtr is a pointer to the XAxiCdma instance
* @param      Length is the transfer length
* @param      Retries is how many times to retry on submission
*
* @return
*            - XST_SUCCESS if transfer is successful
*            - XST_FAILURE if either the transfer fails or the data has
*             error
*
* @note         None
*
******************************************************************************/
static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{
 
       int Status;
 
       Done = 0;
       Error = 0;
 
 
       printf("Start Transfer \n\r");
       /* Try to start the DMA transfer
        */
              Done = 0;
              Error = 0;
 
              /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
               * is enabled
               */
              Xil_DCacheFlushRange((u32)SourceAddr, Length);
 
              Status = XAxiCdma_SimpleTransfer(InstancePtr,
                                                                      (u32)(u8 *) (SourceAddr ),
                                                                      (u32)(DestAddr),
                                                                      Length,
                                                                      Cdma_CallBack,
                                                                      (void *)InstancePtr);
 
              if (Status == XST_FAILURE) {
                     printf("Error in Transfer \n\r");
                     return 1;
              }
 
 
 
              /* Wait until the DMA transfer is done
                      */
                     while (!Done && !Error) {
                            /* Wait */
                     }
 
                     if (Error) {
                            return XST_FAILURE;
                            return 1;
                     }
              /* Invalidate the DestBuffer before receiving the data, in case the
               * Data Cache is enabled
               */
              Xil_DCacheInvalidateRange((u32)DestAddr, Length);
 
       return XST_SUCCESS;
}
int main()
{
       int Status;
       u32 *SrcPtr;
       u32 *DestPtr;
       u32 Index;
       int i, j;
 
    printf("\r\n--- Entering main() --- \r\n");
 
       /*********************************************************************************
              Step : 1 : Intialization of the SOurce Memory with the Specified test pattern
                            Clear Destination memory
       **********************************************************************************/
    TestPattern_Initialization();
 
    /* Initialize the source buffer bytes with a pattern and the
            * the destination buffer bytes to zero
     */
    SrcPtr = (u32*)SourceAddr;
    DestPtr = (u32 *)DestAddr;
    for (Index = 0; Index < (BUFFER_BYTESIZE/1024); Index++)
    {
            MULT_SHIFT_LOOP((Index*100));
            for (i = 0; i < 32; i++)
            {
                   for (j = 0; j < 16; j++)
                   {
                          SrcPtr[((i+j))*(Index+1)]            = Array_3[i][j];
                          SrcPtr[((i+j)*(Index+1)) + 1]      = Array_4[i][j];
                          DestPtr[(i+j)*(Index+1)]             = 0;
                          DestPtr[((i+j)*(Index+1)) + 1] = 0;
                   }
 
            }
 
    }
       /*********************************************************************************
              Step : 2 : AXI CDMA Intialization
                               Association of the CDMA ISR with the Interrupt
                               Enable the CDMA Interrupt
                            Provide Source and destination location to CDMA
                            Specified Number of byte to be transfer to CDMA register
                            Start the CDMA
                            Wait for the Interrupt and return the status
       **********************************************************************************/
 
    Status = XAxiCdma_Interrupt( &IntcController,
                                                     &AxiCdmaInstance,
                                                     DMA_CTRL_DEVICE_ID,
                                                      DMA_CTRL_IRPT_INTR
                                                      );
 
    if (Status != XST_SUCCESS) {
 
                  printf("XAxiCdma_Interrupt: Failed\r\n");
                  return XST_FAILURE;
           }
 
           xil_printf("XAxiCdma_Interrupt: Passed\r\n");
 
 
    /*********************************************************************************
              Step : 3 : Compare Source memory with Destination memory
                               Return the Status
       **********************************************************************************/
           for (Index = 0; Index < (BUFFER_BYTESIZE/4); Index++)
           {
                  if ( DestPtr[Index] != SrcPtr[Index])
                  {
                         printf("Error in Comparison : Index : %x \n\r", Index);
                         return XST_FAILURE;
                  }
           }
 
           printf("DMA Transfer is Successful \n\r");
           return XST_SUCCESS;
 
 
    return 0;
}

驱动程序代码(未完成,有错误待修改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/ioctl.h>
 
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/wait.h>
#include <linux/cdev.h>
 
#include <linux/interrupt.h>
#include <asm/signal.h>
#include <linux/gpio.h>
#include <linux/irq.h>
 
 
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/dma.h>
#define DEVICE_NAME "dma_dev"
 
#define IRQ_MASK 0x00007000
 
#define IRQ_DEVICE_ID 0
 
#define NUMBER_OF_TRANSFERS 2
#define DMA_CTRL_DEVICE_ID 0
#define INTC_DEVICE_ID 0
#define DMA_CTRL_IRPT_INTR 91
 
#define MEMORY_BASE 0x01000000
#define CDMA_BASEADDR 0x80200000
#define XAXICDMA_BTT_OFFSET 0x00000028
#define XAXICDMA_SRCADDR_OFFSET 0x00000018
#define XAXICDMA_DSTADDR_OFFSET 0x00000020
 
#define HP0_BASEADDR    0x10000000
#define HP2_BASEADDR    0x18000000
 
#define XPAR_AXI_CDMA_0_M_AXI_DATA_WIDTH 64
#define XPAR_AXI_CDMA_0_M_AXI_MAX_BURST_LEN 256
 
static u32 SourceAddr  = HP0_BASEADDR;    // =0x10000000
static u32 DestAddr      = HP2_BASEADDR;    // = 0x18000000
 
static int Array_3[32][16];     //阵列
static int Array_4[32][16];
static int Array_1[32][16];
static int Array_2[32][16];
int const input[16] = {0xb504f33, 0xabeb4a0, 0xa267994, 0x987fbfc, 0x8e39d9c, 0x839c3cc, 0x78ad74c, 0x6d743f4, 0x61f78a8, 0x563e6a8, 0x4a5018c, 0x3e33f2c, 0x31f1704, 0x259020c, 0x1917a64, 0xc8fb2c};
 
/* Length of the buffers for DMA transfer */
static u32 BUFFER_BYTESIZE   = (XPAR_AXI_CDMA_0_M_AXI_DATA_WIDTH * XPAR_AXI_CDMA_0_M_AXI_MAX_BURST_LEN);      //大小为64*256/8=2KB,起始就是我们在XPS中设置好的
 
static unsigned long dma_addr = 0;
static unsigned long src_addr = 0;
static unsigned long dest_addr = 0;
static unsigned long mem_addr = 0;
 
static struct class* dma_class = NULL;
static struct device* dma_device = NULL;
 
static int dma_major = 0;
 
typedef struct {
        dev_t dev_no;
 
    u32 IsReady;
    int InterruptPresent;
    u32 BaseAddress;
//      spinlock_t lock;
        atomic_t lock;
} KEY_DEV;
 
static KEY_DEV keydev;
 
 
/************** start data generation func **************/
//Multiply and Shift
int MUL_SHIFT_30(int x, int y)//实现x*y,但又怕溢出,所以右移30位,除以2^30~1e9
{
 return ((int) (((long long) (x) * (y)) >> 30));
}
void MULT_SHIFT_LOOP(int Value )//生成源数据的函数
{
   int i, j;
   for (i = 0; i < 32; i++) {
      for (j = 0; j < 16; j++) {
             Array_3[i][j] = (int)((MUL_SHIFT_30(input[j],Array_1[j][i])) + Value);
             Array_4[i][j] = (int)((MUL_SHIFT_30(input[j],Array_2[j][i])) + Value);
      }
   }
}
 
void TestPattern_Initialization(void)//生成原始数据
{
    printk("begin testPattern\n");
        int i, j;
          for (i = 0; i < 32; i++)
          {
             for (j = 0; j < 16; j++)
             {
                    Array_1[i][j] = (int ) ((0xA5A5A5A5 >> 1) * i );
                    Array_2[i][j] = (int ) ((0xA5A5A5A5 << 1) * i );
             }
          }
    printk("finish testPattern\n");
}
/********finish test data generation func ************/
static void InterruptClear()
{
        u32 val;
        val = ioread32(dma_addr);
        iowrite32(val & IRQ_MASK,dma_addr);
        printk("int cleared");
}
 
 
static irqreturn_t dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    u32 IrqMask = 0x0;
    u32 status = 0xff;
    status = ioread32(dma_addr+0x00000004);
    printk("irq status = 0x%x\n",status);
         
    IrqMask = status & 0x00007000;
     
    if (IrqMask & 0x00004000) {
              printk("\r\n--- Transfer Error --- \r\n");//传输出错
        }
 
        if (IrqMask & 0x00001000) {
              printk("\r\n--- Transfer Done --- \r\n");//传输成功
        }  
 
    InterruptClear();
    return 0;
}
static void InterruptEnable()
{
    printk("in InterruptEnable");
    u32 val;
    val = ioread32(dma_addr);
    iowrite32(val | IRQ_MASK,dma_addr);
}
 
static int transfer()
{
     
    printk("start transfer");
    iowrite32(SourceAddr,dma_addr+XAXICDMA_SRCADDR_OFFSET);
    iowrite32(DestAddr,dma_addr+XAXICDMA_DSTADDR_OFFSET);
    iowrite32(Length,dma_addr+XAXICDMA_BTT_OFFSET);
}
static int dma_open(struct inode *inode, struct file *filp)
{
        int ret;
    int Status;
    u32 *SrcPtr;
    u32 *DestPtr;
    u32 Index;
        int i, j;
    printk("open! just standalone‘s main\n");
     
/****************************************************
Step : 1 : Intialization of the SOurce Memory with the Specified test pattern
Clear Destination memory
*****************************************************/
    TestPattern_Initialization();
    SrcPtr = (u32*)SourceAddr;
        DestPtr = (u32 *)DestAddr;
        for (Index = 0; Index < (BUFFER_BYTESIZE/1024); Index++)
        {
                MULT_SHIFT_LOOP((Index*100));
                for (i = 0; i < 32; i++)
                {
                    for (j = 0; j < 16; j++)
                    {
                          iowrite32(Array_3[i][j],src_addr+((i+j)*(Index+1))*sizeof(int));
                          iowrite32(Array_4[i][j],src_addr+(((i+j)*(Index+1))+1)*sizeof(int));
                          iowrite32(0,dest_addr+((i+j)*(Index+1))*sizeof(int));
                          iowrite32(0,dest_addr+(((i+j)*(Index+1))+1)*sizeof(int));
                    }
 
                }
 
        }
    printk("step1 finished!\n");
/**************************************************************************
Step : 2 : AXI CDMA Intialization
      Association of the CDMA ISR with the Interrupt
      Enable the CDMA Interrupt
      Provide Source and destination location to CDMA transfer()
      Specified Number of byte to be transfer to CDMA register transfer()
      Start the CDMA transfer()
      Wait for the Interrupt and return the status
***************************************************************************/
 
    InterruptEnable();
    printk("interrupt Enabled!\n");
    ret = request_irq(DMA_CTRL_IRPT_INTR, dma_interrupt,IRQF_TRIGGER_RISING, DEVICE_NAME, &keydev);
    if(ret)
    {
        printk("could not register interrupt!");
        return ret;
    }
    printk("register interrupt success!\n");
 
    //start data transfer
    transfer(BUFFER_BYTESIZE);
    printk("start transfer!\n");
     
    return 0;
}
 
static struct file_operations dma_fops = {
    .owner = THIS_MODULE,
    .open = dma_open,
};
 
static int __init cdma_init(void)
{
    int ret;
     
    ret = register_chrdev(0,DEVICE_NAME, &dma_fops);
    if(ret < 0)
    {
        printk("gpio: can‘t get major number\n");
        return ret;
    }
 
    dma_major = ret;
    dma_class = class_create(THIS_MODULE, "dma_class");
    if(IS_ERR(dma_class))
    {
        printk("dma: failed in creating class\n");
        unregister_chrdev(dma_major, DEVICE_NAME);
        return -1;
    }
 
    dma_device = device_create(dma_class,NULL,MKDEV(dma_major,0),NULL,DEVICE_NAME);
    if(IS_ERR(dma_device))
    {
        printk("dma: failed in creating device!\n");
        unregister_chrdev(dma_major, DEVICE_NAME);
        class_unregister(dma_class);
        class_destroy(dma_class);
        return -1;
    }
     
    dma_addr = (unsigned long) ioremap(CDMA_BASEADDR, sizeof(u32));
    //mem_addr = (unsigned long) ioremap(MEMORY_BASE, sizeof(u32));
    dest_addr = (unsigned long)bus_to_virt(HP2_BASEADDR);
    src_addr = (unsigned long)bus_to_virt(HP0_BASEADDR);
    //src_addr = (unsigned long) ioremap(HP0_BASEADDR, sizeof(u32));
    //dest_addr = (unsigned long) ioremap(HP2_BASEADDR, sizeof(u32));
    printk("dma_addr=%lx,src_addr=%lx,dest_addr=%lx\n",dma_addr,src_addr/dest_addr);
    printk("dma installed successfully!\n");
    return 0;
}
 
static void __exit cdma_exit(void)
{
/*
    iowrite32(0x00,led_addr);
    mdelay(100);       
    iowrite32(0xff,led_addr);
*/
    device_destroy(dma_class,MKDEV(dma_major, 0));
    class_unregister(dma_class);
    class_destroy(dma_class);
    unregister_chrdev(dma_major,DEVICE_NAME);
    printk("dma module exit!");
}
 
module_init(cdma_init);
module_exit(cdma_exit);
 
 
MODULE_AUTHOR("seg");
MODULE_LICENSE("GPL");

finish

Learn ZYNQ(2),布布扣,bubuko.com

Learn ZYNQ(2)

标签:des   c   style   class   blog   code   

原文地址:http://www.cnblogs.com/shenerguang/p/3760012.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!