Reputation: 2299
I am using Yocto and meta-atmel to build an embedded Linux(4.4.19). On my board is an Flash which is connected through SPI. I tried several ways to write on it. But they all failed. How to read/write data into it?
Some info:
Flashtype 4Mbit:
s25fl164k (http://www.farnell.com/datasheets/1756778.pdf)
Included through Device Tree:
spi1: spi@f8008000 {
cs-gpios = <&pioC 25 GPIO_ACTIVE_HIGH>;
status = "okay";
m25p80@0 {
compatible = "spansion,s25fl164k";
spi-max-frequency = <50000000>;
reg = <0>;
};
};
Kernel config:
dmesg
print at startup:
[ 2.630000] Creating 8 MTD partitions on "atmel_nand":
[ 2.640000] 0x000000000000-0x000000040000 : "bootstrap"
[ 2.640000] 0x000000040000-0x0000000c0000 : "uboot"
[ 2.650000] 0x0000000c0000-0x000000100000 : "env"
[ 2.660000] 0x000000100000-0x000000140000 : "env_redundant"
[ 2.660000] 0x000000140000-0x000000180000 : "spare"
[ 2.670000] 0x000000180000-0x000000200000 : "dtb"
[ 2.670000] 0x000000200000-0x000000800000 : "kernel"
[ 2.680000] 0x000000800000-0x000010000000 : "rootfs"
[ 2.690000] atmel_spi f0004000.spi: version: 0x213
[ 2.690000] atmel_spi f0004000.spi: DMA TX channel not available, SPI unable to use DMA
[ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller using PIO only
[ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller at 0xf0004000 (irq 25)
[ 2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes)
fdisk
print (look at mtdblock8
):
root@sama5d3xek:~# fdisk -l
Disk /dev/ram0: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk /dev/ram1: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk /dev/ram2: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk /dev/ram3: 8 MiB, 8388608 bytes, 16384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk /dev/mtdblock0: 256 KiB, 262144 bytes, 512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock1: 512 KiB, 524288 bytes, 1024 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock2: 256 KiB, 262144 bytes, 512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock3: 256 KiB, 262144 bytes, 512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock4: 256 KiB, 262144 bytes, 512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock5: 512 KiB, 524288 bytes, 1024 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock6: 6 MiB, 6291456 bytes, 12288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock7: 248 MiB, 260046848 bytes, 507904 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mtdblock8: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mmcblk0: 7.4 GiB, 7985954816 bytes, 15597568 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 8192 15597567 15589376 7.4G b W95 FAT32
Reading/writing test:
cat /dev/mtdblock8
echo "hello" > /dev/mtdblock8
cat /dev/mtdblock8
I don't get any results/errors.
Mounting:
mkdir /tmp/abc
mount -t jffs2 /dev/mtdblock8 /tmp/abc
mount: /dev/mtdblock8: can't read superblock
Any ideas?
I like to do a demo. Let's say write "hello Linux" on position 12345 at the SPI flash.
Upvotes: 3
Views: 26584
Reputation: 802
There is a lot of info missing to be sure what is happening in your system.
You say you want to write to your SPI FLASH device
[ 2.630000] Creating 8 MTD partitions on "atmel_nand":
[ 2.640000] 0x000000000000-0x000000040000 : "bootstrap"
[ 2.640000] 0x000000040000-0x0000000c0000 : "uboot"
[ 2.650000] 0x0000000c0000-0x000000100000 : "env"
[ 2.660000] 0x000000100000-0x000000140000 : "env_redundant"
[ 2.660000] 0x000000140000-0x000000180000 : "spare"
[ 2.670000] 0x000000180000-0x000000200000 : "dtb"
[ 2.670000] 0x000000200000-0x000000800000 : "kernel"
[ 2.680000] 0x000000800000-0x000010000000 : "rootfs"
cat /dev/mtdblock8
echo "hello" > /dev/mtdblock8
cat /dev/mtdblock8
But those 8 MTD partitions looks like belong to NAND FLASH
and m25c80
is device driver for SPI NOR FLASH device.
In order to bind device to spi-nor kernel driver you need a "jedec,spi-nor"
in your compatible
device tree property.
Also /dev/mtdblock8
is a block device, useful for storing a filesystem. You cannot write just a couple of bytes. You can read and write in multiple og blocks, which are e.g. 512 bytes.
If you want to write a string or array of bytes you should better use character device /dev/mtd8
representation instead:
The second interface is a /dev/mtdblockX block device, handled by the mtdblock driver. This device is mostly used to mount MTD filesystems, such as JFFS2 and YAFFS2, because the mount command primarily works with block devices. You may be tempted to use this device to write to the MTD device, but the corresponding driver isn’t elaborate enough for use in production. When you attempt to write to a given block, the previous contents are copied to RAM, the MTD block is erased, and the updated contents are written to the block. As you can see, there is no wear leveling of any sort, as a series of writes to the same part of the block device could very quickly damage the corresponding erase blocks.
mount -t jffs2 /dev/mtdblock8 /tmp/abc
Also if your partition was not formatted, you have to blank your filesystem before mounting it, because a blank JFFS2 filesystem consists entirely of free blocks.
flash_eraseall -j /dev/mtd8
Upvotes: 1
Reputation: 2299
There was an error in my device tree table file. The spi1, the image sensor interface(isi1) and the i2c(i2c1) where using the same pins. When compiling the kernel + dts there are no error shown. In general the combination of fdisk + mtd_debug was very useful to check the driver and the hardware at low level. In my case SAMA5D35 + own mainboard @ dts:
ahb {
apb {
spi1: spi@f8008000 {
cs-gpios = <&pioC 25 GPIO_ACTIVE_LOW>;
status = "okay";
m25p80@0 {
compatible = "spansion,s25fl132k", "jedec,spi-nor";
spi-max-frequency = <108000000>;
reg = <0>;
m25p,fast-read;
};
};
// conflicts with spi1
i2c1: i2c@f0018000 {
status = "disabled";
};
// confilcts with spi1 (pin PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10)
isi: isi@f0034000 {
status = "disabled";
};
};
now it works fine
Upvotes: 2
Reputation: 2534
Perhaps the device is locked by U-Boot, and ioctl UNLOCK is not implemented in your kernel's m25p80 driver. I've seen that before, refer to erasing-flash-nor-ioctlmemunlock-return-status.
Upvotes: 3
Reputation: 93
You can use mtd_debug command tool. With this tool is possible to test read/write one byte. This is very convenient to localize problem.
Upvotes: 1
Reputation: 93
You can try lower clock frequency, this solve my problems with SPI FLASH:
spi-max-frequency = <10000000>
Upvotes: 0
Reputation: 1057
So, let's go step by step. Your SPI NOR flash is described in the devicetree, and it seems you've managed to configure your kernel correctly (that is, add the relevant drivers). This is confirmed by your log:
[ 2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes)
It would also seem true that /dev/mtd8 is the MTD device associated with that device (from your size analysis). You should be able to confirm it by inspecting /sys/class/mtd.
Now, in order to program the device you need to 1) erase the sectors you want to write, 2) write those sectors, and finally read back and confirm.
To write, you can use a write() syscall (i.e. cat somefile > /dev/mtd8
). To erase you need an ioctl syscall, i.e. flash_erase
command.
The MTD website has some relevant information:
http://www.linux-mtd.infradead.org/index.html
The Free-Electrons post mentioned in hashdefine reply is fine too.
Upvotes: 2
Reputation: 344
You can use Memory technology Devices (MTD) subsystem for erase/write/read operation on flash partitions. The SPI flash is mounted to mtdblock8 in your case.Use the below command to see all the existing partitions
cat /proc/mtd
To write to the mtd device, use nandwrite command. It is available with busybox.
For mounting try
mount -t jffs2 /dev/block/mtdblock8 /tmp/abc
Details on MTD: http://free-electrons.com/blog/managing-flash-storage-with-linux/
Details on mtd utils: http://processors.wiki.ti.com/index.php/Mtdutils
Upvotes: 1