我参考开发板中“非操作系统源码”,改了下nand flash操作文件,在linux下编译并下载到开发板运行,但是无法运行。
出现“Segmentation fault”错误,不知道是什么原因?
非操作系统源码能否直接用到linux操作系统编程中?
我要保存数据到nand中,所以要重新写nand读写函数。是不是必须以驱动的形式才能读写?
望高手指点!
nanfflash.c文件如下:
#include <string.h>
#include <stdio.h>
//#include "def.h"
//#include "2440addr.h"
//#include "2440lib.h"
//#include "2440slib.h"
//#include "Nand.h"
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xC)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
//#define GPDAT __REGi(GPIO_CTL_BASE+oGPIO_F+oGPIO_DAT)
#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))
#define NAND_CHIP_DISABLE (NFCONT |= (1<<1))
#define NAND_CLEAR_RB (NFSTAT |= (1<<2))
#define NAND_DETECT_RB { while(! (NFSTAT&(1<<2)) );}
#define TACLS 1//7 // 1-clk(0ns)
#define TWRPH0 4//7 // 3-clk(25ns)
#define TWRPH1 0//7 // 1-clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
#define NFBusy() (!(NFSTAT&1)) // NAND flash memory busy
#define NFReady() (NFSTAT&1) // NAND flash memory ready to operate
#define WrNFCmd(cmd) (NFCMD = (cmd)) // write NAND flash memory commmand
#define WrNFAddr(addr) (NFADDR = (addr)) // write NAND flash address
#define RdNFDat() (NFDATA) // read NAND flash register
#define WrNFDat(dat) (NFDATA = (dat)) // write NAND flash register
// NAND flash 设备命令
#define NAND_CMD_READ0 0x00
#define NAND_CMD_READ1 0x01
#define NAND_CMD_PAGEPROG2 0x10
#define NAND_CMD_READ2 0x50
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_PAGEPROG1 0x80
#define NAND_CMD_READID 0x90
#define NAND_CMD_READID1 0x91
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
#define BUSY 4
unsigned char bufcmd[513];
//extern int Uart_Printf();
void wait_idle(void) {
while(!(NFSTAT & BUSY));
NFSTAT |= BUSY;
}
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
/* low level nand read function */
/* start_addr :page addr
size: page counter*/
int nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /* invalid alignment */
}
NAND_CHIP_ENABLE;
for(i=start_addr; i < (start_addr + size);)
{
/* READ0 */
NAND_CLEAR_RB;
NFCMD = 0;
/* Write Address */
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
NAND_DETECT_RB;
for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
{
*buf = (NFDATA & 0xff);
buf++;
}
}
NAND_CHIP_DISABLE;
return 0;
}
int nand_write(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /* invalid alignment */
}
NAND_CHIP_ENABLE;
for(i=start_addr; i < (start_addr + size);)
{
/* READ0 */
NAND_CLEAR_RB;
NFCMD = 0x80;
/* Write Address */
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
NAND_DETECT_RB;
for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
{
NFDATA=*(buf+j);
buf++;
}
}
NFCMD = 0x10; /*write end*/
NAND_CHIP_DISABLE;
return 0;
}
unsigned short nand_checkId(void)
{
int i;
unsigned short id;
NAND_CHIP_ENABLE; //chip enable
NFCMD=0x90; //Read ID
NFADDR=0x0;
for(i=0;i<10;i++); //wait tWB(100ns)
id=NFDATA<<8; // Maker code(K9S1208V:0xec)
id|=NFDATA; // Devide code(K9S1208V:0x76)
NAND_CHIP_DISABLE; //chip denable
return id;
}
static void nand_reset(void)
{
int i;
NAND_CHIP_ENABLE; //chip enable
NFCMD=0xFF; //reset command
for(i=0;i<10;i++); //tWB = 100ns.
NAND_DETECT_RB; //wait 200~500us;
NAND_CHIP_DISABLE; //chip disable
}
void nand_init(void)
{
unsigned short id;
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
// TACLS [14:12] CLE&ALE duration = HCLK*TACLS.
// TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1)
// TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1)
// AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048
// PageSize(R) [2] NAND memory page size
// when [3]==0, 0:256, 1:512 bytes/page.
// when [3]==1, 0:1024, 1:2048 bytes/page.
// AddrCycle(R) [1] NAND flash addr size
// when [3]==0, 0:3-addr, 1:4-addr.
// when [3]==1, 0:4-addr, 1:5-addr.
// BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit.
NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
// Lock-tight [13] 0:Disable lock, 1:Enable lock.
// Soft Lock [12] 0:Disable lock, 1:Enable lock.
// EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable
// EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable
// RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low
// SpareECCLock [6] 0:Unlock, 1:Lock
// MainECCLock [5] 0:Unlock, 1:Lock
// InitECC(W) [4] 1:Init ECC decoder/encoder.
// Reg_nCE [1] 0:nFCE=0, 1:nFCE=1.
// NANDC Enable [0] operating mode. 0:Disable, 1:Enable.
// NFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
// 1 1 1 1 1 xxx r xxx, r xxx
// En r r ECCR nFCE=H tACLS tWRPH0 tWRPH1
id = nand_checkId();
printf("Chip ID = %x\n", id);
if(id==0xec76)
printf("SAMSUNG K9F1208\n");
else
printf("Chip ID error\n");
nand_reset();
}
int WaitNFBusy(void)
{
int status;
NFCMD=NAND_CMD_STATUS;
status = RdNFDat();
while((status&0x40)==0)status = RdNFDat();
return status&0x01;
}
int BlockErase(int block)
{
int status;
NAND_CHIP_ENABLE;
NFCMD=NAND_CMD_ERASE1;
NFADDR=(block>>9)&0xff;
NFADDR=(block>>17)&0xff;
NFADDR=(block>>25)&0xff;
NFCMD=NAND_CMD_ERASE2;
while(NFBusy());
status = WaitNFBusy();
switch(status)
{
case 0 : printf("Erase block %d succeed ", block); break;
case 1 : printf("Erase block %d failing ", block); break;
}
NFCMD=NAND_CMD_STATUS;
printf("%02x\n",RdNFDat());
NAND_CHIP_DISABLE;
return status;
}
void main()
{
unsigned int i;
//unsigned char bufcmd[513];
nand_init();
for(i=0;i<=512;i++)
bufcmd=i;
printf("bufcmd init!\n");
for(i=0;i<=512;i++)
printf("%d\n",bufcmd);
BlockErase(0x200000);
if(nand_write(bufcmd, 0x3f50000, 512)==0)
{
printf("write sucess!\n");
}
else
{
printf("write error!\n");
}
for(i=0;i<1000;i++) ;
for(i=0;i<=512;i++)
bufcmd=0;
if(nand_read(bufcmd, 0x3f50000, 512)==0)
{
printf("read sucess!\n");
}
else
{
printf("read error!\n");
}
printf("from nandflash!\n");
for(i=0;i<=512;i++)
printf("%d\n",bufcmd);
}