读写Stellaris Cortex-M3片上RAM和FLASH

概述为:

可以用片上MPU单元开辟一块存储区域,通过指令读-写该区域,实现数据的自定义存储-读取。该操作对片上RAM和FLASH同样有效。该操作是动态的,根据需求建立MPU内存区域,用完之后可以释放内存。

除了LM3S101和LM3S102之外,Stellaris M3都有片上MPU单元,有无片上ROM并不影响MPU的使用。

参考例程来自:SW-EK-LM3S8962-8555(无片上ROM) 或SW-EK-LM3S3748-8555(有片上ROM)等的例程mpu-fault。

操作流程描述为:
  1. 定义MPU控制的存储区域,包括地址、大小、使能、读写控制
  2. 编写MPU出错中断服务子程序
  3. 使能MPU。注意,如果对MPU保护的区域进行不正确访问,如对read-only的区域写数据,则用户自定义的MPU出错中断服务子程序会产生出错信息,并除能MPU。因此要保证对MPU保护区域正确操作,并注意使能MPU。
  4. 对MPU控制区域进行读-写。
  5. 除能MPU保护,释放内存,这样其他部分程序可以使用该区域。

实例讲解:

1、定义MPU控制区域,使用MPURegionSet函数

    //
    // Configure an executable, read-only MPU region for flash.  It is an 8 KB
    // region with the last 1 KB disabled to result in a 7 KB executable
    // region.  This region is needed so that the program can execute from
    // flash.
    //
    MPURegionSet(0, FLASH_BASE,
                 MPU_RGN_SIZE_8K |
                 MPU_RGN_PERM_EXEC |
                 MPU_RGN_PERM_PRV_RO_USR_RO |
                 MPU_SUB_RGN_DISABLE_7 |
                 MPU_RGN_ENABLE);

    //
    // Configure a read-write MPU region for RAM.  It is a 64 KB region.  There
    // is a 8 KB sub-region in the middle that is disabled in order to open up
    // a hole in which different permissions can be applied.
    //
    MPURegionSet(1, SRAM_BASE,
                 MPU_RGN_SIZE_64K |
                 MPU_RGN_PERM_NOEXEC |
                 MPU_RGN_PERM_PRV_RW_USR_RW |
                 MPU_SUB_RGN_DISABLE_4 |
                 MPU_RGN_ENABLE);

MPURegionSet的宏定义为:

#define ROM_MPURegionSet                                                      \
        ((void (*)(unsigned long ulRegion,                                    \
                   unsigned long ulAddr,                                      \
                   unsigned long ulFlags))ROM_MPUTABLE[5])


2、MPU出错中断服务子程序
g_ulMMAR 用来记录出错地址
g_ulFaultStatus 用来记录NVIC出错状态
g_ulMPUFaultCount 用来记录出错次数

void MPUFaultHandler(void)
{
    //
    // Preserve the value of the MMAR (the address causing the fault).
    // Preserve the fault status register value, then clear it.
    //
    g_ulMMAR = HWREG(NVIC_MM_ADDR);
    g_ulFaultStatus = HWREG(NVIC_FAULT_STAT);
    HWREG(NVIC_FAULT_STAT) = g_ulFaultStatus;

    //
    // Increment a counter to indicate the fault occurred.
    //
    g_ulMPUFaultCount++;

    //
    // Disable the MPU so that this handler can return and cause no more
    // faults.  The actual instruction that faulted will be re-executed.
    //
    MPUDisable();
}
3、使能MPU出错中断和MPU控制

    //
    // Enable the MPU fault.
    //
    IntEnable(FAULT_MPU);

    //
    // Enable the MPU.  This will begin to enforce the memory protection
    // regions.  The MPU is configured so that when in the hard fault or NMI
    // exceptions, a default map will be used. 
    //
    MPUEnable(MPU_CONFIG_HARDFLT_NMI);
可用如下程序来核查是否错误

    //
    // Verify that the fault occurred, at the expected address.
    //
    if((g_ulMPUFaultCount == 1) &&
       (g_ulFaultStatus == 0x82) &&
       (g_ulMMAR == 0x100))
    {
        RIT128x96x4StringDraw(" OK", 108, 16, 15);
    }
    else
    {
        bFail = 1;
        RIT128x96x4StringDraw("NOK", 108, 16, 15);
    }
4、对MPU保护的区域进行读写
为HWREG(ADDR)进行赋值,则是写数据,如HWREG(0x20008460) = 0xabcdef00;
把HWREG(ADDR)的数据赋给变量,则是读数据,如g_ulValue = HWREG(0x20008440);

5、除能MPU,释放内存

    //
    // Disable the MPU, so there are no lingering side effects if another
    // program is run.
    //
    MPUDisable();



你可能感兴趣的:(Cortex-)