硬汉嵌入式论坛

 找回密码
 立即注册
查看: 16302|回复: 9
收起左侧

[客户分享] 使用J-Link 直接读写 STM32-V5 开发板的NOR Flash

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2013-9-24 11:57:16 | 显示全部楼层 |阅读模式
这是 J-Flash 程序的工程文件
STM32-V5_NOR.jflash.rar (3 KB, 下载次数: 221)

操作步骤:
1、Windows开始菜单中启动 J-Flash ARM 程序
2、点击菜单File -> Open project,选择: STM32-V5_NOR.jflash 文件  (rar解压后的得到)
3、可以读NOR:   点击菜单Target ->Read back -> Entire chip , 读取NOR 芯片数据。
4、装载新文件,点击菜单 open data file, 选择一个 bin 文件,弹出窗口中地址填写 64000000
5、开始烧写,点击菜单 Targe->Auto (也可以按F7键),开始自动编程(带校验)

读完整的16M NOR Flash 时间:49秒
读NOR时间.PNG

写NOR Flash时间:246秒 (测试文件的有效数据数据是5MB)
写NOR时间.PNG


下面这个rar工程是我用来提取J-Link 配置NOR Flash脚本用的,放在此地备份。
F4-005_初始化NOR Flash的MDK工程(提取 J-Link调试脚本).rar (4.27 MB, 下载次数: 318)

为了实现J-Link仿真器烧写NOR Flash,我们需要让仿真器预先执行一段指令来配置STM32的GPIO和FSMC。一种办法是查阅CPU的参考手册,学习时钟寄存器、GPIO寄存器、FSMC相关的寄存器的设置方法。另外一种方法是从成熟的C范例中获取这些寄存器值数据。第一种方法需要花大量的时间学习这些寄存器。第二种方法相对简单有效一些(我花了2个小时搞定)
参考例程:F4-005_NOR Flash访问例程
参考的c函数:
(1)   system_stm32f4xx.c 中的函数 void SystemInit(void)
(2)   system_stm32f4xx.c 中的函数 SetSysClock()   <--- 这个函数用于配置时钟,启动PLL
(3)   bsp_nor_flash.c中的 bsp_InitNorFlash()函数。  <--- 这个函数用于配置GPIO和FSMC
为了讲解整个过程,我们在此贴出函数内容。红色部分的寄存器地址和寄存器是通过J-Link仿真器在线单步跟踪获得的,完全没必要去查阅寄存器地址和构建寄存器数值。
下面我们举个例子解码这句代码:
  RCC->CR |= (uint32_t)0x00000001;
步骤:
(1)  在 文件开头定义2个全局变量 :static uint32_t raddr, rvalue;
(2)  在寄存器操作语句后面添加如下代码:
  raddr = (uint32_t)&RCC->CR;  rvalue = *(uint32_t *)raddr;  
(3)  将 raddr, rvalue 加到 Watch 窗口(右边的窗口)
(4) 单步执行完后 raddr = 这行代码后,记录此时的寄存器地址和寄存器值
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2013-9-24 12:14:43 | 显示全部楼层
顺便附上解码中间记录:

下面是解码过程:结果过程用红色文字表示
void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;  <---  寄存器 0x40023800  = 0x0000A583
  /* Reset CFGR register */
  RCC->CFGR = 0x00000000; <---  寄存器 0x40023808  = 0x00000000
  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF; <---  寄存器 0x40023800  = 0x0000A583
  /* Reset PLLCFGR register */
  RCC-&gtLLCFGR = 0x24003010;  <---  寄存器 0x40023804  = 0x24003010
  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF; <---  寄存器0x40023800  = 0x0000A583
  /* Disable all interrupts */
  RCC->CIR = 0x00000000;  <---  寄存器 0x4002380C  = 0x00000000
/* Configure the System clock source, PLL Multiplier and Divider factors,
     AHB/APBx prescalers and Flash settings ----------------------------------*/
  SetSysClock();
  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */   
#endif
}
static void SetSysClock(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* Enable HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);    <---  寄存器 0x40023800  = 0x0003A583
<--- 等待时钟稳定,可以直接Delay一段固定时长
/* Wait till HSE is ready and if Time out is reached exit */   
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
<--- 下面是判断时钟是否启动成功。正常都会启动成功。我们可以不处理异常分支。
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }
<--- 正常情况下,时钟应该启动成功
  if (HSEStatus == (uint32_t)0x01)
  {
    /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;  <---  寄存器0x40023840 = 0x10000000
    PWR->CR |= PWR_CR_VOS;           <---  寄存器0x40023800 = 0x0003A583
    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;    <---  寄存器0x40023808 = 0x00000000
      
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;    <---  寄存器0x40023808 = 0x00008000
   
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;    <---  寄存器0x40023808 = 0x00009400
    /* Configure the main PLL */
    RCC-&gtLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);  <---  寄存器0x40023804 = 0x07405419
    /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON;  <---  寄存器0x40023800 = 0x0303A583
    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)   <--- 等待时钟稳定,可以Delay固定时长
    {
    }
   
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; <---  寄存器0x40023C00 = 0x00000605
    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  <---  寄存器0x40023808 = 0x00009400
    RCC->CFGR |= RCC_CFGR_SW_PLL; <---  寄存器0x40023808 = 0x0000940A
    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); <--- 等待时钟稳定,可以Delay固定时长
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock
         configuration. User can add here some code to deal with this error */
  }
}
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2013-9-24 12:17:58 | 显示全部楼层
继续:

下面开始配置 GPIO和FSMC
void bsp_InitNorFlash(void)
{
     FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
     FSMC_NORSRAMTimingInitTypeDef  p;
     GPIO_InitTypeDef GPIO_InitStructure;
     /* 使能GPIO时钟 */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF |
                  RCC_AHB1Periph_GPIOG, ENABLE);   // 找到RCC_AHB1PeriphClockCmd 函数,可以看到这个函数修改的寄存器名字
<---  寄存器0x40023830 = 0x00100078
     /* 使能 FSMC 时钟 */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); <---  寄存器0x40023838 = 0x00000001
     /* GPIOD configuration */
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  | GPIO_Pin_1  | GPIO_Pin_4  | GPIO_Pin_5  |
                         GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 | GPIO_Pin_11 |
                         GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
     GPIO_Init(GPIOD, &GPIO_InitStructure);
     /* GPIOE configuration */
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource3 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource6 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 |
                         GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_6 | GPIO_Pin_7 |
                         GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 | GPIO_Pin_11|
                         GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
     GPIO_Init(GPIOE, &GPIO_InitStructure);
     /* GPIOF configuration */
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FSMC);
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  | GPIO_Pin_1  | GPIO_Pin_2  | GPIO_Pin_3  |
                         GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_12 | GPIO_Pin_13 |
                         GPIO_Pin_14 | GPIO_Pin_15;
     GPIO_Init(GPIOF, &GPIO_InitStructure);
     /* GPIOG configuration */
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource2 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource3 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource5 , GPIO_AF_FSMC);
     GPIO_PinAFConfig(GPIOG, GPIO_PinSource9 , GPIO_AF_FSMC);
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  | GPIO_Pin_1  | GPIO_Pin_2  | GPIO_Pin_3 |
                         GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_9;
     GPIO_Init(GPIOG, &GPIO_InitStructure);
     /* PD6 作为忙信号, 配置为GPIO输入模式,软件查询 */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;       /* 输入模式 */
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
     GPIO_Init(GPIOD, &GPIO_InitStructure);
#if 0
     上面的代码的目的配置 GPIO相关的寄存器
typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;
     为了查看方便,我们添加一些代码:
     GPIOD GPIOE GPIOF GPIOG
#endif
#if  1   /* 添加的测试代码 */
     {
         static uint32_t addr, value;
         addr = (uint32_t)&GPIOD->MODER;  value = *(uint32_t *)addr; <---  寄存器0x40020C00= 0xAAAA0A0A
         addr = (uint32_t)&GPIOD->OTYPER;  value = *(uint32_t *)addr; <---  寄存器0x40020C04=0x00000000
         addr = (uint32_t)&GPIOD->OSPEEDR;  value = *(uint32_t *)addr; <---  寄存器0x40020C08=0xFFFF0F0F
         addr = (uint32_t)&GPIOD-&gtUPDR;  value = *(uint32_t *)addr; <---  寄存器0x40020C0C=0x00000000
         //addr = (uint32_t)&GPIOD->IDR;  value = *(uint32_t *)addr; <---  寄存器0x40020C10=0x000000FD
         //addr = (uint32_t)&GPIOD->ODR;  value = *(uint32_t *)addr; <---  寄存器0x40020C14=0x00000000
         //addr = (uint32_t)&GPIOD->BSRRL;  value = *(uint32_t *)addr; <---  寄存器0x40020C18=0x00000000
         //addr = (uint32_t)&GPIOD->BSRRH;  value = *(uint32_t *)addr; <---  寄存器0x40020C1A=0x00000000
         //addr = (uint32_t)&GPIOD->LCKR;  value = *(uint32_t *)addr; <---  寄存器0x40020C1C=0x00000000
         addr = (uint32_t)&GPIOD->AFR[0];  value = *(uint32_t *)addr; <---  寄存器0x40020C20=0x00CC00CC
         addr = (uint32_t)&GPIOD->AFR[1];  value = *(uint32_t *)addr; <---  寄存器0x40020C24=0xCCCCCCCC
         addr = (uint32_t)&GPIOE->MODER;  value = *(uint32_t *)addr; <---  寄存器0x40021000= 0xAAAAAA80
         addr = (uint32_t)&GPIOE->OTYPER;  value = *(uint32_t *)addr; <---  寄存器0x40021004=0x00000000
         addr = (uint32_t)&GPIOE->OSPEEDR;  value = *(uint32_t *)addr; <---  寄存器0x40021008=0xFFFFFFC0
         addr = (uint32_t)&GPIOE-&gtUPDR;  value = *(uint32_t *)addr; <---  寄存器0x4002100C=0x00000000
         //addr = (uint32_t)&GPIOE->IDR;  value = *(uint32_t *)addr; <---  寄存器0x40021010=0x00006004
         //addr = (uint32_t)&GPIOE->ODR;  value = *(uint32_t *)addr; <---  寄存器0x40021014=0x00000000
         //addr = (uint32_t)&GPIOE->BSRRL;  value = *(uint32_t *)addr; <---  寄存器0x40021018=0x00000000
         //addr = (uint32_t)&GPIOE->BSRRH;  value = *(uint32_t *)addr; <---  寄存器0x4002101A=0x00000000
         //addr = (uint32_t)&GPIOE->LCKR;  value = *(uint32_t *)addr; <---  寄存器0x4002101C=0x00000000
         addr = (uint32_t)&GPIOE->AFR[0];  value = *(uint32_t *)addr; <---  寄存器0x40021020=0xCCCCC000
         addr = (uint32_t)&GPIOE->AFR[1];  value = *(uint32_t *)addr; <---  寄存器0x40021024=0xCCCCCCCC
         addr = (uint32_t)&GPIOF->MODER;  value = *(uint32_t *)addr; <---  寄存器0x40021400= 0xAA000AAA
         addr = (uint32_t)&GPIOF->OTYPER;  value = *(uint32_t *)addr; <---  寄存器0x40021404=0x00000000
         addr = (uint32_t)&GPIOF->OSPEEDR;  value = *(uint32_t *)addr; <---  寄存器0x40021408=0xFF000FFF
         addr = (uint32_t)&GPIOF-&gtUPDR;  value = *(uint32_t *)addr; <---  寄存器0x4002140C=0x00000000
         //addr = (uint32_t)&GPIOF->IDR;  value = *(uint32_t *)addr; <---  寄存器0x40021410=0x00000980
         //addr = (uint32_t)&GPIOF->ODR;  value = *(uint32_t *)addr; <---  寄存器0x40021414=0x00000000
         //addr = (uint32_t)&GPIOF->BSRRL;  value = *(uint32_t *)addr; <---  寄存器0x40021418=0x00000000
         //addr = (uint32_t)&GPIOF->BSRRH;  value = *(uint32_t *)addr; <---  寄存器0x4002141A=0x00000000
         //addr = (uint32_t)&GPIOF->LCKR;  value = *(uint32_t *)addr; <---  寄存器0x4002141C=0x00000000
         addr = (uint32_t)&GPIOF->AFR[0];  value = *(uint32_t *)addr; <---  寄存器0x40021420=0x00CCCCCC
         addr = (uint32_t)&GPIOF->AFR[1];  value = *(uint32_t *)addr; <---  寄存器0x40021424=0xCCCC0000
         addr = (uint32_t)&GPIOG->MODER;  value = *(uint32_t *)addr; <---  寄存器0x40021800= 0x00080AAA
         addr = (uint32_t)&GPIOG->OTYPER;  value = *(uint32_t *)addr; <---  寄存器0x40021804=0x00000000
         addr = (uint32_t)&GPIOG->OSPEEDR;  value = *(uint32_t *)addr; <---  寄存器0x40021808=0x000C0FFF
         addr = (uint32_t)&GPIOG-&gtUPDR;  value = *(uint32_t *)addr; <---  寄存器0x4002180C=0x00000000
         //addr = (uint32_t)&GPIOG->IDR;  value = *(uint32_t *)addr; <---  寄存器0x40021810=0x000016C0
         //addr = (uint32_t)&GPIOG->ODR;  value = *(uint32_t *)addr; <---  寄存器0x40021814=0x00000000
         //addr = (uint32_t)&GPIOG->BSRRL;  value = *(uint32_t *)addr; <---  寄存器0x40021818=0x00000000
         //addr = (uint32_t)&GPIOG->BSRRH;  value = *(uint32_t *)addr; <---  寄存器0x4002181A=0x00000000
         //addr = (uint32_t)&GPIOG->LCKR;  value = *(uint32_t *)addr; <---  寄存器0x4002181C=0x00000000
         addr = (uint32_t)&GPIOG->AFR[0];  value = *(uint32_t *)addr; <---  寄存器0x40021820=0x00CCCCCC
         addr = (uint32_t)&GPIOG->AFR[1];  value = *(uint32_t *)addr; <---  寄存器0x40021824=0x000000C0
     }
#endif
     /*-- FSMC Configuration ------------------------------------------------------*/
     p.FSMC_AddressSetupTime = 0x06;           /* 0x05正常, 0x04 出错 */
     p.FSMC_AddressHoldTime = 0x01;
     p.FSMC_DataSetupTime = 0x0C;              /* 0x0B正常, 0x0A 出错 */
     p.FSMC_BusTurnAroundDuration = 0x00;
     p.FSMC_CLKDivision = 0x00;
     p.FSMC_DataLatency = 0x00;
     p.FSMC_AccessMode = FSMC_AccessMode_B;
     FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
     FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
     FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
     FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
     FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
     FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
     FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
     FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
     FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
     FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
     FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
     FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
     FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
     FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
     FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
     FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
#if 1  //添加的测试代码
     //FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_SET;
     //FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = ...
    //FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF;
    {
         static uint32_t addr, value;
         addr = (uint32_t)&FSMC_Bank1->BTCR[FSMC_NORSRAMInitStructure.FSMC_Bank];  value = *(uint32_t *)addr;
<---  寄存器0xA0000008 =0x00001058
         addr = (uint32_t)&FSMC_Bank1->BTCR[FSMC_NORSRAMInitStructure.FSMC_Bank+1];  value = *(uint32_t *)addr;
<---  寄存器0xA000000C =0x10000C16
         addr = (uint32_t)&FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStructure.FSMC_Bank];  value = *(uint32_t *)addr;
<---  寄存器0xA000010C =0x0FFFFFFF
     }
#endif
     /*!< Enable FSMC Bank1_SRAM2 Bank */
     FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);    0xA0000008  = 0X1059
    addr = (uint32_t)&FSMC_Bank1->BTCR[FSMC_NORSRAMInitStructure.FSMC_Bank];  value = (*(uint32_t *)addr);
<---  寄存器0xA0000008  =0x00001059
while (1);   // 原地踏步
寄存器配置完毕,之后 J-Link 就可以直接访问NOR Flash了。
NOR Flash物理地址:0x6400 0000
回复

使用道具 举报

0

主题

20

回帖

20

积分

新手上路

积分
20
发表于 2014-6-26 15:41:48 | 显示全部楼层
弹出错误提示
Can not read register 20(CFBP) while CPU is running
请问这个怎么处理
回复

使用道具 举报

0

主题

4

回帖

0

积分

新手上路

积分
0
发表于 2017-7-11 13:42:40 | 显示全部楼层
你好,请问FLASH上锁后怎么进行读写呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107462
QQ
发表于 2017-7-11 14:09:59 | 显示全部楼层

回 三里十步 的帖子

三里十步:你好,请问FLASH上锁后怎么进行读写呢? (2017-07-11 13:42) 
解锁。
回复

使用道具 举报

0

主题

4

回帖

0

积分

新手上路

积分
0
发表于 2017-7-12 09:33:41 | 显示全部楼层
可是解锁FLASH不是会擦除其中的内容吗
回复

使用道具 举报

0

主题

4

回帖

0

积分

新手上路

积分
0
发表于 2017-7-12 09:36:37 | 显示全部楼层

回 eric2013 的帖子

eric2013:解锁。 (2017-07-11 14:09) 
我在想STM32内部的加解锁函数是不是直接修改了option_bytes里面控制FLASH的标志位。
能不能直接修改标志位,但是保留FLASH中的内容。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107462
QQ
发表于 2017-7-12 10:04:15 | 显示全部楼层

回 三里十步 的帖子

三里十步:我在想STM32内部的加解锁函数是不是直接修改了option_bytes里面控制FLASH的标志位。
能不能直接修改标志位,但是保留FLASH中的内容。
 (2017-07-12 09:36) 
你这个是要复制程序出来? 这个就不清楚了。
回复

使用道具 举报

0

主题

4

回帖

0

积分

新手上路

积分
0
发表于 2017-7-12 10:24:47 | 显示全部楼层

回 eric2013 的帖子

eric2013:你这个是要复制程序出来? 这个就不清楚了。 (2017-07-12 10:04) 
对,在研究JTAG安全方面的问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-2 03:47 , Processed in 0.215953 second(s), 35 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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