/** * @brief fatfs_setlabel Set the volume label * @param fc the current FAT session * @param label the name of the filesystem * @return 0 on success */ int fatfs_setlabel(struct block_cache *output, off_t block_offset, const char *label) { close_open_files(); MAYBE_MOUNT(output, block_offset); CHECK("fat_setlabel", label, f_setlabel(label)); return 0; }
void SDCard_Init(void) { u32 total,free; u8 res=0; W25QXX_Init(); //初始化W25Q128 my_mem_init(SRAMIN); //初始化内部内存池 my_mem_init(SRAMCCM); //初始化CCM内存池 while(SD_Init())//检测不到SD卡 { LCD_ShowString(30,150,200,16,16,"SD Card Error!"); delay_ms(500); LCD_ShowString(30,150,200,16,16,"Please Check! "); delay_ms(500); LED0=!LED0;//DS0闪烁 } exfuns_init(); //为fatfs相关变量申请内存 f_mount(fs[0],"0:",1); //挂载SD卡 res=f_mount(fs[1],"1:",1); //挂载FLASH. if(res==0X0D)//FLASH磁盘,FAT文件系统错误,重新格式化FLASH { LCD_ShowString(30,150,200,16,16,"Flash Disk Formatting..."); //格式化FLASH res=f_mkfs("1:",1,4096);//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇 if(res==0) { f_setlabel((const TCHAR *)"1:ALIENTEK"); //设置Flash磁盘的名字为:ALIENTEK LCD_ShowString(30,150,200,16,16,"Flash Disk Format Finish"); //格式化完成 }else LCD_ShowString(30,150,200,16,16,"Flash Disk Format Error "); //格式化失败 delay_ms(1000); } LCD_Fill(30,150,240,150+16,WHITE); //清除显示 while(exf_getfree("0",&total,&free)) //得到SD卡的总容量和剩余容量 { LCD_ShowString(30,150,200,16,16,"SD Card Fatfs Error!"); delay_ms(200); LCD_Fill(30,150,240,150+16,WHITE); //清除显示 delay_ms(200); LED0=!LED0;//DS0闪烁 } POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(30,150,200,16,16,"FATFS OK!"); LCD_ShowString(30,170,200,16,16,"SD Total Size: MB"); LCD_ShowString(30,190,200,16,16,"SD Free Size: MB"); LCD_ShowNum(30+8*14,170,total>>10,5,16); //显示SD卡总容量 MB LCD_ShowNum(30+8*14,190,free>>10,5,16); //显示SD卡剩余容量 MB }
FRESULT DFATFS::fssetlabel(const char* label) { return(f_setlabel(label)); }
FRESULT FatFs::setlabel(const char* label) { return f_setlabel(label); }
int main(int oargc, char* oargv[]) { int ret; int argc = oargc - 1; char** argv = oargv + 1; // first parameter must be the image file. if (argc == 0) { fprintf(stderr, "Error: First parameter must be a filename.\n"); PRINT_HELP_AND_QUIT(); } if (is_command(argv[0])) { fprintf(stderr, "Error: First parameter must be a filename, found '%s' instead.\n", argv[0]); PRINT_HELP_AND_QUIT(); } if (disk_openimage(0, argv[0])) { fprintf(stderr, "Error: Could not open image file '%s'.\n", argv[0]); ret = 1; goto exit; } argc--; argv++; while (argc > 0) { char* parg = *argv; int nargs = 0; int i = 0; if (!is_command(parg)) { fprintf(stderr, "Error: Expected a command, found '%s' instead.\n", parg); PRINT_HELP_AND_QUIT(); } parg++; argv++; argc--; // find next command, to calculare number of args while ((argv[i] != NULL) && !is_command(argv[i++])) nargs++; if (strcmp(parg, "format") == 0) { // NOTE: The fs driver detects which FAT format fits best based on size int sectors; NEED_PARAMS(1, 2); // Arg 1: number of sectors sectors = atoi(argv[0]); if (sectors <= 0) { fprintf(stderr, "Error: Sectors must be > 0\n"); ret = 1; goto exit; } if (disk_ioctl(0, SET_SECTOR_COUNT, §ors)) { fprintf(stderr, "Error: Failed to set sector count to %d.\n", sectors); ret = 1; goto exit; } NEED_MOUNT(); ret = f_mkfs("0:", 1, sectors < 4096 ? 1 : 8); if (ret) { fprintf(stderr, "Error: Formatting drive: %d.\n", ret); goto exit; } // Arg 2: custom header label (optional) if (nargs > 1) { #define FAT_VOL_LABEL_LEN 11 char vol_label[2 + FAT_VOL_LABEL_LEN + 1]; // Null-terminated buffer char* label = vol_label + 2; // The first two characters are reserved for the drive number "0:" char ch; int i, invalid = 0; int len = strlen(argv[1]); if (len <= FAT_VOL_LABEL_LEN) { // Verify each character (should be printable ASCII) // and copy it in uppercase. for (i = 0; i < len; i++) { ch = toupper(argv[1][i]); if ((ch < 0x20) || !isprint(ch)) { invalid = 1; break; } label[i] = ch; } if (!invalid) { // Pad the label with spaces while (len < FAT_VOL_LABEL_LEN) { label[len++] = ' '; } } } else { invalid = 1; } if (invalid) { fprintf(stderr, "Error: Header label is limited to 11 printable uppercase ASCII symbols."); ret = 1; goto exit; } if (disk_read(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to read existing boot sector from image."); ret = 1; goto exit; } if (g_Filesystem.fs_type == FS_FAT32) { memcpy(buff + 71, label, FAT_VOL_LABEL_LEN); } else { memcpy(buff + 43, label, FAT_VOL_LABEL_LEN); } if (disk_write(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to write new boot sector to image."); ret = 1; goto exit; } // Set also the directory volume label memcpy(vol_label, "0:", 2); vol_label[2 + FAT_VOL_LABEL_LEN] = '\0'; if (f_setlabel(vol_label)) { fprintf(stderr, "Error: Unable to set the volume label."); ret = 1; goto exit; } } } else if (strcmp(parg, "boot") == 0) { FILE* fe; BYTE* temp = buff + 1024; NEED_PARAMS(1, 1); // Arg 1: boot file fe = fopen(argv[0], "rb"); if (!fe) { fprintf(stderr, "Error: Unable to open external file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (!fread(buff, 512, 1, fe)) { fprintf(stderr, "Error: Unable to read boot sector from file '%s'.", argv[0]); fclose(fe); ret = 1; goto exit; } fclose(fe); NEED_MOUNT(); if (disk_read(0, temp, 0, 1)) { fprintf(stderr, "Error: Unable to read existing boot sector from image."); ret = 1; goto exit; } if (g_Filesystem.fs_type == FS_FAT32) { printf("TODO: Writing boot sectors for FAT32 images not yet supported."); ret = 1; goto exit; } else { #define FAT16_HEADER_START 3 #define FAT16_HEADER_END 62 memcpy(buff + FAT16_HEADER_START, temp + FAT16_HEADER_START, FAT16_HEADER_END - FAT16_HEADER_START); } if (disk_write(0, buff, 0, 1)) { fprintf(stderr, "Error: Unable to write new boot sector to image."); ret = 1; goto exit; } } else if (strcmp(parg, "add") == 0) { FILE* fe; FIL fv = { 0 }; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: external file to add // Arg 2: virtual filename fe = fopen(argv[0], "rb"); if (!fe) { fprintf(stderr, "Error: Unable to open external file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (f_open(&fv, argv[1], FA_WRITE | FA_CREATE_ALWAYS)) { fprintf(stderr, "Error: Unable to open file '%s' for writing.", argv[1]); fclose(fe); ret = 1; goto exit; } while ((rdlen = fread(buff, 1, sizeof(buff), fe)) > 0) { if (f_write(&fv, buff, rdlen, &wrlen) || wrlen < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to disk.", wrlen); ret = 1; goto exit; } } fclose(fe); f_close(&fv); } else if (strcmp(parg, "extract") == 0) { FIL fe = { 0 }; FILE* fv; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: virtual file to extract // Arg 2: external filename if (f_open(&fe, argv[0], FA_READ)) { fprintf(stderr, "Error: Unable to open file '%s' for reading.", argv[0]); ret = 1; goto exit; } fv = fopen(argv[1], "wb"); if (!fv) { fprintf(stderr, "Error: Unable to open external file '%s' for writing.", argv[1]); f_close(&fe); ret = 1; goto exit; } while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0)) { if (fwrite(buff, 1, rdlen, fv) < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to file.", rdlen); ret = 1; goto exit; } } f_close(&fe); fclose(fv); } else if (strcmp(parg, "move") == 0) { NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: src path & filename // Arg 2: new path & filename if (f_rename(argv[0], argv[1])) { fprintf(stderr, "Error: Unable to move/rename '%s' to '%s'", argv[0], argv[1]); ret = 1; goto exit; } } else if (strcmp(parg, "copy") == 0) { FIL fe = { 0 }; FIL fv = { 0 }; UINT rdlen = 0; UINT wrlen = 0; NEED_PARAMS(2, 2); NEED_MOUNT(); // Arg 1: src path & filename // Arg 2: new path & filename if (f_open(&fe, argv[0], FA_READ)) { fprintf(stderr, "Error: Unable to open file '%s' for reading.", argv[0]); ret = 1; goto exit; } if (f_open(&fv, argv[1], FA_WRITE | FA_CREATE_ALWAYS)) { fprintf(stderr, "Error: Unable to open file '%s' for writing.", argv[1]); f_close(&fe); ret = 1; goto exit; } while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0)) { if (f_write(&fv, buff, rdlen, &wrlen) || wrlen < rdlen) { fprintf(stderr, "Error: Unable to write '%d' bytes to disk.", wrlen); ret = 1; goto exit; } } f_close(&fe); f_close(&fv); } else if (strcmp(parg, "mkdir") == 0) { NEED_PARAMS(1, 1); NEED_MOUNT(); // Arg 1: folder path if (f_mkdir(argv[0])) { fprintf(stderr, "Error: Unable to create directory."); ret = 1; goto exit; } } else if (strcmp(parg, "delete") == 0) { NEED_PARAMS(1, 1); NEED_MOUNT(); // Arg 1: file/folder path (cannot delete non-empty folders) if (f_unlink(argv[0])) { fprintf(stderr, "Error: Unable to delete file or directory."); ret = 1; goto exit; } } else if (strcmp(parg, "list") == 0) { char* root = "/"; DIR dir = { 0 }; FILINFO info = { 0 }; char lfname[257]; NEED_PARAMS(0, 1); // Arg 1: folder path (optional) if (nargs == 1) { root = argv[0]; } if (f_opendir(&dir, root)) { fprintf(stderr, "Error: Unable to opening directory '%s' for listing.\n", root); ret = 1; goto exit; } printf("Listing directory contents of: %s\n", root); info.lfname = lfname; info.lfsize = sizeof(lfname)-1; while ((!f_readdir(&dir, &info)) && (strlen(info.fname) > 0)) { if (strlen(info.lfname) > 0) printf(" - %s (%s)\n", info.lfname, info.fname); else printf(" - %s\n", info.fname); } } else { fprintf(stderr, "Error: Unknown or invalid command: %s\n", argv[-1]); PRINT_HELP_AND_QUIT(); } argv += nargs; argc -= nargs; } ret = 0; exit: disk_cleanup(0); return ret; }
int main(void) { // TODO disable JTAG // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024); /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // set the system clock to be HSE SystemClock_Config(); // enable GPIO clocks __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOD_CLK_ENABLE(); // enable the CCM RAM __CCMDATARAMEN_CLK_ENABLE(); #if 0 #if defined(NETDUINO_PLUS_2) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; #if MICROPY_HW_HAS_SDCARD // Turn on the power enable for the sdcard (PB1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET); #endif // Turn on the power for the 5V on the expansion header (PB2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); } #endif #endif // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); #if MICROPY_HW_HAS_SWITCH switch_init0(); #endif int first_soft_reset = true; soft_reset: // check if user switch held to select the reset mode led_state(1, 0); led_state(2, 1); led_state(3, 0); led_state(4, 0); uint reset_mode = 1; #if MICROPY_HW_HAS_SWITCH if (switch_get()) { for (uint i = 0; i < 3000; i++) { if (!switch_get()) { break; } HAL_Delay(20); if (i % 30 == 29) { if (++reset_mode > 3) { reset_mode = 1; } led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); } } // flash the selected reset mode for (uint i = 0; i < 6; i++) { led_state(2, 0); led_state(3, 0); led_state(4, 0); HAL_Delay(50); led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); HAL_Delay(50); } HAL_Delay(400); } #endif #if MICROPY_HW_ENABLE_RTC if (first_soft_reset) { rtc_init(); } #endif // more sub-system init #if MICROPY_HW_HAS_SDCARD if (first_soft_reset) { sdcard_init(); } #endif if (first_soft_reset) { storage_init(); } // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib)); mp_obj_list_init(mp_sys_argv, 0); // Change #if 0 to #if 1 if you want REPL on UART_6 (or another uart) // as well as on USB VCP #if 0 { mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(PYB_UART_6), MP_OBJ_NEW_SMALL_INT(115200), }; pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); } #else pyb_stdio_uart = NULL; #endif // Initialise low-level sub-systems. Here we need to very basic things like // zeroing out memory and resetting any of the sub-systems. Following this // we can run Python scripts (eg boot.py), but anything that is configurable // by boot.py must be set after boot.py is run. readline_init0(); pin_init0(); extint_init0(); timer_init0(); uart_init0(); #if MICROPY_HW_ENABLE_RNG rng_init0(); #endif i2c_init0(); spi_init0(); pyb_usb_init0(); // Initialise the local flash filesystem. // Create it if needed, and mount in on /flash. { // try to mount the flash FRESULT res = f_mount(&fatfs0, "/flash", 1); if (reset_mode == 3 || res == FR_NO_FILESYSTEM) { // no filesystem, or asked to reset it, so create a fresh one // LED on to indicate creation of LFS led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); res = f_mkfs("/flash", 0, 0); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("could not create LFS"); } // set label f_setlabel("/flash/pybflash"); // create empty main.py FIL fp; f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // create .inf driver file f_open(&fp, "/flash/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS); f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n); f_close(&fp); // create readme file f_open(&fp, "/flash/README.txt", FA_WRITE | FA_CREATE_ALWAYS); f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n); f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } else if (res == FR_OK) { // mount sucessful } else { __fatal_error("could not access LFS"); } } // The current directory is used as the boot up directory. // It is set to the internal flash filesystem by default. f_chdrive("/flash"); // Make sure we have a /flash/boot.py. Create it if needed. { FILINFO fno; #if _USE_LFN fno.lfname = NULL; fno.lfsize = 0; #endif FRESULT res = f_stat("/flash/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file // LED on to indicate creation of boot.py led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); FIL fp; f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } } #if defined(USE_DEVICE_MODE) usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH; #endif #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on /sd/ if (sdcard_is_present()) { FRESULT res = f_mount(&fatfs1, "/sd", 1); if (res != FR_OK) { printf("[SD] could not mount SD card\n"); } else { // use SD card as current directory f_chdrive("/sd"); // TODO these should go before the /flash entries in the path mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); if (first_soft_reset) { // use SD card as medium for the USB MSD #if defined(USE_DEVICE_MODE) usb_medium = USB_STORAGE_MEDIUM_SDCARD; #endif } } } #endif // reset config variables; they should be set by boot.py pyb_config_main = MP_OBJ_NULL; pyb_config_usb_mode = MP_OBJ_NULL; // run boot.py, if it exists // TODO perhaps have pyb.reboot([bootpy]) function to soft-reboot and execute custom boot.py if (reset_mode == 1) { const char *boot_py = "boot.py"; FRESULT res = f_stat(boot_py, NULL); if (res == FR_OK) { int ret = pyexec_file(boot_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { flash_error(4); } } } // turn boot-up LEDs off led_state(2, 0); led_state(3, 0); led_state(4, 0); // Now we initialise sub-systems that need configuration from boot.py, // or whose initialisation can be safely deferred until after running // boot.py. #if defined(USE_HOST_MODE) // USB host pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device usb_device_mode_t usb_mode = USB_DEVICE_MODE_CDC_MSC; // if we are not in reset_mode==1, this config variable will always be NULL if (pyb_config_usb_mode != MP_OBJ_NULL) { if (strcmp(mp_obj_str_get_str(pyb_config_usb_mode), "CDC+HID") == 0) { usb_mode = USB_DEVICE_MODE_CDC_HID; } } pyb_usb_dev_init(usb_mode, usb_medium); #endif #if MICROPY_HW_HAS_MMA7660 // MMA accel: init and reset accel_init(); #endif #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif #if MICROPY_HW_ENABLE_DAC // DAC dac_init(); #endif mod_network_init(); // At this point everything is fully configured and initialised. // Run the main script from the current directory. if (reset_mode == 1 && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { const char *main_py; if (pyb_config_main == MP_OBJ_NULL) { main_py = "main.py"; } else { main_py = mp_obj_str_get_str(pyb_config_main); } FRESULT res = f_stat(main_py, NULL); if (res == FR_OK) { int ret = pyexec_file(main_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { flash_error(3); } } } // Main script is finished, so now go into REPL mode. // The REPL mode can change, or it can request a soft reset. for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } } soft_reset_exit: // soft reset printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); timer_deinit(); uart_deinit(); first_soft_reset = false; goto soft_reset; }