STM32+NAND FLASH做U盘,程序运行后格式化失败,而且查看容量为0,是啥原因
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32+NAND FLASH做U盘,程序运行后格式化失败,而且查看容量为0,是啥原因相关的知识,希望对你有一定的参考价值。
参考技术A 通过重新对U盘进行分区,利用磁盘分区工具和磁盘碎片处理软件进行处理,然后再重新启动计算机,就会解决该问题。我的U盘就是我弄好的本回答被提问者采纳 参考技术B 把U盘进行分区,利用磁盘分区工具和磁盘碎片处理软件进行处理然后再重新启动计算机,就会解决该问题。 参考技术C 我也遇到同样的问题了,你现在解决这个问题了吗?原因是什么?
移值2016的u-boot-第2篇-支持Nand flash启动
1, 要求:在4K 的代码以内,完成 NOR NAND 类型判断,初始化 NAND 复制自身到 SDRAM ,重定向。
2, 在 /arch/arm/cpu/arm920t/ 文件夹里 添加一个 inic.c 的文件,要在这个文件里面做上面说的事情。
修改 /arch/arm/cpu/arm920t/Makefile 加入 inic.c 的 编译。
extra-y = start.o
obj-y += init.o
obj-y += cpu.o
init.c 最后有补丁文件
3, 在 start.S 中初始化 SP 后调用 init.c 中的 初始化 NAND FLASH 和 复制 u-boot 到 SDRAM 清BSS 等
ldr sp, =4096 #在 NOR 启动时定在这里是不能写的,sp 中通常是保存 入栈 出栈 , 局部变量等,因为函数中并没有用到,设不设这里都可以。
bl init_sdram
ldr sp, =0x34000000
bl nand_init_ll
/**
* 从 0 地址开始复制 到 SDRAM 中
* 在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE
* u-boot 的加载地址
*/
mov r0,#0
ldr r1,=CONFIG_SYS_TEXT_BASE
ldr r2,=__bss_start
sub r2, r2, r1
bl copy_code_to_sdram
bl clear_bss #清不清都可以,因为重定向那里还要在清一次,为了以后去掉重定向这里也清。
#从片内 4K 跳到 SDRAM 中 bl 不行,要用 ldr pc
ldr pc,=_main
4, 启用流程
/arch/arm/cpu/arm920t/start.S
/arch/arm/lib/crt0.S
u-boot 第一阶段
/common/Board_f.c 中的 board_init_f() 函数
最后调用
jump_to_copy()
if (gd->flags & GD_FLG_SKIP_RELOC)
return 0;
调用/arch/arm/librelocate.S relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);
执行完毕后返回
crt0.S
bl board_init_f
下面直接执行第2阶段,也是因为执行了重定位,bl 跳不了
ldr pc, =board_init_r
5, 如何兼容 NOR FLASH NAND FLASH 启用?
不改动 原来的 重定位代码比较简单。
兼容 NOR FLASH NAND FLASH 的方法是,如果不想修改重定位的代码,就是先把 u-boot 复制到
SDRAM 的一个低地址,然后,它会从 这里在复制到 SDRAM 的高地址去。
NAND FLASH 启用要做的就是,在 4K 自动复制的代码里面,实现把u-boot 复制到 SDRAM 的低地址
6, 确定一个可用的链接地址
crt0.S
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
这里先把 sp 定在了最低端,因此不能使用 0x30000000
又因为u-boot 最终会被放到高地址也不能用 0x34000000
因为内存很大,放在10M 的位置吧。
在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE 0x30a00000
补丁文件:
1 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/init.c u-boot-2016.03-ok/arch/arm/cpu/arm920t/init.c 2 --- u-boot-2016.03/arch/arm/cpu/arm920t/init.c 1970-01-01 07:00:00.000000000 +0700 3 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/init.c 2016-05-17 06:48:31.635438931 +0800 4 @@ -0,0 +1,196 @@ 5 +/* NAND FLASH控制器 */ 6 +#define NFCONF (*((volatile unsigned long *)0x4E000000)) 7 +#define NFCONT (*((volatile unsigned long *)0x4E000004)) 8 +#define NFCMMD (*((volatile unsigned char *)0x4E000008)) 9 +#define NFADDR (*((volatile unsigned char *)0x4E00000C)) 10 +#define NFDATA (*((volatile unsigned char *)0x4E000010)) 11 +#define NFSTAT (*((volatile unsigned char *)0x4E000020)) 12 + 13 +/* CLK */ 14 +#define CLKDIVN (*(volatile unsigned long *)0x4C000014) 15 +#define MPLLCON (*(volatile unsigned long *)0x4C000004) 16 + 17 +/* SDRAM */ 18 +#define BWSCON (*(volatile unsigned long *)0x48000000) 19 +#define BANKCON6 (*(volatile unsigned long *)0x4800001c) 20 +#define REFRESH (*(volatile unsigned long *)0x48000024) 21 +#define BANKSIZE (*(volatile unsigned long *)0x48000028) 22 +#define MRSRB6 (*(volatile unsigned long *)0x4800002c) 23 + 24 +void init_clock(void) 25 +{ 26 + //Mpll = 400M 27 + MPLLCON = (0x5c<<12) | (1<<4) | 1; 28 + //FCLK 400M HCLK 100M PCLK 50M 29 + CLKDIVN = 2<<1 | 1<<0; 30 + __asm__( 31 + "mrc p15,0,r0,c1,c0,0\\n" 32 + "orr r0,r0,#0xc0000000\\n" 33 + "mcr p15,0,r0,c1,c0,0\\n" 34 + ); 35 +} 36 + 37 +void init_sdram(void) 38 +{ 39 + BWSCON = 1<<25; 40 + BANKCON6 = 1<<16 | 1<<15 | 1; 41 + REFRESH = (1<<23) + 1268; 42 + BANKSIZE = 1<<7 | 1<<4 | 1; 43 + MRSRB6 = 0x30; 44 +} 45 + 46 +void clear_bss(void) 47 +{ 48 + extern int __bss_start, __bss_end; 49 + int *p = &__bss_start; 50 + 51 + for (; p < &__bss_end; p++) 52 + { 53 + *p = 0; 54 + } 55 +} 56 + 57 +static void nand_latency(void) 58 +{ 59 + int i=100; 60 + while(i--); 61 +} 62 + 63 +static void nand_is_ready(void) 64 +{ 65 + //bit 0 : 1 不忙了 66 + while(! (NFSTAT & 1)); 67 +} 68 + 69 +static void nand_write_addr(unsigned int addr) 70 +{ 71 + int col, page; 72 + col = addr % 2048; 73 + page = addr / 2048; 74 + 75 + NFADDR = col & 0xff; /* Column Address A0~A7 */ 76 + nand_latency(); 77 + NFADDR = (col >> 8) & 0x0f; /* Column Address A8~A11 */ 78 + nand_latency(); 79 + NFADDR = page & 0xff; /* Row Address A12~A19 */ 80 + nand_latency(); 81 + NFADDR = (page >> 8) & 0xff; /* Row Address A20~A27 */ 82 + nand_latency(); 83 + NFADDR = (page >> 16) & 0x03; /* Row Address A28~A29 */ 84 + nand_latency(); 85 +} 86 + 87 +static unsigned char nand_read_char(void) 88 +{ 89 + //只保留8个bit 90 + return NFDATA & 0xff; 91 +} 92 + 93 +static void nand_cmd(unsigned char cmd) 94 +{ 95 + NFCMMD = cmd; 96 + nand_latency(); 97 +} 98 + 99 +static void nand_select_chip(void) 100 +{ 101 + //1bit : 0 选中 102 + NFCONT &= ~(1<<1); 103 +} 104 + 105 +static void nand_deselect_chip(void) 106 +{ 107 + //1bit : 1 选中 108 + NFCONT |= (1<<1); 109 +} 110 + 111 +static void nand_reset(void) 112 +{ 113 + nand_select_chip(); 114 + nand_cmd(0xff); 115 + nand_deselect_chip(); 116 +} 117 + 118 +void nand_init_ll(void) 119 +{ 120 + //TACLS 3.3v 时 12ns 121 + #define TACLS 0 122 + //12ns 123 + #define TWRPH0 1 124 + //5ns 125 + #define TWRPH1 0 126 + NFCONF = TACLS<<12 | TWRPH0<<8 | TWRPH1<<4; 127 + /* 4 ECC 128 + * 1 CE 先不选中,用的时候在选中 129 + * 0 启动 flash controller 130 + */ 131 + NFCONT = 1<<4 | 1<<1 | 1; 132 + nand_reset(); 133 +} 134 + 135 +static void nand_read(unsigned int addr, unsigned char *buf, int len) 136 +{ 137 + //选中 138 + nand_select_chip(); 139 + //j 地址可能不是从0对齐开始读的 140 + unsigned int i = addr,j = addr % 2048; 141 + for(; i<(addr + len);) 142 + { 143 + //读命令 144 + nand_cmd(0x00); 145 + nand_is_ready(); 146 + 147 + //发送地址 148 + nand_write_addr(i); 149 + nand_is_ready(); 150 + 151 + //在次发出读命令 152 + nand_cmd(0x30); 153 + nand_is_ready(); 154 + //读2K 155 + for(; j<2048; j++) 156 + { 157 + *buf = nand_read_char(); 158 + buf++; 159 + i++; 160 + } 161 + j=0; 162 + nand_latency(); 163 + } 164 + //取消选中 165 + nand_deselect_chip(); 166 +} 167 + 168 +static int boot_is_nor() 169 +{ 170 + //利用 NOR 不能写的特点判断 171 + volatile unsigned int *p = (volatile unsigned int *)0; 172 + unsigned int val; 173 + val = *p; 174 + *p = 0x12345678; 175 + if(0x12345678 == *p) 176 + { 177 + *p = val; 178 + return 0; 179 + } 180 + return 1; 181 +} 182 + 183 +//片内4K 的程序要复制到链接SDRAM中去 184 +void copy_code_to_sdram(unsigned char *src,unsigned char *dst,int len) 185 +{ 186 + int i = 0; 187 + if(boot_is_nor()) 188 + { 189 + while(i < len) 190 + { 191 + dst[i] = src[i]; 192 + i++; 193 + } 194 + } 195 + else 196 + { 197 + nand_read((int)src, dst, len); 198 + } 199 +} 200 + 201 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/Makefile u-boot-2016.03-ok/arch/arm/cpu/arm920t/Makefile 202 --- u-boot-2016.03/arch/arm/cpu/arm920t/Makefile 2016-03-14 22:20:21.000000000 +0800 203 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/Makefile 2016-05-17 06:48:31.767626866 +0800 204 @@ -8,6 +8,7 @@ 205 extra-y = start.o 206 207 obj-y += cpu.o 208 +obj-y += init.o 209 obj-$(CONFIG_USE_IRQ) += interrupts.o 210 211 obj-$(CONFIG_EP93XX) += ep93xx/ 212 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/start.S u-boot-2016.03-ok/arch/arm/cpu/arm920t/start.S 213 --- u-boot-2016.03/arch/arm/cpu/arm920t/start.S 2016-03-14 22:20:21.000000000 +0800 214 +++ u-boot-2016.03-ok/arch/arm/cpu/arm920t/start.S 2016-05-17 06:48:31.782641369 +0800 215 @@ -82,11 +82,50 @@ 216 217 /* FCLK:HCLK:PCLK = 1:2:4 */ 218 /* default FCLK is 120 MHz ! */ 219 - ldr r0, =CLKDIVN 220 - mov r1, #3 221 - str r1, [r0] 222 + //ldr r0, =CLKDIVN 223 + //mov r1, #3 224 + //str r1, [r0] 225 + 226 + /* 设置分频参数 */ 227 + ldr r0, =CLKDIVN 228 + mov r1, #0x05; /* FCLK:HCLK:PCLK=1:4:8 */ 229 + str r1, [r0] 230 + 231 + /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */ 232 + mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ 233 + orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */ 234 + mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */ 235 + 236 + /* 配置时钟 */ 237 + #define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) 238 + ldr r0, =0x4c000004 239 + ldr r1, =S3C2440_MPLL_400MHZ 240 + str r1, [r0] 241 + 242 #endif /* CONFIG_S3C24X0 */ 243 244 + /** 245 + * 调用 init.c 中的初始化 246 + * 因为已经初始化好内存 所以 sp 在 顶部 247 + * 在 NOR 时不能用片内 4K 248 + */ 249 + ldr sp, =4096 250 + bl init_sdram 251 + ldr sp, =0x34000000 252 + bl nand_init_ll 253 + /** 254 + * 从 0 地址开始复制 到 SDRAM 中 255 + * 在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE 256 + * u-boot 的加载地址 257 + */ 258 + mov r0,#0 259 + ldr r1, =CONFIG_SYS_TEXT_BASE 260 + ldr r2, =__bss_start 261 + sub r2, r2, r1 262 + bl copy_code_to_sdram 263 + bl clear_bss 264 + ldr pc, =_main 265 + 266 /* 267 * we do sys-critical inits only at reboot, 268 * not when booting from ram! 269 @@ -95,8 +134,6 @@ 270 bl cpu_init_crit 271 #endif 272 273 - bl _main 274 - 275 /*------------------------------------------------------------------------------*/ 276 277 .globl c_runtime_cpu_setup 278 diff -urN u-boot-2016.03/arch/arm/cpu/u-boot.lds u-boot-2016.03-ok/arch/arm/cpu/u-boot.lds 279 --- u-boot-2016.03/arch/arm/cpu/u-boot.lds 2016-03-14 22:20:21.000000000 +0800 280 +++ u-boot-2016.03-ok/arch/arm/cpu/u-boot.lds 2016-05-12 09:28:12.338040880 +0800 281 @@ -32,7 +32,7 @@ 282 */ 283 /DISCARD/ : { *(.rel._secure*) } 284 #endif 285 - . = 0x00000000; 286 + . = 0; 287 288 . = ALIGN(4); 289 .text : 290 diff -urN u-boot-2016.03/arch/arm/Kconfig u-boot-2016.03-ok/arch/arm/Kconfig 291 --- u-boot-2016.03/arch/arm/Kconfig 2016-03-14 22:20:21.000000000 +0800 292 +++ u-boot-2016.03-ok/arch/arm/Kconfig 2016-05-09 08:48:52.118143749 +0800 293 @@ -91,6 +91,10 @@ 294 config TARGET_SMDK2410 295 bool "Support smdk2410" 296 select CPU_ARM920T 297 + 298 +config TARGET_SMDK2440 299 + bool "Support smdk2440" 300 + select CPU_ARM920T 301 302 config TARGET_ASPENITE 303 bool "Support aspenite" 304 @@ -829,6 +833,7 @@ 305 source "board/phytec/pcm052/Kconfig" 306 source "board/ppcag/bg0900/Kconfig" 307 source "board/samsung/smdk2410/Kconfig" 308 +source "board/samsung/smdk2440/Kconfig" 309 source "board/sandisk/sansa_fuze_plus/Kconfig" 310 source "board/schulercontrol/sc_sps_1/Kconfig" 311 source "board/siemens/draco/Kconfig" 312 diff -urN u-boot-2016.03/arch/arm/lib/crt0.S u-boot-2016.03-ok/arch/arm/lib/crt0.S 313 --- u-boot-2016.03/arch/arm/lib/crt0.S 2016-03-14 22:20:21.000000000 +0800 314 +++ u-boot-2016.03-ok/arch/arm/lib/crt0.S 2016-05-16 17:11:44.287690421 +0800 315 @@ -99,7 +99,6 @@ 316 * relocate_code(addr_moni). Trick here is that we\'ll return 317 * \'here\' but relocated. 318 */ 319 - 320 ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ 321 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ 322 mov r3, sp 323 @@ -130,14 +129,17 @@ 324 325 bl c_runtime_cpu_setup /* we still call old routine here */ 326 #endif 327 + 328 + 329 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK) 330 -# ifdef CONFIG_SPL_BUILD 331 +#ifdef CONFIG_SPL_BUILD 332 /* Use a DRAM stack for the rest of SPL, if requested */ 333 bl spl_relocate_stack_gd 334 cmp r0, #0 335 movne sp, r0 336 movne r9, r0 337 -# endif 338 +#endif 339 + 340 ldr r0, =__bss_start /* this is auto-relocated! */ 341 342 #ifdef CONFIG_USE_ARCH_MEMSET 343 @@ -177,3 +179,4 @@ 344 #endif 345 346 ENDPROC(_main) 347 + 348 diff -urN u-boot-2016.03/arch/arm/lib/relocate.S u-boot-2016.03-ok/arch/arm/lib/relocate.S 349 --- u-boot-2016.03/arch/arm/lib/relocate.S 2016-03-14 22:20:21.000000000 +0800 350 +++ u-boot-2016.03-ok/arch/arm/lib/relocate.S 2016-05-16 17:11:48.481661370 +0800 351 @@ -26,6 +26,7 @@ 352 353 ENTRY(relocate_vectors) 354 355 + 356 #ifdef CONFIG_CPU_V7M 357 /* 358 * On ARMv7-M we only have to write the new vector address 359 diff -urN u-boot-2016.03/board/samsung/smdk2440/Kconfig u-boot-2016.03-ok/board/samsung/smdk2440/Kconfig 360 --- u-boot-2016.03/board/samsung/smdk2440/Kconfig以上是关于STM32+NAND FLASH做U盘,程序运行后格式化失败,而且查看容量为0,是啥原因的主要内容,如果未能解决你的问题,请参考以下文章
STM32CubeMX学习笔记(48)——USB接口使用(MSC基于外部Flash模拟U盘)
STM32CubeMX学习笔记(47)——USB接口使用(MSC基于内部Flash模拟U盘)
STM32CubeMX学习笔记(48)——USB接口使用(MSC基于外部Flash模拟U盘)