os(uos) usage for mount

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
codyhanks
Posts: 12
Joined: Thu Nov 30, 2017 7:30 pm

os(uos) usage for mount

Post by codyhanks » Fri Jun 15, 2018 1:05 am

I am having trouble with using uos for mounting a spi device.

Code: Select all

class flash():
	def __init__(self,port,cs):
        	self._port = port
        	self._cs= cs
        	self._cs.high()
        	self._block_cnt=31
        	self._block_size=4096
        	self._baseoffsett=0x0
        	self.command(clsr, 0)
        	self.command(wren, 0)
        	
	def readblocks(self,block_num,buf):
        	cmd=bytearray(1)
        	cmd[0] = fourread
        	cmd.extend(self.block_to_bytes(self._baseoffsett+block_num *self._block_size))
        	#print('read cmd {}'.format(list(cmd)))
        	self._cs.low()
        	time.sleep_us(1)
       		self._port.send(cmd)
        	self._port.readinto(buf)
        	self._cs.high()
        
        def writeblocks(self,block_num,buf):
        	pagesize = 256
        	cmd=bytearray(5)
        	cmd[0]=fourp4e
        	cmdwrite=bytearray(5)
        	cmdwrite[0] = fourpp
        	#for each block erase block and write again 
        	nblocks, err = divmod(len(buf), self._block_size)
        	mv = memoryview(buf)
        	offset=0
        	curblock=0
        	while(curblock < nblocks):
           		#erase this block
            		cmd[1:4]=self.block_to_bytes(self._baseoffsett+(block_num*self._block_size)+(curblock*self._block_size))[0:3]
            		self.command(wren, 0)
            		self.command(cmd, 0)
            		#print('cmd_clear {}'.format(list(cmd)))
            		#wait for write complete 
            		self.command(rdsr1, 1)
            		while ((self._buffer[0]&0x01) ==0x01):
                		#print('clear in progress')
               			self.command(rdsr1, 1) 
           	#write this block 
            	for x in range(self._block_size/pagesize):
                	#print('x {} start point {}'.format(x,curblock*self._block_size+(x*pagesize)))
               		cmdwrite[1:4]=self.block_to_bytes(self._baseoffsett+(block_num*self._block_size)+(curblock*self._block_size)+(x*pagesize))[0:3]
                	#print('cmdwrite = {}'.format(list(cmdwrite)))
                	self.command(wren, 0)
                	time.sleep_us(1)
                	self._cs.low()
                	time.sleep_us(1)
                	self._port.send(cmdwrite)
                	startpoint=(curblock*self._block_size)+(x*pagesize)
                	tempbuff = buf[startpoint:startpoint+pagesize]
                	print(tempbuff)
                	self._port.send(buf[startpoint:startpoint+pagesize])
                	self._cs.high()
               	 	time.sleep_us(1)
                	self.command(rdsr1, 1)
                	while ((self._buffer[0]&0x01) ==0x01):
                   		print('Write in progress')
                    		self.command(rdsr1, 1)
                	#print('Done')
            	curblock+=1
            	
        def ioctl(self,op,arg):
        	if op==4:
            		return self._block_size
       		if op==5:
           		return self._block_cnt
        
    	    def count(self):
       		return self._block_cnt
  
This is the response I am getting

>>> uos.VfsFat.mkfs(_mtr.flash_ic)
>>> vfs=uos.VfsFat(_mtr.flash_ic)
>>> uos.mount(vfs,'/test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 19] ENODEV


I have verified the block read and write are working I am sure i am missing something small and simple But cannot seem to see it.

User avatar
pythoncoder
Posts: 2661
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: os(uos) usage for mount

Post by pythoncoder » Fri Jun 15, 2018 6:13 am

It's hard to debug code without access to the hardware: the ENODEV error may suggest a hardware issue. I can't see anything obviously wrong but you might like to look at my ferroelectric RAM driver which is a pretty minimal example of a mountable device driver.

Your post prompted me to update the test program framtest_pb.py to use VFS mounting. You'll see it uses similar code to yours except that mine assumes an already existing filesystem. It works correctly.
Peter Hinch

Damien
Site Admin
Posts: 560
Joined: Mon Dec 09, 2013 5:02 pm

Re: os(uos) usage for mount

Post by Damien » Fri Jun 15, 2018 1:48 pm

If you define the ioctl method (which is good, you should do this), then don't define the count method because count will override ioctl.

codyhanks
Posts: 12
Joined: Thu Nov 30, 2017 7:30 pm

Re: os(uos) usage for mount

Post by codyhanks » Fri Jun 15, 2018 10:55 pm

Thanks for the help after digging into this for a while the mkfs doesn't seem to be actually making any changes to the sectors on the drive.
I am wondering if it has to do with the line.

line 5144 in oofatfs/ff.c

Code: Select all

 if (sz_vol < 50) return FR_MKFS_ABORTED;   /* Check if volume size is >=50s */


but not sure where, the issue might be that its not actually creating the fatfs on the drive.

Damien
Site Admin
Posts: 560
Joined: Mon Dec 09, 2013 5:02 pm

Re: os(uos) usage for mount

Post by Damien » Sat Jun 16, 2018 1:15 am

The FAT filesystem does need a lot of blocks to create a blank filesystem, that's why there is this minimum limit of 50 blocks. You can't really get around this, simply due to the FAT format. This number (50) was already decreased from a much larger number in the original FAT driver.

Another limitation is that on pyboard (stm32 port) currently you must have a 512 byte block size. It looks like you are using 4096 as your block size. The block size corresponds to the amount of RAM the FATFS driver needs for caching purposes, so it's currently limited to 512 on pyboard to reduce RAM usage. esp8266 uses 4096 to be compatible with the page erase size on the esp8266.

It would be possible to allow bigger block sizes on pyboard but that requires some improvements to the code base to make it work efficiently.

FAT is not really the best filesystem for embedded devices because of the above limitations. We are currently looking to add littlfs support https://github.com/micropython/micropython/pull/3847 to get around these limitations: littlfs only needs a few blocks at minimum for the filesystem meta data, and the erase-page size can be large without affecting RAM usage.

codyhanks
Posts: 12
Joined: Thu Nov 30, 2017 7:30 pm

Re: os(uos) usage for mount

Post by codyhanks » Sat Jun 16, 2018 10:13 am

Thanks that helps with another question I was having as to whether the uos uses the CCRAM on STM or not.

Post Reply