用mini2440烧写spiflash『上』

来源:互联网 发布:linux分辨率代码 编辑:程序博客网 时间:2024/05/16 07:49

       前段时间,偶然发现有些路由器是可以下第三方的固件,自己就弄了下。可我的740N的flash和ram都比较小,要升级硬件。就从TB上买了4M的25L32,从公司捞了几片32M的SDRAM。spiflash先是用同事的烧写器烧的,后来就萌发出用以前买的mini2440弄出烧写器。

mini2440上没有spiflash的例子程序真是遗憾。

        首先是spi硬件接口。

        在板子上GPIO接口上是可以引出来的。引线方法不再多说,在原理图或手册上都可以看清楚。强调一下,spiflash的wp#与hold#是要拉高的,不能悬空,没有电阻的话直接接3.3V上也可以。

        接下来是修改驱动程序。

        我是参考http://blog.csdn.net/lxmky/article/details/6858322弄得。下好重启后,会

[root@FriendlyARM fengchen]# ls -l /dev/spi*

crw-rw----    1 root     root     153,   0 Jan  1 08:00 /dev/spidev0.0

crw-rw----    1 root     root     153,   1 Jan  1 08:00 /dev/spidev1.0

[root@FriendlyARM fengchen]# 

        随后确实可以用Documentation/spi/spidev_test.c作测试。
        不过,程序中用ioctl的返回是否为1判断调用是否成功,这样是有问题的(新版本内核已修改)。其一,返回是1会让人觉得调用是有问题;其二,返回值其实是传输的个数(read/write,全双工),如果传输一个字节,就会被认为是调用不成功。
        可以看下driver/spi/spidev.c,spidev_ioctl函数调用spidev_message,在函数中添加的printk如下:
static int spidev_message(struct spidev_data *spidev,struct spi_ioc_transfer *u_xfers, unsigned n_xfers){struct spi_messagemsg;struct spi_transfer*k_xfers;struct spi_transfer*k_tmp;struct spi_ioc_transfer *u_tmp;unsignedn, total;u8*buf;intstatus = -EFAULT;spi_message_init(&msg);k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);if (k_xfers == NULL)return -ENOMEM;/* Construct spi_message, copying any tx data to bounce buffer. * We walk the array of user-provided transfers, using each one * to initialize a kernel version of the same transfer. */buf = spidev->buffer;total = 0;printk("\n[0status=%d/total=%d]\n",status,total);for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;n;n--, k_tmp++, u_tmp++) {k_tmp->len = u_tmp->len;total += k_tmp->len;printk("[1status=%d/total=%d]\n",status,total);if (total > bufsiz) {status = -EMSGSIZE;printk("[goto done 0]");goto done;}if (u_tmp->rx_buf) {k_tmp->rx_buf = buf;if (!access_ok(VERIFY_WRITE, (u8 __user *)(uintptr_t) u_tmp->rx_buf,u_tmp->len)){printk("[goto done 1]");goto done;}}if (u_tmp->tx_buf) {k_tmp->tx_buf = buf;if (copy_from_user(buf, (const u8 __user *)(uintptr_t) u_tmp->tx_buf,u_tmp->len)){printk("[goto done 2]");goto done;}}buf += k_tmp->len;k_tmp->cs_change = !!u_tmp->cs_change;k_tmp->bits_per_word = u_tmp->bits_per_word;k_tmp->delay_usecs = u_tmp->delay_usecs;k_tmp->speed_hz = u_tmp->speed_hz;#ifdef VERBOSEprintk("  xfer len %zd %s%s%s%dbits %u usec %uHz\n",u_tmp->len,u_tmp->rx_buf ? "rx " : "",u_tmp->tx_buf ? "tx " : "",u_tmp->cs_change ? "cs " : "",u_tmp->bits_per_word ? : u_tmp->bits_per_word,u_tmp->delay_usecs,u_tmp->speed_hz ? : u_tmp->speed_hz);#endifspi_message_add_tail(k_tmp, &msg);}printk("[2status=%d/total=%d]\n",status,total);status = spidev_sync(spidev, &msg);//返回传输的个数if (status < 0){printk("[goto done 3]");goto done;}printk("[3status=%d/total=%d]\n",status,total);/* copy any rx data out of bounce buffer */buf = spidev->buffer;for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {if (u_tmp->rx_buf) {if (__copy_to_user((u8 __user *)(uintptr_t) u_tmp->rx_buf, buf,u_tmp->len)) {status = -EFAULT;printk("[goto done 4]");goto done;}}buf += u_tmp->len;}printk("[4status=%d/total=%d]\n",status,total);//status = total;//上面这句是不应该有的done:printk("[5status=%d/total=%d]\n",status,total);kfree(k_xfers);return status;}

在传输时通过串口的打印可以看出问题产生在哪儿。

原创粉丝点击