Many TLAs: MTP MSC FS SD SDFat LittleFS UsbMSCFat to work with each other 8)

@mjs513 - I started hitting head with larger hammer ;)

I was playing with creating the partition in the MBR before you actually do the format.
One reason is maybe the MBR is full or ...

I just finished hacking up pass 1 of it. Still some holes and have not run it yet...

So I hacked up the start of create partition like:
Code:
bool PFsFatFormatter::createPartition(BlockDevice* dev, uint8_t fat_type, uint32_t startSector, uint32_t sectorCount, uint8_t* secBuf, print_t* pr) {
  bool rtn;
  
  m_dev = dev;
  m_secBuf = secBuf;
  m_pr = pr;
  m_sectorCount = sectorCount;
  m_capacityMB = (m_sectorCount + SECTORS_PER_MB - 1)/SECTORS_PER_MB;
  m_part_relativeSectors = startSector;
  
  newPart = 1;

  if (m_capacityMB <= 6) {
    writeMsg("Card is too small.\r\n");
    return false;
  } else if (m_capacityMB <= 16) {
    m_sectorsPerCluster = 2;
  } else if (m_capacityMB <= 32) {
    m_sectorsPerCluster = 4;
  } else if (m_capacityMB <= 64) {
    m_sectorsPerCluster = 8;
  } else if (m_capacityMB <= 128) {
    m_sectorsPerCluster = 16;
  } else if (m_capacityMB <= 1024) {
    m_sectorsPerCluster = 32;
  } else if (m_capacityMB <= 32768) {
    m_sectorsPerCluster = 64;
  } else {
    // SDXC cards
    m_sectorsPerCluster = 128;
  }

  [COLOR="#FF0000"]m_part = addPartitionToMbr(startSector, sectorCount);  
  if (m_part == 0xff) return false; // error in adding a partition to the MBR[/COLOR]


#if defined(DBG_Print)
  Serial.println(m_part);

The new function:
Code:
uint8_t PFsFatFormatter::addPartitionToMbr(uint32_t startSector, uint32_t sectorCount) {
  uint32_t endSector = startSector + sectorCount;

  MbrSector_t* mbr = reinterpret_cast<MbrSector_t*>(m_secBuf);

  if (!m_dev->readSector(0, m_secBuf)) {
    writeMsg("Didn't read MBR Sector !!!\n");
    return 0xff; // did not read the sector.
  }

  uint8_t part_index = 3; // zero index;
  MbrPart_t *pt = &mbr->part[part_index];
  uint32_t part_sector_start = getLe32(pt->relativeSectors);
  uint32_t part_total_sectors = getLe32(pt->totalSectors);

  uint16_t sig = getLe16(mbr->signature);
  if (sig != MBR_SIGNATURE) {
    // not valid we will use the whole thing
    memset(m_secBuf, 0, 512); 
    part_index = 0;
  } else {
    // lets look through to see if we have any empty slots
    if (pt->type && part_sector_start && part_total_sectors) return 0xff; // We don't have any room in the MBR
    // loop through the blank ones
    while (part_index && (pt->type==0) && (part_sector_start== 0) && (part_total_sectors == 0)) {
      part_index--;
      pt = &mbr->part[part_index];
      part_sector_start = getLe32(pt->relativeSectors);
      part_total_sectors = getLe32(pt->totalSectors);
    }
    // was empty.
    if  ((part_index==0) && (pt->type==0) && (part_sector_start== 0) && (part_total_sectors == 0)) return 0; // empty mbr...

    // Now see if we found the spot or if we need to move items down.

    while (part_index && (startSector < part_sector_start)) {
      // Should we check for overlaps?
      if (endSector > part_sector_start) {
        Serial.println("Partion overlaps existing partition");
        return 0xff;
      }
      //move that item down
      memcpy((void*)pt, (void*)&mbr->part[part_index+1], sizeof(MbrPart_t));
      part_index--;

      pt = &mbr->part[part_index];
      part_sector_start = getLe32(pt->relativeSectors);
      part_total_sectors = getLe32(pt->totalSectors);
    }
    // Now see if we are at the start or...
    if (part_index != 0) part_index++; // back up to the one before
    else if (startSector > part_sector_start) part_index++; // likewise need to backup. 
    // BUGBUG:: should probably test that we don't overlap on the other side...
    // probably don't need this, but:
    pt = &mbr->part[part_index];
    memset(pt, 0, sizeof(MbrPart_t));
  }

  m_dev->writeSector(0, m_secBuf);
  return part_index;

}
As I mentioned in BUGBUG: I detected one form of overlap of the partitions, but not the other yet. Also potentially could modify that says something like:
Start at X and use what is available. Both for holes and at end...

Does any of this make sense? Or maybe the wrong rabbit hole :D
 
@KurtE
Yes it does make sense, I didn't think to check the limits was concentrating more on getting it to add a partition, then got overloaded so took a break.

I see what you did with moving the partition down. Had no clue on how to implement that piece:
Code:
      //move that item down
      memcpy((void*)pt, (void*)&mbr->part[part_index+1], sizeof(MbrPart_t));
nice work.

BTW: Your add partition is a lot nicer than my writeNewMbr :).
 
@KurtE
Just gave your sketch a try and something strange. After formatting a 64GB thumb to have 3 active partitions and 1 unallocated partition at the end I tried to create the last partition:
Code:
msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16:	1,0,0x20,0x21,0x0,0xE,0x17,0x18,0xFF,2048,4096000
FAT32:	2,0,0x17,0x19,0xFF,0xB,0xFE,0xFF,0xFF,4098048,39780352
FAT32:	3,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,43878400,38848512
pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
	 < unused area starting at: 82726912 length 38418431 >
drive 0 Partition 0 valid:1
drive 0 Partition 1 valid:1
drive 0 Partition 2 valid:1

***** Partition List *****
0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 19998
1(0:2):>> Fat32: Volume name:() Partition Total Size:20357578752 Used:65536 time us: 770498
2(0:3):>> Fat32: Volume name:() Partition Total Size:19880706048 Used:65536 time us: 748873
done...

==========================================================================

 *** Create a NEW partition Drive 0 Starting at: 38418431 Count: 0 ***
0

Create Partition::format................
Sector Count: 82726912, Sectors/MB: 2048
Partition Capacity (MB): 40394
Fat Type: 32
    m_relativeSectors:38418431

format makeFAT32
 MAKEFAT32
m_dataStart: 16384, m_fatSize: 5049, r: 18299
m_dataStart: 24576, m_fatSize: 5048, r: 18297
    m_sectorCount: 82726912
    m_dataStart: 24576
    m_sectorsPerCluster: 128
    nc: 646112
    m_fatSize: 5048
partType: 12, m_relativeSectors: 38418431, fatStart: 38424719, fatDatastart: 38443007, totalSectors: 82726912
new Partition requested: 1
0,2048,4096000
1,4098048,39780352
2,43878400,38848512
3,0,0
setIP = 3
lastIP = 3
PFsFatFormatter::initFatDir(32, 10224)
Writing FAT ...................................
Format Done
Press any key to run again
Initialize USB drive...UsbBase::mscBegin called 20006a20 1 1
    After usbDriveBegin
Blocks: 121145343 Size: 512

msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16:	1,0,0x20,0x21,0x0,0xE,0x17,0x18,0xFF,2048,4096000
FAT32:	2,0,0x17,0x19,0xFF,0xB,0xFE,0xFF,0xFF,4098048,39780352
FAT32:	3,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,43878400,38848512
[COLOR="#FF0000"]FAT32:	4,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,38418431,82726912
[/COLOR]drive 0 Partition 0 valid:1
drive 0 Partition 1 valid:1
drive 0 Partition 2 valid:1
drive 0 Partition 3 valid:1


[COLOR="#FF0000"]***** Partition List *****
[/COLOR]0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 20123
1(0:2):>> Fat32: Volume name:() Partition Total Size:20357578752 Used:65536 time us: 770748
2(0:3):>> Fat32: Volume name:() Partition Total Size:19880706048 Used:65536 time us: 747498
[COLOR="#FF0000"]3(0:4):>> Fat32:  Partition Total Size:0 Used:0 time us: 416500
[/COLOR]
It looks like it created the partition in the MBR but when it went to print size info it is blank.

EDIT: Also when I put it into Windows only the original 3 drives (partitions) show up in explorer
 
Yep something screwy going on. Just getting ready to debug.

Was not sure of the state of my drive so used the sledgehammer command it cleared it to one big partition, and then
I could use the delete to delete it...

Now to add some more debug printing and see where I am screwing up!
 
It looks like startingSectors and SectorCount are reversed in the MBR?

EDIT: It looks like its happening in CreatePartition function in the sketch?
Code:
 *** Create a NEW partition Drive 0 Starting at: 38418431 Count: 0 ***
StartSector: 38418431,  SectorCount: 82726912 [B][COLOR="#FF0000"]----- SENT FROM SKETCH TO LIB[/COLOR][/B]
On CreatPartion: StartSector: 38418431,  SectorCount: 82726912
0

Create Partition::format................
Sector Count: 82726912, Sectors/MB: 2048
Partition Capacity (MB): 40394
Fat Type: 32
    m_relativeSectors:38418431
Confused on where it could be.

EDIT Could it be coming from commandlinenext?
 
Last edited:
Afternoon/Evening - Maybe the command was wrong and I did not catch it... That is it hit me as well:
I forgot to tell it which drive. like: N 0 4008192 4000000
Once or Twice I forgot the 0...

There is probably other stuff going on as well.
 
Shoot I forgot to tell what drive as well - nice way to tell me obvious user error

EDIT: This time ran it with the drive number and it worked no problem :) and showed up in windows explorer.

Guess almost time to add in your new stuff.
 
Fixed the main issue... will filling in.... I had the memcpy parameters reversed. (Dest, Source, count)...

I was thinking of pushing my current stuff with your new stuff up to my temporary branch. Still more work we can and probably should do
Need better validation of the data. Currently if you do a N 8192 ... and there already is an 8192, it will probably just overwrite.

But also wondering in some of these cases: Where I show you starting sector and free sector count. Wondering if in some of these cases do we want to type in Sector counts, or
do we want some of the data to output maybe MB and allow us to type in MB for partition size...

Also probably have some of this code have some better smarts. like:
If I say instead of: N 0 4008192 4000000
Like I just did, I do: N 0 408192
And it would say Oh, there is another partition above this so Size will be up to that. Or the rest of the drive...

The updated code with more debug:
Code:
uint8_t PFsFatFormatter::addPartitionToMbr(uint32_t startSector, uint32_t sectorCount) {
  uint32_t endSector = startSector + sectorCount;
  Serial.printf("PFsFatFormatter::addPartitionToMbr: %u %u (%u)\n", startSector, sectorCount, endSector);

  MbrSector_t* mbr = reinterpret_cast<MbrSector_t*>(m_secBuf);

  if (!m_dev->readSector(0, m_secBuf)) {
    writeMsg("Didn't read MBR Sector !!!\n");
    return 0xff; // did not read the sector.
  }
  dump_hexbytes(&mbr->part[0], 4*sizeof(MbrPart_t));

  uint8_t part_index = 3; // zero index;
  MbrPart_t *pt = &mbr->part[part_index];
  uint32_t part_sector_start = getLe32(pt->relativeSectors);
  uint32_t part_total_sectors = getLe32(pt->totalSectors);

  uint16_t sig = getLe16(mbr->signature);
  if (sig != MBR_SIGNATURE) {
    // not valid we will use the whole thing
    memset(m_secBuf, 0, 512); 
    part_index = 0;
  } else {
    // lets look through to see if we have any empty slots
    Serial.printf("    p %u: %u %u %u: ", part_index, pt->type, part_sector_start, part_total_sectors);
    if (pt->type && part_sector_start && part_total_sectors) return 0xff; // We don't have any room in the MBR
    // loop through the blank ones
    while (part_index && (pt->type==0) && (part_sector_start== 0) && (part_total_sectors == 0)) {
      Serial.println(" - empty slot");
      part_index--;
      pt = &mbr->part[part_index];
      part_sector_start = getLe32(pt->relativeSectors);
      part_total_sectors = getLe32(pt->totalSectors);
      Serial.printf("    p %u: %u %u %u: ", part_index, pt->type, part_sector_start, part_total_sectors);
    }
    // was empty.
    if  ((part_index==0) && (pt->type==0) && (part_sector_start== 0) && (part_total_sectors == 0)) {
      Serial.println(" - MBR empty");  
      return 0; // empty mbr...
    } 

    // Now see if we found the spot or if we need to move items down.

    while (part_index && (startSector < part_sector_start)) {
      // Should we check for overlaps?
      if (endSector > part_sector_start) {
        Serial.println(" - overlaps existing partition");
        return 0xff;
      }
      //move that item down
      memcpy((void*)&mbr->part[part_index+1], (void*)pt, sizeof(MbrPart_t));
      Serial.println("- > Move down");
      part_index--;

      pt = &mbr->part[part_index];
      part_sector_start = getLe32(pt->relativeSectors);
      part_total_sectors = getLe32(pt->totalSectors);
      Serial.printf("    p %u: %u %u %u: ", part_index, pt->type, part_sector_start, part_total_sectors);
    }
    // Now see if we are at the start or...
    Serial.println("- exited copy down");
    if (part_index != 0) part_index++; // back up to the one before
    else if (startSector > part_sector_start) part_index++; // likewise need to backup. 
    Serial.printf("    Return partion num: %u\n", part_index);
    // BUGBUG:: should probably test that we don't overlap on the other side...
    // probably don't need this, but:
    pt = &mbr->part[part_index];
    memset(pt, 0, sizeof(MbrPart_t));
  }
  Serial.println("After Add Partition");
  dump_hexbytes(&mbr->part[0], 4*sizeof(MbrPart_t));
  m_dev->writeSector(0, m_secBuf);
  return part_index;

}
 

Attachments

  • MSCFormatter.zip
    99.4 KB · Views: 41
KurtE said:
I was thinking of pushing my current stuff with your new stuff up to my temporary branch. Still more work we can and probably should do
Need better validation of the data. Currently if you do a N 8192 ... and there already is an 8192, it will probably just overwrite.
Probably be a good idea so we have a common starting point.

Bill starts with 8192 by default but when I do partitioning in windows always seems to have partition 0 starting at 2048. So not 100% sure on whether that is right but hasn't hurt anything yet.

But also wondering in some of these cases: Where I show you starting sector and free sector count. Wondering if in some of these cases do we want to type in Sector counts, or
do we want some of the data to output maybe MB and allow us to type in MB for partition size...
That was actually on my todo list but didn't want to confuse the issue. Think we need to be careful though especially with the conversion between sector counts and capacity conversion. May wind up creating a hole accidently.

Also probably have some of this code have some better smarts. like:
If I say instead of: N 0 4008192 4000000
Like I just did, I do: N 0 408192
And it would say Oh, there is another partition above this so Size will be up to that. Or the rest of the drive...
That would make it easier.

Glad you got it sorted with writing a partition between partitions. How many dents do you have? Anyway will wait for you to post the updated code before I start playing. I was going to try and add in format drive and then work on exFAT.
 
@mjs513 - Just pushed up the WIP (same stuff in zip file).

Once we have all of the stuff in PFsForm and and the Ex... will probably then remove my initialize USB drive... or maybe integrate it into the main library functions.

Also need to clean out some unused code.

Right now I am hacking on my Initialize Drive code, to remove the need for it to be USB... Try using the Sectorcount... And then try it out on SD cards as well.
 
Pushed up minor update to Sketch:
I believe the code worked to Initialize the SD cards as well.

I renumbered the Devices as 10 is SDIO and 11 is my SPI (on pin 10).

Now play some more with maybe auto figuring out sizes and the like.

EDIT forgot to mention that probably should give better guess for the 8192... I think it mainly had to do with SD card manufacturers, where maybe they used different memory or the like for the start of the card to use for special things... Not sure how applicable it is to thumb drives or the like.
 
@mjs513 @KurtE - OK, my brain is fried at this point with ext4:confused:...
It is going to be along hard road to converting lwext4 to use MSC or any other configuration we might come up with. As always mixing C and C++ is going to be a challenge. Putting a wrapper on it or converting it to C++ is going to take time. Really not sure which way to go. I suppose the best way would be to convert it C++. I think the biggest problem is that I still am not that good with C++ yet:) Still learning as I go.

Anyway, I have made some progress with it. It compiles and I can open a ext4 block device. Still have to finish the low level IO access to read and write sectors and such. NOT EVEN going near locking or unlocking the device yet:) Disabled at this point.

Going to finish up tonight playing with what you guy's have done...
 
Pushed up minor update to Sketch:
I believe the code worked to Initialize the SD cards as well.

I renumbered the Devices as 10 is SDIO and 11 is my SPI (on pin 10).

Now play some more with maybe auto figuring out sizes and the like.

EDIT forgot to mention that probably should give better guess for the 8192... I think it mainly had to do with SD card manufacturers, where maybe they used different memory or the like for the start of the card to use for special things... Not sure how applicable it is to thumb drives or the like.

Will give it a try in the morning and play with some more. Time for sleep where I am.
 
@wwatson
Is this the library you are trying to port: https://github.com/gkostka/lwext4, or is it another one. Just wanted to be you saw this one.

Yes I know the feeling about brain being fried :)

Yep that's the one. Also from gkosta is this link that I am using as a guide to convert lwext4 for use with Teensy:
https://github.com/gkostka/stm32f429disco-lwext4

And:
https://github.com/ngkaho1234/fuse-lwext4

I guess maybe tomorrow I will start a GitHub entry with what I have so far as COMPLETELY WIP:)

Just trying to help or add to what @Paul and you guy's are accomplishing I guess.

Time to eat and go to bed.,,,,
 
@mjs513 - Have a good night.

I am just about to push up some additional changes:

I now have it computing some of the sizes for you... One more hack to go:
in: bool PFsFatFormatter::createPartition(BlockDevice* dev, uint8_t fat_type, uint32_t startSector, uint32_t sectorCount, uint8_t* secBuf, print_t* pr) {

There is:

Code:
   if(fat_type == 16 && [COLOR="#FF0000"]fat_type < 0X400000[/COLOR] ) {
	writeMsg("format makeFAT16\r\n");  
	rtn = makeFat16();
  } else if(fat_type == 32) {
	writeMsg("format makeFAT32\r\n");  
	rtn = makeFat32();
  }	else {
	rtn = false;
The part in red is probably typo.
But I was also going to add if fattype == 0
Then we will compute by the comments:
"Cards up to 2 GiB (GiB = 2^30 bytes) will be formated FAT16.\n"
"Cards larger than 2 GiB and up to 32 GiB will be formatted\n"
 
@mjs513 @wwatson - I cleaned up some of the code, still more to go.

The code now does things like, see if you specify a size or not. If not, and it finds a gap it fills in the size
If it is at the end it uses the size of the dev->sectorCount() to setup the size.
It also checks the spot you are trying to add it and see if your size will extend into another partition.

Probably a few things still not caught.

Enough hitting head with hammer for today :D
 
@mjs513 @wwatson - I cleaned up some of the code, still more to go.

The code now does things like, see if you specify a size or not. If not, and it finds a gap it fills in the size
If it is at the end it uses the size of the dev->sectorCount() to setup the size.
It also checks the spot you are trying to add it and see if your size will extend into another partition.

Probably a few things still not caught.

Enough hitting head with hammer for today :D

You bet, I guess maybe a soft blow hammer would be better:)
 
@mjs513 - Have a good night.

I am just about to push up some additional changes:

I now have it computing some of the sizes for you... One more hack to go:
in: bool PFsFatFormatter::createPartition(BlockDevice* dev, uint8_t fat_type, uint32_t startSector, uint32_t sectorCount, uint8_t* secBuf, print_t* pr) {

There is:

Code:
   if(fat_type == 16 && [COLOR="#FF0000"]fat_type < 0X400000[/COLOR] ) {
	writeMsg("format makeFAT16\r\n");  
	rtn = makeFat16();
  } else if(fat_type == 32) {
	writeMsg("format makeFAT32\r\n");  
	rtn = makeFat32();
  }	else {
	rtn = false;
Good Morning @KurtE

The part in red is probably typo.
But I was also going to add if fattype == 0
Then we will compute by the comments:
"Cards up to 2 GiB (GiB = 2^30 bytes) will be formated FAT16.\n"
"Cards larger than 2 GiB and up to 32 GiB will be formatted\n"

Think it was suppose to be fat_size but that is overtaken by events at this point. Will download again :)
 
@KurtE

Just downloaded the latest and gave it a test drive. Works great.

I started with this (64GB)
Code:
msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16:	1,0,0x20,0x21,0x0,0xE,0x17,0x18,0xFF,2048,4096000
FAT32:	2,0,0x17,0x19,0xFF,0xB,0xFE,0xFF,0xFF,4098048,39780352
FAT32:	3,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,43878400,38848512
FAT32:	4,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,82726912,38418431

***** Partition List *****
0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 15998
1(0:2):>> Fat32: Volume name:() Partition Total Size:20357578752 Used:65536 time us: 616373
2(0:3):>> Fat32: Volume name:() Partition Total Size:19880706048 Used:65536 time us: 601998
3(0:4):>> Fat32:  Partition Total Size:19661815808 Used:186482688 time us: 297875
deleted partition 0:2:
Code:
msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16:	1,0,0x20,0x21,0x0,0xE,0x17,0x18,0xFF,2048,4096000
	 < unused area starting at: 4098048 length 39780352 >
FAT32:	2,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,43878400,38848512
FAT32:	3,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,82726912,38418431
pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
then added it back.
Code:
msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16:	1,0,0x20,0x21,0x0,0xE,0x17,0x18,0xFF,2048,4096000
FAT32:	2,0,0x17,0x19,0xFF,0xC,0xFE,0xFF,0xFF,4098048,39780352
FAT32:	3,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,43878400,38848512
FAT32:	4,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,82726912,38418431

***** Partition List *****
0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 15873
1(0:2):>> Fat32:  Partition Total Size:20359151616 Used:289112064 time us: 308375
2(0:3):>> Fat32: Volume name:() Partition Total Size:19880706048 Used:65536 time us: 601998
3(0:4):>> Fat32:  Partition Total Size:19661815808 Used:186482688 time us: 297750
then gave part 0:2 and 0:4 a volume name:
Code:
***** Partition List *****
0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 15998
1(0:2):>> Fat32: Volume name:(v1FAT32) Partition Total Size:20359151616 Used:289112064 time us: 308373
2(0:3):>> Fat32: Volume name:(newFAT32) Partition Total Size:19880706048 Used:65536 time us: 601998
3(0:4):>> Fat32: Volume name:(v4FAT32) Partition Total Size:19661815808 Used:186482688 time us: 297748
done..

Ok now for coffee and get back to work.
 
Morning @mjs513 and ...

Right now doing a little more cleanup: I removed a few pinMode() in the main, plus put the debug messages in the formatter in #if...
Sometime it might be nice to go through some of these files like this and maybe replace blocks like:
Code:
      #if defined(DBG_Print)
      Serial.printf("    Adjust sector count: %u = %u - %u CAP: %u\n", m_sectorCount, last_start_sector, m_part_relativeSectors, m_capacityMB);
      #endif
With something like:
Code:
      DBGPrintf("    Adjust sector count: %u = %u - %u CAP: %u\n", m_sectorCount, last_start_sector, m_part_relativeSectors, m_capacityMB);
Like we have in the USBHost (example bluetooth.cpp)
Then at top we could have:
Code:
#if defined(DBG_Print)
#define DBGPrintf Serial.printf
#else
void inline DBGPrintf(...) {};
#endif
Could do the same for print and println or simply convert those to printf...

Now that the createPartition is working (so far Fat... Next we should do ExFat)

I am going to hack up my Sledgehammer function, to probably just:
Zero out the MBR and then call the createPartition() to do the rest...
 
Code:
I am going to hack up my Sledgehammer function, to probably just:
Zero out the MBR and then call the createPartition() to do the rest...
Probably for the best - was just incorporating your sledgehammer approach into the FatLib. Also was trying to clean up some extraneous left over code in FatFormatter. Can do the DBGPrintf at the same time. Will let you modify your sledge hammer and finish cleaning up FatFormater - then on to exFAT

First attempt below:
Code:
***** Partition List *****
0(0:1):>> Fat16: Volume name:(FAT16) Partition Total Size:2096857088 Used:98304 time us: 15998
1(0:2):>> Fat32: Volume name:(v1FAT32) Partition Total Size:20359151616 Used:289112064 time us: 308373
2(0:3):>> Fat32: Volume name:(newFAT32) Partition Total Size:19880706048 Used:65536 time us: 601998
3(0:4):>> Fat32: Volume name:(newFAT32) Partition Total Size:19661815808 Used:186482688 time us: 297748
done...
Enter command:

 **** Try Sledgehammer on USB Drive 0 ****
Warning it appears like this drive has valid partitions, continue: Y? 
sectorCount = 121145343, FatType: 20
0

PFsFatFormatter::format................
Sector Count: 121145343, Sectors/MB: 2048
Fat Type: 32
    m_dataStart:24576
    m_sectorsPerCluster:128
    m_relativeSectors:8192

0

PFsFatFormatter::format................
Sector Count: 121137024, Sectors/MB: 2048
Partition Capacity (MB): 59149
Fat Type: 0
    m_dataStart:0
    m_sectorsPerCluster:0
    m_relativeSectors:8192

format makeFAT32
 MAKEFAT32
m_dataStart: 16384, m_fatSize: 7393, r: 22987
m_dataStart: 24576, m_fatSize: 7393, r: 22987
    m_sectorCount: 121137024
    m_dataStart: 24576
    m_sectorsPerCluster: 128
    nc: 946191
    m_fatSize: 7393
partType: 12, m_relativeSectors: 8192, fatStart: 9790, fatDatastart: 32768, totalSectors: 121137024
PFsFatFormatter::initFatDir(32, 14914)
Writing FAT .................................
free clusters after format: 0
free clusters after begin on partVol: 932852
Format Done
Press any key to run again
Initialize USB drive...UsbBase::mscBegin called 20006b80 1 1
    After usbDriveBegin
Blocks: 121145343 Size: 512

msc # Partition Table
	part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT32:	1,0,0x82,0x3,0x0,0xC,0xFE,0xFF,0xFF,8192,121137024
pt_#0:	2,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0:	3,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
	 < unused area starting at: 121145216 length 127 >
drive 0 Partition 0 valid:1

Initialize SDIO SD card...initialization failed.


Initialize SPI SD card...initialization failed.


***** Partition List *****
0(0:1):>>[COLOR="#FF0000"] Fat32:  Partition Total Size:0 Used:0 time us: 469375[/COLOR]
Almost worked so probably missed something but Windows still liked it.
 
Morning again:

I am not sure about chicken and the egg on cleanup. If you are already in the process of cleaning up PFsFatFormatter, I could wait until you are done and maybe do a couple of simple changes after I merge your changes in.

As my edits will probably collide with yours :D I will update the sledge hammer function. Actually I have it now... But have not tested yet:
Code:
//----------------------------------------------------------------
// Function to handle one MS Drive...
void InitializeBlockDevice(uint8_t drive_index, uint8_t fat_type)
{
  BlockDeviceInterface *dev = nullptr;
  PFsVolume partVol;

  for (int ii = 0; ii < count_partVols; ii++) {
    if (partVols_drive_index[ii] == drive_index) {
      while (Serial.read() != -1) ;
      Serial.println("Warning it appears like this drive has valid Fat partitions, continue: Y? ");
      int ch;
      while ((ch = Serial.read()) == -1) ;
      if (ch != 'Y') {
        Serial.println("Canceled");
        return;
      }
      break;
    }
  }

  if (drive_index == LOGICAL_DRIVE_SDIO) {
    dev = sd.card();
  } else if (drive_index == LOGICAL_DRIVE_SDSPI) {
    dev = sdSPI.card();
  } else {
    if (!msDrives[drive_index]) {
      Serial.println("Not a valid USB drive");
      return;
    }
    dev = (USBMSCDevice*)msc[drive_index].usbDrive();
  }

  // First lets verify that we can actually talk to the device by reading in the MBR
  if (!dev->readSector(0, sectorBuffer)) {
    Serial.println("Error: Could not read from device");
    return;
  }

  uint32_t sectorCount = dev->sectorCount();
  
  // Serial.printf("Blocks: %u Size: %u\n", msDrives[drive_index].msCapacity.Blocks, msDrives[drive_index].msCapacity.BlockSize);
  if ((fat_type == FAT_TYPE_EXFAT) && (sectorCount < 0X100000 )) fat_type = 0; // hack to handle later
  if ((fat_type == FAT_TYPE_FAT16) && (sectorCount >= SECTORS_2GB )) fat_type = 0; // hack to handle later
  if ((fat_type == FAT_TYPE_FAT32) && (sectorCount >= SECTORS_127GB )) fat_type = 0; // hack to handle later
  if (fat_type == 0)  {
    // assume 512 byte blocks here.. 
    if (sectorCount < SECTORS_2GB) fat_type = FAT_TYPE_FAT16;
    else if (sectorCount < SECTORS_32GB) fat_type = FAT_TYPE_FAT32;
    else fat_type = FAT_TYPE_EXFAT;
  }


  // lets generate a MBR for this type...
  memset(sectorBuffer, 0, 512); // lets clear out the area.
  MbrSector_t* mbr = reinterpret_cast<MbrSector_t*>(sectorBuffer);
  setLe16(mbr->signature, MBR_SIGNATURE);

  // Temporary until exfat is setup...
  if (fat_type == FAT_TYPE_EXFAT) {
    Serial.println("TODO createPartition on ExFat");
    return;
  } else {
    // Fat16/32
    dev->writeSector(0, sectorBuffer);
    FatFormatter.createPartition(dev, 0, 0, 0, sectorBuffer, &Serial);
  
  }
What I wanted to check in the Fat createPartition code probably in the addPartitionToMbr function or maybe back in the create partition. That if
m_part_relativeSectors == 0 we set it to the default offset for our guess of which FAT.

Not sure best place, as if we do it after the call finishes for addPartition and I guessed on size of partition based off of 0, than need to decrement count by what we set this to...

I could not tell if you were saying that you would then go to the ExFat or if you wanted me to take a first cut at it?

Kurt
 
What I was talking about was finishing off FAT formatting functions to intialize the drive then copy and paste code (and mod accordingly) over to the exFATformatter to create partitions, add partitions etc. Make it easier I think - I will take care of exFAT once we get FAT finished.

Was also thing about adding to the lib delete partition. Instead of doing it from a sketch.

Was also thinking about creating a new wrapper that would call off to either exFAT or FAT. Think it would be easier to manage the calls what do you think? Maybe keep Initialize drive in that wrapper class to handle both.

EDIT: can you think of anything else?
 
Back
Top