This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LC4357:QS:MPU 和 DMA 的融合?

Guru**** 2462880 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1100415/tms570lc4357-qs-the-confugrations-of-mpu-and-dma

器件型号:TMS570LC4357

大家好:

   在我的项目中 、我遇到了 MPU 和 DMA 配置问题。

   我想 通过 DMA 将数据从 SPI_RX_regs 传输到 RXBUF[256](在 RAM 中定义),它无法正常工作。  

   但是、如果我将 RXBUF[256]定义到 SDRAM 中、则 DMA 工作正常。  SDRAM 的 DMA 配置 与 RAM 相同。  下面是 DMA 的配置、请帮助我检查配置。

dmaConfigCtrlRxPacket((uint32) & (ram->rx[0].data), (uint32)pRxBuf, e_count, f_count, IsU8);
void dmaConfigCtrlRxPacket(uint32 src_add, uint32 des_add, uint32 e_count, uint32 f_count, uint16 IsU8)
{
  g_dmaCTRL_rx.SADD 		 = src_add + (uint32)(IsU8 == 1); 	 /* source address						 */
  g_dmaCTRL_rx.DADD 		 = des_add; 	 /* destination  address			 */

  g_dmaCTRL_rx.CHCTRL 	     = 0ul; 							/* channel control						*/
  g_dmaCTRL_rx.ELCNT		 = e_count; 					/* element count							*/
  g_dmaCTRL_rx.FRCNT		 = f_count; 					/* frame count								*/

  g_dmaCTRL_rx.RDSIZE 	 =  ACCESS_8_BIT ; 		 /* read size 								 */
  g_dmaCTRL_rx.WRSIZE 	 =  ACCESS_8_BIT ; 		 /* write size								 */

  //source
  g_dmaCTRL_rx.ELSOFFSET = 4;						 /* element source offset */
  g_dmaCTRL_rx.FRSOFFSET = 0; 							/* frame source offset */
  g_dmaCTRL_rx.ADDMODERD = ADDR_OFFSET; 			/* address mode read					*/
  //destination
  g_dmaCTRL_rx.ELDOFFSET = 0; 								 /* element destination offset */
  g_dmaCTRL_rx.FRDOFFSET = 0;            						/* frame destination offset */
  g_dmaCTRL_rx.ADDMODEWR = ADDR_INC1; 			 /* address mode write 				*/
  
  g_dmaCTRL_tx.PORTASGN  = PORTB_READ_PORTA_WRITE; /* port b */
  g_dmaCTRL_rx.TTYPE	 = FRAME_TRANSFER ; 	    /* transfer type							*/
  g_dmaCTRL_rx.AUTOINIT  = AUTOINIT_OFF; 			/* autoinit 									*/
}
  /* Assign DMA Control Packet to Channel 1 */
  dmaSetCtrlPacket(pDMAReqActCfg->nDMA_CHN_rx, g_dmaCTRL_rx);
  /* Assign DMA request: channel-m with request line - n */
  dmaReqAssign(pDMAReqActCfg->nDMA_CHN_rx, pDMAReqActCfg->nDMA_REQ_rx); /* Request Line i is MIBSPIx[j] */
  /* Set the DMA Channel n to trigger on h/w request */
  dmaSetChEnable(pDMAReqActCfg->nDMA_CHN_rx, DMA_HW);
  bRXDMAENAx = 1u;

  mibspi->DMACNTLEN	  =	1ul; /* Disable Large Count */
  mibspi->DMACOUNT[0] =	((uint32)(f_count - 1U)) << 16; /*lint !e701 f_count-1 is uint16 */
  mibspi->DMACTRL[0]  =	( 1ul << 31)	/* Auto-disable of DMA channel after ICOUNT+1 transfers. */
                        | ((e_count - 1U) << 24) /* Buffer utilized to trigger DMA transfer. */
                        | (((uint32)pDMAReqActCfg->nDMA_MAP_rx) << 20)	 /* RXDMA_MAPx */
                        | (((uint32)pDMAReqActCfg->nDMA_MAP_tx) << 16)	 /* TXDMA_MAPx */
                        | (((uint32)bRXDMAENAx) << 15)	 /* Receive data DMA channel enable. */
                        | (((uint32)bTXDMAENAx) << 14)	 /* Transmit data DMA channel enable. */
                        | ( 0ul << 13)	 /* Non-interleaved DMA block transfer. This bit is available in master mode only. */
                        | ( 0ul <<	8);  /* ICOUNTx */
  dmaEnable();

   第二部分是 MPU 的配置。  我是第一次使用 MPU 函数,所以 还没有解决。 另外、请帮助我查看 MPU 的配置:

    // RAM, default read-only access
    mpuInitRegion(
        (U32) 0, //MPU_REGION_DEFAULT_INTERNAL_RAM
        0x08000000u,
        (U32)INTERNAL_RAM_SIZE | MPU_REG_EN,     
        #if BOOT_STAGE==0 
    		#define RAM_RULES (MPU_PRIV_RW_USER_RO_EXEC | MPU_NORMAL_OIWBNOWA_SHARED)
  	 #else
    	 	#define RAM_RULES (MPU_PRIV_RW_USER_RO_NOEXEC | MPU_NORMAL_OIWBNOWA_NONSHARED)
        );

    // peripherials, default read-only access
    mpuInitRegion(
        (U32)1, //MPU_REGION_DEFAULT_IO
        0xFF000000u,
        (U32)MPU_16_MB | MPU_REG_EN,
        (U32)MPU_PRIV_RW_USER_RO_NOEXEC | (U32)MPU_STRONGLYORDERED_SHAREABLE
        );
        
   mpuInitRegion(
        (U32) 2,//MPU_REGION_DEFAULT_EXTERNAL_RAM
        0x80000000,
        8MB_SIZE,
        (U32)MPU_PRIV_RW_USER_RO_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
        );
        
   mpuInitRegion( //do MPU setting for 0x0800_0000 to 0803_0000 shared
      (U32) 4,//MPU_REGION_SHAREABLE
     mpuSetting.drbar, 
     mpuSetting.drsr,
      (U32)MPU_PRIV_RW_USER_RO_NOEXEC | MPU_NORMAL_OIWBNOWA_SHARED //PRQA S 4522 //enum types used in operation (|)
      );
     
   mpuInitRegion(
      (U32) 5,//MPU_REGION_SHAREABLE_END
       0x8040000,
       0x40000,
      (U32)MPU_PRIV_RW_USER_RO_NOEXEC | MPU_NORMAL_OIWBNOWA_SHARED //PRQA S 4522 //enum types used in operation (|)
      ); 
        
   mpuInitRegion( //do MPU setting for 0x0800_0000 to 0x0801_0000 , non shared 
      (U32) 6,//MPU_REGION_FIRMWARE
      mpuSetting.drbar,
      mpuSetting.drsr,
      (U32)MPU_PRIV_RW_USER_RO_NOEXEC | MPU_NORMAL_OIWBNOWA_NONSHARED //PRQA S 4522 //enum types used in operation (|)
      );
        
    // process stack (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32) 8,//MPU_REGION_STACK
        0u,
        0u,
#if BOOT_STAGE==0 //PRQA S 1252, 3332 //define in makefile
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
#else
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_NONSHARED
#endif
        );

    // process stack non-access (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32)9,// MPU_REGION_STACK_PROTECT
        0u,
        0u,
        (U32)MPU_PRIV_NA_USER_NA_EXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
        );

    // process static variables I (DRBAR, DRSR will be filled by context switch)
  
    mpuInitRegion(
        (U32)10,// MPU_REGION_RAM_1,
        0u,
        0u,
#if BOOT_STAGE==0 //PRQA S 1252, 3332 //define in makefile
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
#else
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_NONSHARED
#endif
        );
#if 1
    // process static variables II (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32) 11, //MPU_REGION_RAM_2
        0u,
        0u,
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
        );
#endif

    // process pool I (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32) 12,//MPU_REGION_POOL_1
        0u,
        0u,
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
        );

    // process pool II (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32)13,// MPU_REGION_POOL_2
        0u,
        0u,
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_NORMAL_OIWBNOWA_SHARED
        );

    // process peripherial (DRBAR, DRSR will be filled by context switch)
    mpuInitRegion(
        (U32) 14,//MPU_REGION_USERIO
        0u,
        0u,
        (U32)MPU_PRIV_RW_USER_RW_NOEXEC | (U32)MPU_STRONGLYORDERED_SHAREABLE
        );

    // Flash, read only
    mpuInitRegion(
        (U32) 15,//MPU_REGION_FLASH
        0x00000000u,
        MPU_FLASH_SIZE | MPU_REG_EN,
        (U32)MPU_PRIV_RO_USER_RO_EXEC | (U32)MPU_NORMAL_OIWTNOWA_NONSHARED
        );

    mpuInitEnd();    // enable MPU & enable Background region

 RAM 中 RXBUF[256]的地址为0x08050000、在我的配置中 、这个区域是"MPU_PRIV_RW_USER_RO_NOexec | MPU_NORY_OIWBNOWA_SHARE"、与 SDRAM 相同。 但是、DMA 在 SDRAM 中工作、而不是在 RAM 中工作。

  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Li、

    SRAM 上的 MPU 设置只影响 CPU 访问存储器区域的方式:回写、直写、只读等

    上次我与您共享 DMA 示例时。 您是否能够使用 DMA 将数据从一个 SRAM 位置传输到另一个 SRAM 位置? 您是否为 DMA 设置了 NMPU?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    默认情况下、DMA 的 NMPU 区域不启用。 您可以检查 NMPU2寄存器的值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否能够使用 DMA 将数据从一个 SRAM 位置传输到另一个 SRAM 位置?

    我正在为 LC4357的 launchpad 而努力、因此我不会尝试它。

    您是否为 DMA 设置了 NMPU?

    我不为 DMA 设置 NMPU。 此步骤是否必要? 我还记得、您告诉我、NMPU 默认处于关闭状态、因此我认为 NMPU 对于 DMA 传输来说不是必需的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    SRAM 上的 MPU 设置只影响 CPU 访问存储器区域的方式:回写、直写、只读等

    在我看来、如果 SRAM 上的 MPU 设置不是共享的、那么 DMA 不应该访问 SRAM?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经在 launchpad 上尝试过您的代码。

    结果 只有"RXDATA_ram0[0]-RXDATA_ram0[39]"可以通过 DMA 接收数据。  "RXDATA_RAM1[0]-RXDATA_RAM1[59]"可以通过 DMA 接收数据。

    2.下面是“SHAREDRAM (RW): origin=0x0807A000 length=0x0005000”的 MPU 设置。 此外、我不确定优先级是否合适? 我是否应该使用更高优先级(区域5或更高?)?

        ; Setup region 3
            mov   r0,  #2
            mcr   p15, #0,    r0, c6, c2, #0
            ldr   r0,  r3Base
            mcr   p15, #0,    r0, c6, c1, #0
            mov   r0,  #0x0006				;	MPU_NORMAL_OIWTNOWA_SHARED
            orr   r0,  r0,    #0x1300		;	MPU_PRIV_RW_USER_RW_NOEXEC
            mcr   p15, #0,    r0, c6, c1, #4
            movw  r0,  #((0 << 15) + (0 << 14) + (0 << 13) + (0 << 12) + (0 << 11) + (0 << 10) + (0 <<  9) + (0 <<  8) + (0x13 << 1) + (1))
            mcr   p15, #0,    r0, c6, c1, #2

    3.我的 QS 是: 当我设置 区域3的属性时, 如果该区域的大小小于512KB,则主板将无法正常运行。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该器件的 SRAM 大小为512KB。 如果您选择小于512KB (例如256KB)的大小、则在访问定义区域之外的地址时会中止。  对 未映射到 MPU 中某个区域的地址的所有访问都会产生一个后台故障。