精华内容
下载资源
问答
  • MIPS 科技公司模拟业务部嵌入式外设总监 Luis Laranjeira     如今这个问题仍然是摆在MIPS 面前的挑战,但是除了分立式芯片元件,MIPS 还有 IP。随着实现现代、多功能 SoC 所需的复杂性增加,集成难度成为了一个...
  • MIPS 科技公司模拟业务部嵌入式外设总监 Luis Laranjeira     如今这个问题仍然是摆在MIPS 面前的最大挑战,但是除了分立式芯片元件,MIPS 还有 IP。随着实现现代、多功能 SoC 所需的复杂性增加,集成难度成为了一...
  • 【整理】嵌入式外设之DMA 2013 年 11 月 14 日 下午 2:43crifan已有188人围观我来说几句 DMA简介 DMA 不是独立的某个外设,而是一个硬件模块 支持DMA的功能 一般对应的,也是按个数来的,对应
    原文地址:http://www.crifan.com/summary_embedded_peripherals_dma/

    【整理】嵌入式外设之DMA

    DMA简介

    DMA

    不是独立的某个外设,而是一个硬件模块

    支持DMA的功能

    一般对应的,也是按个数来的,对应的叫做多少个通道channel。

     

    【整理】以快递为例来说明DMA的功能

    DMA本意解析

    DMA==Direct Memory Access==直接存储器访问

    Direct:直接,对应的就有间接:之前都是,CPU参与,一点点把数据,从一个地方拷贝,即像搬家一样搬到,另一个地方

    很明显,此时,相对时间比较宝贵(比较值钱)的CPU,把时间,就用在(浪费在)拷贝数据了。

     

    Memory:存储器

    一般多数都指的是内存

    当然,DMA也会涉及到,外设的一些Buffer,数据寄存器等等操作

    Access:访问

    即操作上面所提到的,存储器

    即数据的读写,所以要访问,操作对应的存储器

     

    为何会出现DMA?

    所以,尤其很明显可以看出:

    之前就是觉得,对于数据拷贝这样,相对低级的,简单的任务,

    结果却要,时间比较值钱的CPU,去干这样的“杂货”

    就有点浪费CPU的时间了

    所以,才出现这个DMA

    专门去干,拷贝数据这个活

    由此,释放了CPU,CPU就可以去干其他的,相对更加有价值(值钱的)事情了

     

    DMA使用示例

    比如,拿uboot中的

    S3c2410_nand.c (drivers\mtd\nand) 4513 2013/10/17

    中的:

    nand_read_buf

    为例来说明:

    之前就只是CPU去一点点的,慢慢的读数据:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    static void nand_read_buf(struct mtd_info *mtd, u_char *buf, intlen)
    {
        int i;
        struct nand_chip *this = mtd->priv;
     
        for (i = 0; i < len; i++)
            buf[i] = readb(this->IO_ADDR_R);
    }

    而如果是改为DMA

    则只需要:

    CPU去配置好DMA

    然后DMA自动会去读数据

    就不用CPU再操心了

    就不用CPU再费时间去读数据了。

    CPU就有空去执行其他更重要的事情了。

     

    另外再举个例子:

    之前已经实现的,linux的kernel中的nand flash驱动中的dma的例子:

    在对应的hwecc的read函数:

    as353x_nand_read_page_hwecc

    中,当开启了DMA的READ和普通read的相关代码为:

    ?
    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
    static int as353x_nand_read_page_hwecc(struct mtd_info *mtd,
                struct nand_chip *chip, uint8_t *buf)
    {
    ...
    #ifdef NAF_USE_DMA_READ
        info->len = mtd->writesize;
     
        /* map CPU buffer(virtual address) to DMA buffer(DMA address) */
        info->txaddr = dma_map_single(   info->device,
                                        (void *)buf,
                                        info->len,/* here len is in bytes, not in words !*/
                                        DMA_FROM_DEVICE);
        if (unlikely(dma_mapping_error(info->device, info->txaddr))) {
            ret = -ENOMEM;
            dev_err(info->device, "DMA read map failed\n");
            goto dma_map_err;
        }
     
        /* apply DMA slave and client */
        as353x_nand_dma_init_tx(info);
     
        /* set info for use in call back */
        info->callback_param.client_info = (void *)info;
     
        /* init values */
        info->txsg.length        = info->len;
        info->txsg.page_link = 0;
        info->txsg.offset        = 0;
        info->txsg.dma_address = info->txaddr;
     
        desc = info->txchan->device->device_prep_slave_sg(
                                info->txchan,
                                &info->txsg,
                                1,
                                DMA_FROM_DEVICE,
                                DMA_PREP_INTERRUPT);
        if ( unlikely(!desc) ) {
            dev_err(info->device, "Unable to get descriptor for DMA read\n");
            ret = -EBUSY;
            goto prep_sg_err;
        }
     
        desc->callback = as353x_nand_dma_complete_callback;
        desc->callback_param = &info->callback_param;
        desc->tx_submit(desc);
        /* inform dma controller to start */
        info->txchan->device->device_issue_pending(info->txchan);
     
        /* inform nand controller to start */
        set_bit32(NAF_CFG_DMA_ON, info->regs + NAF_CONFIG);
     
        if (unlikely(!wait_for_completion_timeout(&info->done,
                                    msecs_to_jiffies(1 * 1000)))) {
            dev_err(info->device, "DMA read timeout\n");
            clear_bit32(NAF_CFG_DMA_ON, info->regs + NAF_CONFIG);
            ret = -ENXIO;
            info->txchan->device->device_free_chan_resources(info->txchan);
            info->txchan = NULL;
            AS353XNAND_DBG("len=%d, read=%x\n", info->len, info->txcount);
            as353x_nand_show_reg(mtd);
            goto dma_timeout_err;
        }
    #else
        /* none-DMA trasfer */
     
        /* read page data */
        as353x_nand_read_buf_hwbch4(mtd, buf,   mtd->writesize);
    #endif
    ...
    }
     
    /* for read, from nand to buffer, using DMA_FROM_DEVICE */
    static void as353x_nand_dma_init_tx(struct as353x_nand_info *info)
    {
        struct dma_client *txclient;
        struct dma_slave *txslave;
     
        txslave = &info->txslave;
        txclient = &info->txclient;
     
        txslave->tx_reg = 0;
        txslave->rx_reg = info->dmabase + NAF_FIFODATA;
        txslave->reg_width = DMA_SLAVE_WIDTH_32BIT;
        txslave->dev = info->device;
        txclient->event_callback     = as353x_nand_dma_req_tx_chan_callback;
        dma_cap_set(DMA_SLAVE, txclient->cap_mask);
        txclient->slave = txslave;
        dma_async_client_register(txclient);
        dma_async_client_chan_request(txclient);
    }
     
    static void as353x_nand_read_buf_hwbch4(struct mtd_info *mtd,
                u_char *buf, int len)
    {
        int i, j;
        u32 *buf_u32 = (u32 *)buf;
        struct as353x_nand_info *info = as353x_nand_mtd_toinfo(mtd);
     
        /* to words */
        len = BYTE2WORD(len);
     
        for ( j = ( len / NAF_FIFO_FILLSIZE_IN_WORDS ); j > 0; --j ) {
            /* wait for fifo to get filled (again) - with high speed flashes this */
            as353x_nand_wait_until_almost_full(mtd);
             
            for ( i = 0; i < NAF_FIFO_FILLSIZE_IN_WORDS; i++ )
            {
                *buf_u32 = readl(info->regs + NAF_FIFODATA);
                ++buf_u32;
            }
        }
     
        /* if any words left in FIFO in case of
        non n-times words of NAF_FIFO_FILLSIZE_IN_WORDS */
        for ( i = 0; i < ( len % NAF_FIFO_FILLSIZE_IN_WORDS ); i++) {
            while (as353x_fifo_isempty(mtd)); /* wait for FIFO is filled */
            *buf_u32 = readl(info->regs + NAF_FIFODATA);
            ++buf_u32;
        }
    }

    可见,当不用DMA时,对应就是去:

    对应的读取寄存器中的数据

    ?
    1
    readl(info->regs + NAF_FIFODATA)

    而开启了DMA的话,则是去利用对应的DMA驱动中,申请对应的DMA通道和资源,

    然后再去用DMA去传输数据的。

    DMA中,对应的指定源地址是:

    ?
    1
    txslave->rx_reg = info->dmabase + NAF_FIFODATA;

    目的地址则是对应的,一点点增加的,每次增加的是32bit=4字节:

    ?
    1
    txslave->reg_width = DMA_SLAVE_WIDTH_32BIT;

     

    DMA vs 快递

    由此可看出,其实DMA,和快递,很类似:

    快递:

    你的需求是:

    想要送东西,从某地到某地

    想要通过快递去实现此需求

    而之所以选择快递而不自己去送,

    有的是自己没时间;

    有的是自己有时间,但是成本更高,不值得花在送东西这上面:

        比如,寄点东西,本身就只值100元,打算从南京送到北京,快递的话,可能也就10元,20元就够了,而要自己去送,单独火车票,甚至飞机票,都要几百,甚至几千。所以,还是通过快递公司送东西,更划算。

    有的是,自己有时间,但是自己的时间,更值钱,不值得花在送东西这上面:

        假如你是身家不菲,比如比尔盖茨,即使不嫌弃自己送东西的成本更高,但是也是自己的时间浪费不起,自己的时间,如果花费在送东西上,加起来会值更多的钱,所以不值得自己把宝贵的时间,用在送东西的小事情上面,所以还是选择快递更合适。

    等等情况。

    对于快递来说:

    其优点是:

    对于多数用户来说,选择快递寄东西,成本更低,更经济,更划算;

    而快递对于用户来说,其所关心的是:

    告诉其目的地:对应的,起始的出发地点,在你送东西时,就已经知道了,所以不用再问你

    告诉其价格:用户只要支持对应的价格,快递就可以寄送了。

    由此类似的DMA:

    CPU,就像DMA的用户

    CPU的时间很值钱,在有DMA的前提下,

    还是把数据拷贝这个事情,交个DMA去做,更经济,更划算。

    然后CPU就有空去做其他更值钱,更有意义的事情了。

    而对于DMA来说:

    其只需要CPU配置好DMA,DMA就可以去干活了,就可以去搬运数据了。

    而CPU配置DMA,实际上就是告诉DMA:

    搬运数据的起始地址和目标地址:就类似于送快递时的,出发点和目的地

    而关于快递时用户要支付的价格,对于CPU来说,表面上是没有去额外给DMA什么补偿的。

    只不过,对于整个系统来说,如果你的CPU可以借用DMA去传数据,那么:

    系统中是要存在DMA这个硬件(模块,功能)的:这对于设计系统的硬件时,是否增加DMA功能,本身就是成本和效率方面的衡量后的考虑;

    不过,CPU使用DMA传输数据,和用户使用快递寄东西,有些方面不太一样:

    • 速度

    CPU使用DMA传输数据,往往是为了提高CPU利用率,而结果,更重要的是:

    DMA传输数据的话,速度更快,效率更高;

    对应的用户选择快递寄东西,有时候,未必是比自己亲自去送,的速度更快,花的时间更短。

    但是总的来说,往往是最经济的。

    • DMA通道个数是有限的

    现实中的快递公司,除了大的节假日之外,对于普通用户来说,那处理能力,基本都是无限的。

    不会由于你多寄了个东西,快递公司,就忙不过来了。

    而现实中的DMA,其资源是有限的:

    DMA的个数,是按照通道channel来算的;

    同一时刻,一个channel的DMA,只能做一件数据搬家的工作;

    而且,往往是:

    一个嵌入式系统中,往往很多内部功能模块,都希望有机会用到DMA,但是实际上DMA通道个数有限,

    使得很难都满足其需求。

    所以,在DMA的使用上,是需要你程序设计者去决定哪个模块使用DMA,然后在对应的驱动中,将数据拷贝的功能,用DMA来实现,以此提升性能的。

    不过,另外,一般情况下,也是有对应的DMA驱动,去管理DMA资源,使得只要错开同时使用,也是以可以使得多个模块,都能用到DMA的。但是,往往系统中,某个模块用DMA的话,都是相对比较频繁的,因为是很多时候都在处理数据拷贝,所以往往是某个模块,要是用DMA的话,都是独占单个的DMA通道的。

    比如:

    系统中,假如只有一个通道的DMA的话,

    而Nand Flash中,SD卡驱动中,都希望用到,那么:

    你只能根据自己的需求去决定:

    假如我的嵌入式系统,物理上的主要的存储设备是Nand Flash

    为了提升系统性能,决定把DMA给Nand Flash使用

    在保证系统整体的性能相对较好的前提下,而对于SD卡,只是用于存储用户数据,速度稍微慢一点,其也是能接受的。

     

    关于DMA是需要硬件支持的

    比如AS3536中,就支持:

    AHB1中的8个DMA的channel,16个request:

    as3536 ahb1 dma ahb2 peripheral request

     

    AHB2中有8个DMAchannel,32个request:

    ahb2 dma controller request 0 to 16 channels

    ahb2 dma controller request 17 to 31 channels

     

     

    总结

    DMA,资源有限,需要合理利用。

    且需硬件支持。



    展开全文
  • This user guide describes the IP cores provided by Intel ® Quartus ® Prime design software. The IP cores are optimized for Intel FPGA devices and can be easily implemented to ...
  • 嵌入式外设之DMA

    2020-02-11 11:24:12
    目录 DMA简介 ...不是独立的某个外设,而是一个硬件模块 支持DMA的功能 一般对应的,也是按个数来的,对应的叫做多少个通道channel。 【整理】以快递为例来说明DMA的功能 DMA本意解析 ...

    目录

     

    DMA简介

    【整理】以快递为例来说明DMA的功能

    DMA本意解析

    为何会出现DMA?

    DMA使用示例

    DMA vs 快递

    关于DMA是需要硬件支持的

    总结


    DMA简介

    DMA

    不是独立的某个外设,而是一个硬件模块

    支持DMA的功能

    一般对应的,也是按个数来的,对应的叫做多少个通道channel。

     

    【整理】以快递为例来说明DMA的功能

    DMA本意解析

    DMA==Direct Memory Access==直接存储器访问

    Direct:直接,对应的就有间接:之前都是,CPU参与,一点点把数据,从一个地方拷贝,即像搬家一样搬到,另一个地方

    很明显,此时,相对时间比较宝贵(比较值钱)的CPU,把时间,就用在(浪费在)拷贝数据了。

     

    Memory:存储器

    一般多数都指的是内存

    当然,DMA也会涉及到,外设的一些Buffer,数据寄存器等等操作

    Access:访问

    即操作上面所提到的,存储器

    即数据的读写,所以要访问,操作对应的存储器

     

    为何会出现DMA?

    所以,尤其很明显可以看出:

    之前就是觉得,对于数据拷贝这样,相对低级的,简单的任务,

    结果却要,时间比较值钱的CPU,去干这样的“杂货”

    就有点浪费CPU的时间了

    所以,才出现这个DMA

    专门去干,拷贝数据这个活

    由此,释放了CPU,CPU就可以去干其他的,相对更加有价值(值钱的)事情了

     

    DMA使用示例

    比如,拿uboot中的

    S3c2410_nand.c (drivers\mtd\nand) 4513 2013/10/17

    中的:

    nand_read_buf

    为例来说明:

    之前就只是CPU去一点点的,慢慢的读数据:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)

    {

        int i;

        struct nand_chip *this = mtd->priv;

     

        for (i = 0; i < len; i++)

            buf[i] = readb(this->IO_ADDR_R);

    }

    而如果是改为DMA

    则只需要:

    CPU去配置好DMA

    然后DMA自动会去读数据

    就不用CPU再操心了

    就不用CPU再费时间去读数据了。

    CPU就有空去执行其他更重要的事情了。

     

    另外再举个例子:

    之前已经实现的,linux的kernel中的nand flash驱动中的dma的例子:

    在对应的hwecc的read函数:

    as353x_nand_read_page_hwecc

    中,当开启了DMA的READ和普通read的相关代码为:

    ?

    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

    static int as353x_nand_read_page_hwecc(struct mtd_info *mtd,

                struct nand_chip *chip, uint8_t *buf)

    {

    ...

    #ifdef NAF_USE_DMA_READ

        info->len = mtd->writesize;

     

        /* map CPU buffer(virtual address) to DMA buffer(DMA address) */

        info->txaddr = dma_map_single(   info->device,

                                        (void *)buf,

                                        info->len,/* here len is in bytes, not in words !*/

                                        DMA_FROM_DEVICE);

        if (unlikely(dma_mapping_error(info->device, info->txaddr))) {

            ret = -ENOMEM;

            dev_err(info->device, "DMA read map failed\n");

            goto dma_map_err;

        }

     

        /* apply DMA slave and client */

        as353x_nand_dma_init_tx(info);

     

        /* set info for use in call back */

        info->callback_param.client_info = (void *)info;

     

        /* init values */

        info->txsg.length        = info->len;

        info->txsg.page_link = 0;

        info->txsg.offset        = 0;

        info->txsg.dma_address = info->txaddr;

     

        desc = info->txchan->device->device_prep_slave_sg(

                                info->txchan,

                                &info->txsg,

                                1,

                                DMA_FROM_DEVICE,

                                DMA_PREP_INTERRUPT);

        if ( unlikely(!desc) ) {

            dev_err(info->device, "Unable to get descriptor for DMA read\n");

            ret = -EBUSY;

            goto prep_sg_err;

        }

     

        desc->callback = as353x_nand_dma_complete_callback;

        desc->callback_param = &info->callback_param;

        desc->tx_submit(desc);

        /* inform dma controller to start */

        info->txchan->device->device_issue_pending(info->txchan);

     

        /* inform nand controller to start */

        set_bit32(NAF_CFG_DMA_ON, info->regs + NAF_CONFIG);

     

        if (unlikely(!wait_for_completion_timeout(&info->done,

                                    msecs_to_jiffies(1 * 1000)))) {

            dev_err(info->device, "DMA read timeout\n");

            clear_bit32(NAF_CFG_DMA_ON, info->regs + NAF_CONFIG);

            ret = -ENXIO;

            info->txchan->device->device_free_chan_resources(info->txchan);

            info->txchan = NULL;

            AS353XNAND_DBG("len=%d, read=%x\n", info->len, info->txcount);

            as353x_nand_show_reg(mtd);

            goto dma_timeout_err;

        }

    #else

        /* none-DMA trasfer */

     

        /* read page data */

        as353x_nand_read_buf_hwbch4(mtd, buf,   mtd->writesize);

    #endif

    ...

    }

     

    /* for read, from nand to buffer, using DMA_FROM_DEVICE */

    static void as353x_nand_dma_init_tx(struct as353x_nand_info *info)

    {

        struct dma_client *txclient;

        struct dma_slave *txslave;

     

        txslave = &info->txslave;

        txclient = &info->txclient;

     

        txslave->tx_reg = 0;

        txslave->rx_reg = info->dmabase + NAF_FIFODATA;

        txslave->reg_width = DMA_SLAVE_WIDTH_32BIT;

        txslave->dev = info->device;

        txclient->event_callback     = as353x_nand_dma_req_tx_chan_callback;

        dma_cap_set(DMA_SLAVE, txclient->cap_mask);

        txclient->slave = txslave;

        dma_async_client_register(txclient);

        dma_async_client_chan_request(txclient);

    }

     

    static void as353x_nand_read_buf_hwbch4(struct mtd_info *mtd,

                u_char *buf, int len)

    {

        int i, j;

        u32 *buf_u32 = (u32 *)buf;

        struct as353x_nand_info *info = as353x_nand_mtd_toinfo(mtd);

     

        /* to words */

        len = BYTE2WORD(len);

     

        for ( j = ( len / NAF_FIFO_FILLSIZE_IN_WORDS ); j > 0; --j ) {

            /* wait for fifo to get filled (again) - with high speed flashes this */

            as353x_nand_wait_until_almost_full(mtd);

             

            for ( i = 0; i < NAF_FIFO_FILLSIZE_IN_WORDS; i++ )

            {

                *buf_u32 = readl(info->regs + NAF_FIFODATA);

                ++buf_u32;

            }

        }

     

        /* if any words left in FIFO in case of

        non n-times words of NAF_FIFO_FILLSIZE_IN_WORDS */

        for ( i = 0; i < ( len % NAF_FIFO_FILLSIZE_IN_WORDS ); i++) {

            while (as353x_fifo_isempty(mtd)); /* wait for FIFO is filled */

            *buf_u32 = readl(info->regs + NAF_FIFODATA);

            ++buf_u32;

        }

    }

    可见,当不用DMA时,对应就是去:

    对应的读取寄存器中的数据

    ?

    1

    readl(info->regs + NAF_FIFODATA)

    而开启了DMA的话,则是去利用对应的DMA驱动中,申请对应的DMA通道和资源,

    然后再去用DMA去传输数据的。

    DMA中,对应的指定源地址是:

    ?

    1

    txslave->rx_reg = info->dmabase + NAF_FIFODATA;

    目的地址则是对应的,一点点增加的,每次增加的是32bit=4字节:

    ?

    1

    txslave->reg_width = DMA_SLAVE_WIDTH_32BIT;

     

    DMA vs 快递

    由此可看出,其实DMA,和快递,很类似:

    快递:

    你的需求是:

    想要送东西,从某地到某地

    想要通过快递去实现此需求

    而之所以选择快递而不自己去送,

    有的是自己没时间;

    有的是自己有时间,但是成本更高,不值得花在送东西这上面:

        比如,寄点东西,本身就只值100元,打算从南京送到北京,快递的话,可能也就10元,20元就够了,而要自己去送,单独火车票,甚至飞机票,都要几百,甚至几千。所以,还是通过快递公司送东西,更划算。

    有的是,自己有时间,但是自己的时间,更值钱,不值得花在送东西这上面:

        假如你是身家不菲,比如比尔盖茨,即使不嫌弃自己送东西的成本更高,但是也是自己的时间浪费不起,自己的时间,如果花费在送东西上,加起来会值更多的钱,所以不值得自己把宝贵的时间,用在送东西的小事情上面,所以还是选择快递更合适。

    等等情况。

    对于快递来说:

    其优点是:

    对于多数用户来说,选择快递寄东西,成本更低,更经济,更划算;

    而快递对于用户来说,其所关心的是:

    告诉其目的地:对应的,起始的出发地点,在你送东西时,就已经知道了,所以不用再问你

    告诉其价格:用户只要支持对应的价格,快递就可以寄送了。

    由此类似的DMA:

    CPU,就像DMA的用户

    CPU的时间很值钱,在有DMA的前提下,

    还是把数据拷贝这个事情,交个DMA去做,更经济,更划算。

    然后CPU就有空去做其他更值钱,更有意义的事情了。

    而对于DMA来说:

    其只需要CPU配置好DMA,DMA就可以去干活了,就可以去搬运数据了。

    而CPU配置DMA,实际上就是告诉DMA:

    搬运数据的起始地址和目标地址:就类似于送快递时的,出发点和目的地

    而关于快递时用户要支付的价格,对于CPU来说,表面上是没有去额外给DMA什么补偿的。

    只不过,对于整个系统来说,如果你的CPU可以借用DMA去传数据,那么:

    系统中是要存在DMA这个硬件(模块,功能)的:这对于设计系统的硬件时,是否增加DMA功能,本身就是成本和效率方面的衡量后的考虑;

    不过,CPU使用DMA传输数据,和用户使用快递寄东西,有些方面不太一样:

    • 速度

    CPU使用DMA传输数据,往往是为了提高CPU利用率,而结果,更重要的是:

    DMA传输数据的话,速度更快,效率更高;

    对应的用户选择快递寄东西,有时候,未必是比自己亲自去送,的速度更快,花的时间更短。

    但是总的来说,往往是最经济的。

    • DMA通道个数是有限的

    现实中的快递公司,除了大的节假日之外,对于普通用户来说,那处理能力,基本都是无限的。

    不会由于你多寄了个东西,快递公司,就忙不过来了。

    而现实中的DMA,其资源是有限的:

    DMA的个数,是按照通道channel来算的;

    同一时刻,一个channel的DMA,只能做一件数据搬家的工作;

    而且,往往是:

    一个嵌入式系统中,往往很多内部功能模块,都希望有机会用到DMA,但是实际上DMA通道个数有限,

    使得很难都满足其需求。

    所以,在DMA的使用上,是需要你程序设计者去决定哪个模块使用DMA,然后在对应的驱动中,将数据拷贝的功能,用DMA来实现,以此提升性能的。

    不过,另外,一般情况下,也是有对应的DMA驱动,去管理DMA资源,使得只要错开同时使用,也是以可以使得多个模块,都能用到DMA的。但是,往往系统中,某个模块用DMA的话,都是相对比较频繁的,因为是很多时候都在处理数据拷贝,所以往往是某个模块,要是用DMA的话,都是独占单个的DMA通道的。

    比如:

    系统中,假如只有一个通道的DMA的话,

    而Nand Flash中,SD卡驱动中,都希望用到,那么:

    你只能根据自己的需求去决定:

    假如我的嵌入式系统,物理上的主要的存储设备是Nand Flash

    为了提升系统性能,决定把DMA给Nand Flash使用

    在保证系统整体的性能相对较好的前提下,而对于SD卡,只是用于存储用户数据,速度稍微慢一点,其也是能接受的。

     

    关于DMA是需要硬件支持的

    比如AS3536中,就支持:

    AHB1中的8个DMA的channel,16个request:

    as3536 ahb1 dma ahb2 peripheral request

     

    AHB2中有8个DMAchannel,32个request:

    ahb2 dma controller request 0 to 16 channels

    ahb2 dma controller request 17 to 31 channels

     

     

    总结

    DMA,资源有限,需要合理利用。

    且需硬件支持。

    转载请注明:在路上 » 【整理】嵌入式外设之DMA

    展开全文
  • 【整理】嵌入式外设之SD/MMC

    千次阅读 2013-12-24 16:55:51
    原文地址:... 【整理】嵌入式外设之SD/MMC 2013 年 11 月 11 日 下午 11:47crifan已有148人围观我来说几句 最后更新:2013-11-11 TODO: 1.整理SD的各种类型: MMC 
    原文地址:http://www.crifan.com/embedded_peripherals_sd_mmc_card_interface/

    【整理】嵌入式外设之SD/MMC

    最后更新:2013-11-11

    TODO:

    1.整理SD的各种类型:

    MMC 
    RS-MMC 
    MMCplus 
    SecureMMC 
    SDIO 
    SD 
    miniSD 
    microSD

    2.以及SD本身根据速度还分:SDHC,SDXC等。


    SD/MMC简介

    常见的外设接口之一。

    现在比较流行的手机,Android手机中,常常就支持再插入一个外接存储卡,就是SD卡。

    只不过是小型接口的MicroSD。

     

    SD/MMC的名称解释

    之所以常常看到,把SD和MMC连在一起叫。

    那是因为:

    SD接口,算是MMC接口的升级版,

    理论上,SD接口和更早的MMC接口是兼容的。

    所以,可以看做是同样的物理上的一个接口

    所以一般是把SD和MMC连在一起叫:

    SD/MMC接口

     

     

    SD/MMC的物理外形和接口说明

     

    MMC卡长啥样

    先上图,看看常见的MMC卡,是什么样的:

    正面:

    what looklike for common mmc card front

    注:最下面那个是MMC卡的插槽

    反面:

    what looklike for common mmc card back

     

     

    SD卡长啥样

    再来看看SD卡长啥样:

    common sd card looklike what

    另外,还有一个小型的SD卡,叫做MicroSD,其明显小了一号

    对应的可以通过普通的SD卡的卡套,变成和普通SD类似的效果:

    micro sd card and adapter

     

    MMC和SD卡引脚说明

    直接上图:

    sd mmc pins comparation

    真实的SD卡和MMC卡,背面对比:

    real sd vs mmc card

    再加一个,带引脚说明的对比图:

    sd card and mmc card pins name function

    很明显:

    MMC和SD,在接口上,都还是很类似,很兼容的。

    对应的,SD和MMC的接口的名称和含义,

    如下:

    MMC卡的引脚名称和功能

    对应的,MMC,分MMC模式和SPI模式,引脚和功能,不太一样:

     

    MMC卡模式(MultiMedia Card mode)时的MMC引脚名称和功能

    Pin Signal Description
    1 RSV NC Not connected or Always ?1? (data 3?)
    2 CMD I/O Command/Response
    3 VSS1 S Supply Voltage Ground
    4 VDD S Supply Voltage
    5 CLK I Clock
    6 VSS2 S Supply Voltage Ground
    7 DAT0 I/O PP Data 0

     

    SPI模式时的MMC引脚名称和功能

    Pin Signal Description
    1 CS Chip select (neg. true)
    2 DI DATA in
    3 Vss Ground
    4 Vcc Power supply
    5 SCLK Clock
    6 Vss2 Ground
    7 DO DATA out

     

    SD卡的引脚名称和功能

    SD卡,也分对应的SD模式和SPI模式

    Pin SD Mode SPI Mode
    Name Type Description Name Type Description
    1 CD/DAT3 I/O/PP Card detection / Connector data line 3 CS I Chip selection in low status
    2 CMD PP Command/Response line DI I Data input
    3 Vss1 S GND VSS S GND
    4 Vdd S Power supply VDD S Power supply
    5 CLK I Clock SCLK I Clock
    6 Vss2 S GND VSS2 S GND
    7 DAT0 I/O/PP Connector data line 0 DO O/PP Data output
    8 DAT1 I/O/PP Connector data line 1 RSV    
    9 DAT2 I/O/PP Connector data line 2 RSV    

     

     

    SD卡或MMC卡在卡Card的模式时的引脚功能说明

     

    Pin No. Name Type Explanation
    1 CD/DAT3 Input/Output using push pull drivers After power up this line is input with 50 kOhm pull-up. This can be used for card detection. Relevant only for SD cards, pull-up resistor is disabled after initialization procedure for using this line as DATA3 line for data transfer.
    2 CMD Push Pull This is a bi-directional line. It is a bidirectional command channel used for card initialization and data transfer commands. The CMD signal has two operation modes: open-drain for initialization mode and push-pull for fast command transfer. Commands are sent from the MultiMediaCard bus master (card host controller) to the card and responses from the cards to the host.
    3 Vss Power supply Supply voltage ground.
    4 Vdd Power supply Supply voltage.
    5 CLK Input With each cycle of this signal an one bit transfer on the command and data lines is done. The frequency may vary between zero and the maximum clock frequency.
    6 Vss2 Power supply Supply voltage ground.
    7 DAT[0] Input/Output using push pull driver DAT is a bidirectional data channel. The DAT signal operates in push-pull mode. Only one card or the host is driving this signal at a time. Relevant only for SD cards: On data transfer, this line is DATA 0.
    8 DAT[1] Input/Output using push pull drivers On MMC card this line does not exist. Relevant only for SD cards: On data transfer, this line is DATA 1.
    9 DAT[2] Input/Output using push pull drivers On MMC card this line does not exist. Relevant only for SD cards: On data transfer, this line is DATA 2.

     

    SD卡或MMC卡在SPI模式时的引脚功能说明

     

    Pin No. Name Type Explanation
    1 CS Input Chip Select sets the card active at low level and inactive at high level.
    2 Data In Input Data In is seen from the card, therefore data transmitted to the card will be received from this line.
    3 Vss Supply ground Supply voltage ground.
    4 Vdd Supply voltage Supply voltage.
    5 SCLK Input Clock signal must be generated by the target system. 
    The card is always in slave mode.
    6 Vss2 Supply ground Supply voltage ground.
    7 Data Out Output Data Out is seen from the card. Data transferred to host will be sent by card from this line.
    8 Reserved Not used -
    9 Reserved Not used -

     

    总结

    SD/MMC,还是使用的很广泛的。

     

    其他资料

    之前收集的,供参考:

    基于S3C2410的SD卡linux驱动工作原理

    SD和MMC记忆卡介面技术[ZT]

    High Capacity for SD Family

    SD Card Specifications

    和刚才参考的:

    http://en.wikipedia.org/wiki/MultiMediaCard

    SD-, SDHC- und MMC-Karten an AVR anschließen

    How to Use MMC/SDC

    MultiMedia Card (MMC) pinout

    Secure Digital (SD) card pinout

    Driver SD, SDHC & MMC


    展开全文
  • 【整理】嵌入式外设之RS232

    千次阅读 2013-12-24 16:56:50
    原文地址:http://www.crifan.com/summary_embedded_peripherals_rs232/ 后更新:2013-11-14 ...注:当然,串口这个概念,严格的说,还包含其他一些,比如RS485,RS422,这两个,一般是工业控制领域才用得到。...

    原文地址:http://www.crifan.com/summary_embedded_peripherals_rs232/

    后更新:2013-11-14


    RS232==串口

    注:当然,串口这个概念,严格的说,还包含其他一些,比如RS485,RS422,这两个,一般是工业控制领域才用得到。

    普通消费类数码领域,很少用得到。

    一般还会说明个数

    因为:

    有的系统中,有对应的需要,可能会需要多个UART的

    所以,硬件支持中,对应的最好希望是有多个UART主控去支持的。

    比如:http://www.freescale.com/zh-Hans/webapp/sps/site/prod_summary.jsp?code=MCF5227X

    中就有:“3 UART”

     

    RS232协议简介

    硬件引脚介绍

    电压介绍

    负电压表示正

    正电压表示负

    握手 流控制

    虽然不是RS232特有的

    但是主要是RS232中才会涉及到

    其他的可能用到的也有RS485等串行通信中也会遇到

    软件流控制:XON/XOFF

    硬件流控制:RTS/CTS和DTR/DSR

    【整理】RS232 RTS/CTS的流控制的具体过程/机制

    【整理】串口(RS232/RS485等)通讯中RTS/CTS,DTR/DSR的含义详解

    常见串口工具介绍

    虽然不是只是用于RS232,但是主要也就只是用于RS232

    各种串口软件的总结

    软件简介

    截图用法

    用连接Uboot输出为例,截图示例每个软件都是啥样的

    之前已整理了一点:

    【整理】常用的串口工具简介

    包括但不限于:

    Putty

    【整理】Windows用ssh连接Linux,想要从Linux上面上传/下载文件 -> putty的子工具psftp

    【整理】Windows下超级终端的最佳替代品,免费的串口终端工具Putty

    SecureCRT

    【crifan推荐】极佳的串口开发工具:SecureCRT

    超级终端(Hyper Terminal)

    【整理】如何在Win7中安装使用超级终端Hyper Terminal

        其中,之前整理了出来两个版本,放到csdn上了,供大家下载使用:

    1.不带hticons.dll的版本:

    Hyper Termina English ANSI + 超级终端 中文版

    http://download.csdn.net/source/3508497

    2.带hticons.dll的完整版本:

    Win7 超级终端Hyper Terminal

    http://download.csdn.net/source/3532046

    BOAST

    【整理】利用串口工具,周期性地发送数据(命令)

    (后来工作中看到别人用的)Commix

    Commix 工业控制串口调试工具 V1.4

        串口调试工具Commix V1.3

    http://download.csdn.net/detail/snhs163/3577953

        Commix混合输入串口调试工具 1.0 绿色版

    http://www.cngr.cn/dir/217/360/20130812100638.html

    其他,不同平台的,和串口,有关的:

    【整理】Android的USB转串口相关资料

     

     

     

    常见的USB转串口方面的内容:

    常见的Silicon labs的CP210X,FTDI的FT232R等,microchip(?)的PL2303,其他还有

    注意,有些是usb转其他的,比如usb转HART的,其内部也是usb转串口的

     

    包括相关的串口和串口终端软件有哪些:

    【整理】常用的串口工具简介

    包括windows的hyper terminal:

    【整理】如何在Win7中安装使用超级终端Hyper Terminal

    和其他的,比如

    pytty:

    http://www.crifan.com/files/doc/docbook/crifan_rec_soft/release/htmls/dev.putty.html

    中的:

    【整理】Windows下超级终端的最佳替代品,免费的串口终端工具Putty

    secureCRT:

    【记录】SecureCRT中用Ymodem传输文件,中途死掉Halt -> Ymodem-1K可以正常传输,但是完成后会死掉

    等等

    甚至包括其他一些串口的项目/工具/软件:

    Linux和Windows间文件传输工具rz/sz(lrz/lsz) 介绍

     

     

    串口RS232相关的一些协议

    【整理】Kermit Xmodem Xmodem-1K Ymodem Ymodem-G Ymodem-1K Zmodem

     

    相关的:

    【记录】去确定USB转串口中的握手协议handshaking方面的支持


    展开全文
  • 提供嵌入式linux下arm平台等的常用外设接口如spi、i2c等的硬件接口测试代码。
  • 嵌入式访问外设两种方式

    千次阅读 2013-11-02 15:21:08
    先说一个概念,内存映射。...此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要 设立专门的外设I/O指令。 简而言之,可以这样理解,要访问某个I/O ,只需要访问物理地址空间就可以做到
  • 嵌入式系统中,通常外设之间不能直接通信,对于一些需要外设联动的操作,需要MCU介入,比如定时到了,启动串口的发送/接收,则需要为定时器写一个中断处理程序,在其中启动串口动作。在有一些SoC中,提供了PRS功能...
  • 嵌入式系统的各种常见外设

    千次阅读 2019-05-20 11:10:38
    嵌入式系统的各种常见外设
  • 嵌入式USB主机/外设控制器版本。该器件符合AEC(汽车电子协会)Q100规范,提供了一个-40℃至85℃的工作温度范围。它面向汽车“信息娱乐”应用,包括实现MP3播放机、手机和GPS系统与车内无线电通信和显示系统的连接。...
  • 本文主要对嵌入式系统的各种常见外设进行了总结,下面一起来学习一下
  • 作者Email: sunchengli@sjzue.edu.cn 摘要:随着CPU的... 本文介绍软外设的设计思想以及在开发过程中应注意的事项,并结合一个嵌入式系统,分析软外设对系统的影响以及如何使设计合理化。 关键词:嵌入式系统 UAR
  • 嵌入式系统的各种常见外设总结docx,嵌入式系统的各种常见外设总结,嵌入式系统中,硬件方面,有很多常见的外围设备。在此,专门整理一下。
  • 什么是嵌入式系统中的外设外设==外部设备==Peripheral外部:主要指的是除了嵌入式系统中主要的CPU,即SoC,MCU等之外的设备:某种硬件功能模块外设==接口此处,所指的外设,也常被称为各种接口,硬件接口...
  • 1.GPIO之LED的测试 输入命令 cd /sys/class/leds ls 6个LED的控制程序 输入命令,熄灭PS_LED1,反之点亮 “echo 0 > ps_led1/brightness 命令,闪烁led2灯 echo timer > ps_led1/trigger ......
  • Cypress 半导体公司推出其专为汽车应用而优化的CY7C67300 EZ-Host嵌入式USB主机/外设控制器版本。该器件符合AEC(汽车电子协会)Q100规范,提供了一个-40℃至85℃的工作温度范围。它面向汽车信息娱乐应用,包括实现...
  • 临近比赛,板子坏了,于是将比赛中用到的各种外设写一遍,分享出来! 其中PWM以及捕获等定时器相关的全部放在定时器文件夹下~ 链接:https://pan.baidu.com/s/1o20nkOSLlntjSjxaX69UAg 提取码:hw8v 复制这段内容...
  • 介绍了硬件概念以及常用的单片机外设
  • ROS Robotics Projects(3)嵌入式硬件和外设 这本书的第4章和第5章,介绍了一些常用的嵌入式硬件和外设等, 具体也可以参考官网,包括Arduino,STM32,Raspberry Pi 2和Odroid。 具体可以参考: 1 ...
  • 在做嵌入式设计时,不免要在主芯片上挂各种外设,比如挂flash,挂加密芯片,挂网卡等等,在第一步编写驱动时需要检验主芯片所用的口是否能用,那怎么检测呢? IO口检测,把主芯片所用到的管脚配置成IO模式,然后对...
  • 我们需要用到boa,boa 是一个小型的 web 服务器,可执行代码只有约 60KB,可以用于多种平台,它一个单任务 web 服务器,只能依次完成用户的请求,在嵌入式中比较常见。boa 的官方网站为www.boa.org,可以在上面下载...
  • 嵌入式USB主机/外设控制器版本。该器件符合AEC(汽车电子协会)Q100规范,提供了一个-40℃至85℃的工作温度范围。它面向汽车“信息娱乐”应用,包括实现MP3播放机、手机和GPS系统与车内无线电通信和显示系统的连接。...
  • 嵌入式系统与设计-银川能源学院教案.docx 有嵌入式的基本概念,原理。 嵌入式硬件、嵌入式软件系统 嵌入式外设接口 外部设备驱动实验
  • 深圳蓝天嵌入式计算机增值套件及外设BS-BPC-4698pdf,深圳蓝天嵌入式计算机增值套件及外设BS-BPC-4698

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,743
精华内容 1,097
关键字:

嵌入式外设