请选择 进入手机版 | 继续访问电脑版
查看: 7626|回复: 0

如何使用NXP原厂SDK实现DMA操作详解

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-8 16:43
  • 签到天数: 299 天

    连续签到: 1 天

    [LV.8]以坛为家I

    3744

    主题

    7313

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    37888
    最后登录
    2025-4-27
    发表于 2020-12-17 10:45:29 | 显示全部楼层 |阅读模式
    如何使用NXP原厂SDK实现DMA操作详解


    为方便参加恩智浦大学生智能车设计竞赛的同学们,成都逐飞科技设计制作了i.MX RT1064核心板,并配套开发了相应的函数库。
    本文为逐飞科技来稿,在此分享给大家,对不参加智能车竞赛的朋友也有很大的帮助作用。
    点此回顾往期内容:
    GPIO详解
    FAST GPIO模块详解与使用示例
    ADC模块和QTIMER模块
    PIT模块详解与使用示例
    UART模块详解与使用示例

    PWM和CACHE模块的使用

    I2C模块和SPI模块的使用
    NVIC模块和EFUSE模块

    USB模块和uSDHC模块





    各位朋友好,逐飞科技连载的“基于RT1064的智能车应用入门指导”开发分享又来投稿啦!今天通过举例如何使用NXP原厂SDK,实现DMA操作的详解,来说明如何使用原厂的SDK。
    感谢恩智浦的支持,感谢梁平老师的支持以及帮忙检查修改文中错误,感谢关注“逐飞科技”。接下来进入我们今天分享的主题----“如何使用NXP原厂SDK实现DMA操作详解”。




    SDK实现DMA操作


    如果有需要使用的功能,但发现逐飞科技提供的开源库里面还没有提供的话,可以自己直接调用SDK的底层,实现芯片的任意功能。
    关于SDK的使用可以查看逐飞编写的库底层是如何调用SDK的,从而快速的了解SDK,并自己编写自己需求的功能。
    接下来我们以DMA为例,来讲解SDK的使用。我们使用DMA来完成将一个数组中的数据拷贝到另外一个数组中。


    1. DMA功能
    DMA(Direct Memory Access)是直接内存访问。通过DMA访问内存可以完全不需要CPU的干预,这样将数据搬运的工作交给DMA完成,而CPU则可以干其他更重要的事,以此提高效率。


    2. DMA库函数
    以下函数均位于fsl_edma.c和fsl_edma.h:
    21.png
    EDMA_Init函数参数
    22.png
    EDMA_Deinit函数参数
    23.png
    EDMA_GetDefaultConfig函数参数
    24.png
    EDMA_CreateHandle函数参数
    25.png
    EDMA_SetCallback函数参数
    26.png
    EDMA_PrepareTransfer函数参数
    27.png
    EDMA_SubmitTransfer函数参数
    28.png
    EDMA_StartTransfer函数参数
    29.png
    EDMA_StopTransfer函数参数
    30.png
    EDMA_AbortTransfer函数参数
    31.png
    DMA使用示例


    使用DMA进行内存数据拷贝

    1. #include "headfile.h"  
    2. #include "fsl_edma.h"  
    3. #include "fsl_dmamux.h"  
    4.   
    5. #define EXAMPLE_DMA                 DMA0      
    6. #define EXAMPLE_DMAMUX              DMAMUX  
    7. #define DMA0_DMA16_DriverIRQHandler DMA_CH_0_16_DriverIRQHandler  
    8. #define BUFF_LENGTH                 4U  
    9.   
    10. edma_handle_t g_EDMA_Handle1;  
    11. volatile bool g_Transfer_Done = false;  
    12.   
    13. //中断回调函数  void EDMA_Callback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)  
    14. {  
    15.     if (transferDone)  
    16.     {  
    17.         g_Transfer_Done = true;  
    18.     }  
    19. }  
    20.   
    21. AT_NONCACHEABLE_SECTION_INIT(uint32_t srcAddr[BUFF_LENGTH])  = {0x01, 0x02, 0x03, 0x04};  
    22. AT_NONCACHEABLE_SECTION_INIT(uint32_t destAddr[BUFF_LENGTH]) = {0x00, 0x00, 0x00, 0x00};  
    23.   
    24.   
    25. int main(void)  
    26. {  
    27.     uint32_t i = 0;  
    28.     edma_transfer_config_t transferConfig;  
    29.     edma_config_t userConfig;  
    30.   
    31.     BOARD_ConfigMPU();  
    32.     BOARD_InitPins();  
    33.     BOARD_BootClockRUN();  
    34.     BOARD_InitDebugConsole();  
    35.       
    36.     //打印例程信息  
    37.     PRINTF("EDMA memory to memory transfer example begin.\r\n\r\n");  
    38.     PRINTF("Destination Buffer:\r\n");  
    39.     for (i = 0; i < BUFF_LENGTH; i++)  
    40.     {  
    41.         PRINTF("%d\t", destAddr[i]);  
    42.     }  
    43.     //配置DMA复用设置  
    44.     DMAMUX_Init(EXAMPLE_DMAMUX);  
    45. #if defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON  
    46.     DMAMUX_EnableAlwaysOn(EXAMPLE_DMAMUX, 0, true);  
    47. #else  
    48.     DMAMUX_SetSource(EXAMPLE_DMAMUX, 0, 63);  
    49. #endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */  
    50.     DMAMUX_EnableChannel(EXAMPLE_DMAMUX, 0);  
    51.     //配置EDMA为仅工作一次模式

    52.     //userConfig.enableRoundRobinArbitration = false;  
    53.     //userConfig.enableHaltOnError = true;  
    54.     //userConfig.enableContinuousLinkMode = false;  
    55.     //userConfig.enableDebugMode = false;  
    56.     EDMA_GetDefaultConfig(&userConfig);  
    57.       
    58.     EDMA_Init(EXAMPLE_DMA, &userConfig);  
    59.     EDMA_CreateHandle(&g_EDMA_Handle1, EXAMPLE_DMA, 0);  
    60.     EDMA_SetCallback(&g_EDMA_Handle1, EDMA_Callback, NULL);  
    61.     EDMA_PrepareTransfer(&transferConfig, srcAddr, sizeof(srcAddr[0]), destAddr, sizeof(destAddr[0]),  
    62.                          sizeof(srcAddr[0]), sizeof(srcAddr), kEDMA_MemoryToMemory);  
    63.     EDMA_SubmitTransfer(&g_EDMA_Handle1, &transferConfig);  
    64.     EDMA_StartTransfer(&g_EDMA_Handle1);  
    65.       
    66.     //等待DMA发送完成  
    67.     while (g_Transfer_Done != true)  
    68.     {  
    69.     }  
    70.       
    71.     //打印目的数组信息  
    72.     PRINTF("\r\n\r\nEDMA memory to memory transfer example finish.\r\n\r\n");  
    73.     PRINTF("Destination Buffer:\r\n");  
    74.     for (i = 0; i < BUFF_LENGTH; i++)  
    75.     {  
    76.         PRINTF("%d\t", destAddr[i]);  
    77.     }  
    78.     while (1)  
    79.     {  
    80.     }  
    81. }
    复制代码
    编程要点:根据自己使用的模块包含对应的的头文件。

    随着本期分享的结束,逐飞科技连载的“基于RT1064的智能车应用入门指导”开发分享也都结束了,共12期讲了19个应用示例,再次感谢NXP梁老师的支持。
    大家在使用库的过程中如果遇到什么问题、或发现不足及建议请及时联系“逐飞科技”,我们将尽快完善。关注“逐飞科技”微信公众号与我们保持联系,下次再见!

    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-4-27 17:38 , Processed in 0.122104 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表