nand flash坏块多怎么解决?是我的应用程序有问题吗?高手请指点:Q:26451602

以下是main程序和主要类定义程序,有很多类头文件,在此不能一一列出, 望有空余时间的朋友和我一起探讨.Q:26451602.现在的问题是:flash读写次数很少,就成坏块了.而且用mkyaffs工具也格式化不了.你有什么办法吗?我们系统是:一片单片机负责8路A/D转换,以及和ARM主板通讯.ARM:S3C2410,DM9000网卡,K9F1208flash,linux-2.6.14.1系统,busybox1.1.3,u-boot-1.1.6.

/**************************************************************** Copyright(c) 2009-2010,Newkoom Net Tech.Co,.Ltd 模块名称(Filename): beep_s3c2410.c 项目名称(Projectname): RPM(Remote Power Manager System) 版本号(Version): 1.0.0 创建日期(Date): 2009-11-22 作者(Author): ZMF(Zheng meifu) 功能描述(Description): buzzer(beep) driver for linux2.6.14.1 其他说明(Others): 修改记录(History): 调试成功:2009-11-23 ****************************************************************/ /* 读取键值,控制LED灯亮。0x80-0x85:灭1-6号灯。0x00-0x05:点亮1-6号灯。 键值:1-6. 修改记录: 2009-10-26: 依据阿潘要求,改为刚按下/按住/释放都要给应用层信号。 修改标志:ZMF091026 */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> #include <signal.h> #include <pthread.h> #include "timer.h" #include "sysconfig.h" #include "powercontrolboard.h" #include "led.h" #include "beep.h" #include "serial.h" #include "datatype.h" /* keyflag: bit4:y/n longkey; bit0:y/n quickkey; bit1:quickkey valid; bit5: key valid; */ /* keyflag: bit8-bit11: pressed key num:1-15 */ #define QUICKKEYbit 0 #define QUICKKEYVALbit 1 #define LONGKEYbit 4 #define KEYVALIDbit 5 #define KBDFILE "/dev/keybutton" #ifdef DBG_ALLON #define MAIN_DBG 1 #else //#define MAIN_DBG 1 #endif #ifdef MAIN_DBG #define PRINTF(arg...) printf(arg) #else #define PRINTF(arg...) do{}while(0) #endif volatile key_reg_t keyregdat; pthread_t g_LedCheckThreadId; int key_fd=-1; RCV_SND_REC_T * rcv_snd_rec; FILE * rcv_fp; #define RCV_SND_REC_FILE "/data/rcv_snd_srl_rec" int open_rec(RCV_SND_REC_T **rec, FILE **fp){ int size; if((*fp=fopen(RCV_SND_REC_FILE, "w+b")) ==NULL){ perror("open_rec:fopen(RCV_SND_REC_FILE) error"); system("free"); *fp=NULL; return -1; } size=sizeof(RCV_SND_REC_T); if((*rec=(RCV_SND_REC_T *)malloc(size)) == (RCV_SND_REC_T *)NULL){ perror("open_rec:malloc(RCV_SND_REC_T) error"); fclose(*fp); return -1; } memset(*rec,0, size); if(fread(*rec, size,1,*fp) != 1){ perror("open_rec:read rec_fp error"); write_rec(*rec, fp); } return 1; } int close_rec(RCV_SND_REC_T * rec, FILE ** fp){ if(*fp){ write_rec(rec,fp); fclose(*fp); } if(rec) free(rec); return 1; } int write_rec(RCV_SND_REC_T * rec, FILE ** fp){ int ret; if((ret=fwrite(rec,sizeof(RCV_SND_REC_T),1, *fp)) < 1){ perror("write_rec:write error!"); } return ret; } int write_rec_ram(RCV_SND_REC_T * rec, Uchar *buf, int len, FILE **fp){ void * tmpp; len= len>MAX_RECEIVE_LINE ? MAX_RECEIVE_LINE : len; PRINTF("rec->receive_rec[%d][0]=%p; buf=%p; len=%d",rec->curr_row_rcv, &rec->receive_rec[rec->curr_row_rcv][0],buf,len); tmpp=(void *)memcpy(&rec->receive_rec[rec->curr_row_rcv][0], buf, len); PRINTF("/tmemcpy ret:%p/n",tmpp); rec->curr_row_rcv=INCBUF(rec->curr_row_rcv, MAX_RECEIVE_ROW); if(rec->curr_row_rcv==(MAX_RECEIVE_ROW-1)){ fseek(*fp, 0, SEEK_SET); write_rec(rec, fp); } return 1; } void clr_keyregdat(int set_interval_time){ memset((char *)&keyregdat, 0, sizeof(key_reg_t)); keyregdat.interval_time=set_interval_time; } void keyscan_fun(int keyfd){ volatile int ret, key_val_r[8],xi,key_val,keyreadnum,keyflag=keyregdat.key_flag; g_PowerControlBoard.set_buzzer(PRESET_FREQ, SET_KEY_PRESS_BEEP); keyreadnum=read(key_fd, (char *)&key_val_r,8*sizeof(int)); if (keyreadnum<=0 ||keyreadnum>4){ /* 非阻塞读键盘返回0*/ perror("keyscan_fun:read(key_fd)"); return; } for (xi=0; xi <keyreadnum; xi++){ keyflag=keyregdat.key_flag; key_val=key_val_r[xi]; PRINTF("receive:%d button%x/n",keyreadnum,key_val); if(key_val < 0x1000 ){ /* 初始值处理 */ if (xi ==0){ if(key_val==keyregdat.keybuf[0]){ SETBIT(keyflag, QUICKKEYVALbit); }else{ CLRBIT(keyflag, QUICKKEYVALbit); keyregdat.press_holdtime=0; keyregdat.keybuf[1]=keyregdat.keybuf[2]=0; keyregdat.keybuf[0]=key_val; } }else{ keyregdat.press_holdtime+=key_val; } }else if (key_val >= 0x2000){ /* 保持值处理 */ if(keyregdat.keybuf[0]==key_val-0x2000){ keyregdat.keybuf[1]=key_val; keyregdat.press_holdtime++; keyregdat.interval_time=KEYCLR_TIMES; }else goto ERRRT; }else{ /* 释放值处理 */ if(keyregdat.keybuf[0]==key_val-0x1000){ /*释放值和初始值一样 */ /* 先判断是否是长按键 */ if (keyregdat.press_holdtime>=21){ CLRALLBIT(keyflag); SETBIT(keyflag, LONGKEYbit); keyflag &=0xf0ff; keyflag |= ((keyregdat.keybuf[0]&0x000f)<<8); clr_keyregdat(KEYCLR_TIMES); goto RIGHTRT; }else { /* 不是长按键 */ keyregdat.press_holdtime=0; if (keyregdat.keybuf[2]==0){ /* 若是第一次按下,则不判断是否是双击键 */ keyregdat.keybuf[2]=key_val; gettimeofday((struct timeval *)&(keyregdat.tv1), NULL); keyregdat.interval_time=KEYCLR_TIMES>>1; goto RIGHTRT; } } /*以下判断是否是双击键 */ if(keyregdat.keybuf[2]==key_val){ /* 第二次按下释放值一样 */ gettimeofday((struct timeval *)&(keyregdat.tv2), NULL); ret=1000000*(keyregdat.tv2.tv_sec-keyregdat.tv1.tv_sec)+ keyregdat.tv2.tv_usec-keyregdat.tv1.tv_usec; if(ret<1000000 && ret>0 && ISSETBIT(keyflag, QUICKKEYVALbit)){ CLRALLBIT(keyflag); SETBIT(keyflag, QUICKKEYbit); keyflag &=0xf0ff; keyflag |= ((keyregdat.keybuf[0]&0x000f)<<8); clr_keyregdat(KEYCLR_TIMES); }else { CLRALLBIT(keyflag); clr_keyregdat(KEYCLR_TIMES); } }else goto ERRRT;/* 初始键值相同,不同释放值*/ } else goto ERRRT; /* 释放值和初始值不一样,则错误 */ } RIGHTRT: keyregdat.key_flag=keyflag; continue; ERRRT: CLRALLBIT(keyflag); clr_keyregdat(KEYCLR_TIMES); keyregdat.key_flag=keyflag; } } void * kbd_led_fun(void * pa){ int ret; key_fd=open(KBDFILE,O_RDONLY|O_NONBLOCK, S_IRWXU|S_IRWXG|S_IROTH); if(key_fd<0){ perror("cann't open device /dev/keybutton"); exit(1); } g_PowerControlBoard.open_led(); g_PowerControlBoard.write_led(g_ConfigData.m_ConfigData.sw_state, 4); keyregdat.interval_time=KEYCLR_TIMES; // 防止启动后会清键标志发提示音。 if(init_sigaction_set(SIGIO,keyscan_fun)==SIG_ERR) perror("init_sigaction_set:SIGIO keyscan_fun"); fcntl(key_fd,F_SETOWN,getpid()); int oflag=fcntl(key_fd,F_GETFL); fcntl(key_fd, F_SETFL, oflag|FASYNC); for (;;) { if(keyregdat.key_flag & 0x01){ ret=(keyregdat.key_flag&0x0f00)>>8; g_PowerControlBoard.set_buzzer(PRESET_FREQ, SET_RIGHT_ACTION_BEEP); PRINTF("You pressed quick button:%d/n",ret); if(ret>=1 && ret<=6 ){ ret--; g_ConfigData.m_ConfigData.sw_state[ret] ^=(1<<7); g_PowerControlBoard.write_led(&g_ConfigData.m_ConfigData.sw_state[ret], 1); g_PowerControlBoard.SendControlSwitch((unsigned char)(ret&0x0f), g_ConfigData.m_ConfigData.sw_state[ret]&0x80 ); g_PowerControlBoard.m_srl_state =0x0410|(ret<<12); } keyregdat.key_flag=0; }else if(keyregdat.key_flag & 0x10){ ret=(keyregdat.key_flag&0x0f00)>>8; g_PowerControlBoard.set_buzzer(PRESET_FREQ, SET_KEY_PRESS_BEEP); PRINTF("You pressed long button:%d/n",ret); keyregdat.key_flag=0; } } g_PowerControlBoard.close_led(); close(key_fd); return 0; } int main(int argc, char** argv){ while(g_ConfigData.LoadConfigData(true)==2); /*装载配置数据*/ open_rec(&rcv_snd_rec, &rcv_fp); PRINTF("rcv_snd_rec=%p, rcv_fp=%p/n",rcv_snd_rec, rcv_fp); g_PowerControlBoard.InitComPort(COM1, B9600); PRINTF("initcomport!/n"); g_PowerControlBoard.Pause(); /*电源控制板串口通讯线程开始*/ g_PowerControlBoard.open_buzzer(); pthread_create((pthread_t *)&g_LedCheckThreadId, NULL, kbd_led_fun, NULL); PRINTF("created kbd_led_fun pthread!/n"); g_Ctimedata.init_timer(); PRINTF("created timer pthread!/n"); while (true){ ; } g_PowerControlBoard.close_buzzer(); close_rec(rcv_snd_rec,&rcv_fp); exit(0); }

 

/**************************************************************** Copyright(c) 2009-2010,Newkoom Net Tech.Co,.Ltd 模块名称(Filename): powercontrolboard.cpp 项目名称(Projectname): RPM(Remote Power Manager System) 版本号(Version): 1.0.0 创建日期(Date): 2009-11-22 作者(Author): ZMF(Zheng meifu) 功能描述(Description): powercontrolboard class define 其他说明(Others): 修改记录(History): 调试成功:2009-11-23 ****************************************************************/ #include<stdio.h> #include"powercontrolboard.h" #include "sysconfig.h" CPowerControlBoard g_PowerControlBoard; #ifdef DBG_ALLON #define POWERCONTROLBOARD_DBG 1 #else #define POWERCONTROLBOARD_DBG 1 #endif #ifdef POWERCONTROLBOARD_DBG #define PRINTF(arg...) printf(arg) #else #define PRINTF(arg...) do{}while(0) #endif void CPowerControlBoard::ProcessOKPack(unsigned char *buff,unsigned char len){ int i; PRINTF("OKPack:cmd=0x%02x ", buff[1]); switch(buff[1]){ case 0x21:/* 1.打开/关闭电源开关(0x21) */ for(i=0;i<len; i++) PRINTF("%x ",buff[i]); PRINTF("/n"); SETBIT(g_PowerControlBoard.m_srl_state, SRL_HAVEACKBIT); break; case 0x22:/*2. 读取电源开关(0x22)*/ break; case 0x23:/*3. 读取各路电流值(0x23)*/ break; case 0x24:/*4. 读取当前环境温度变量(0x24)*/ break; case 0x61:/*5. 定时上传开关状态,各路电流值和环境温度(0x61)*/ for(i=0;i<len; i++) PRINTF("%x ",buff[i]); PRINTF(" totalpack=%d/n",(int)m_TotalPacket); Update61CMD(buff+3); write_rec_ram(rcv_snd_rec, buff, len, &rcv_fp); break; default: PRINTF("/terror!/n"); break; } } void CPowerControlBoard::ProcessBadPack(unsigned char *buff,unsigned char len){ int i; PRINTF("BadPack:"); for(i=0;i<len; i++) PRINTF("0x%x ",buff[i]); PRINTF("/n"); } void CPowerControlBoard::CaleCheckSum(unsigned char* buff){ unsigned char checksum = buff[1] ^ buff[2]; unsigned char length = buff[2]; for (int i = 0; i < buff[2]; i++) { checksum ^= buff[3 + i]; } buff[length + 3] = checksum; } void CPowerControlBoard::addbytes(/*const */ unsigned char *b,int size){ while(size--){ if(addbyte(*b++)) { if (m_Buffer[0] == 0x7E) ProcessOKPack(m_Buffer, m_Count); else ProcessBadPack(m_Buffer, m_Count); } } } int CPowerControlBoard::addbyte(unsigned char b){ unsigned char c=1; static int paralength = 0; static unsigned char sumcheck = 0; while(c) { c=0; switch(m_Step){ case 0: //0x7E if (b == 0x7E ){ Newpack(); add(b); m_Step++; sumcheck = 0; } break; case 1: //0x21,0x22,0x23,0x24,0x61 if ((b == 0x21) || (b == 0x22) || (b == 0x23) || (b == 0x24) || (b == 0x61)) { add(b); m_Step++; sumcheck ^= b; }else{ m_Step=0; c=1; } break; case 2: add(b); paralength = b; sumcheck ^= b; m_Step++; break; case 3: if (paralength > 0) { add(b); sumcheck ^= b; }else{ m_Step++; c = 1; } paralength -= 1; break; case 4: //checksum add(b); if (b == sumcheck){ m_Step++; }else{ PRINTF("check error:"); for (c=0; c<m_Count; c++) PRINTF("%x ",m_Buffer[c]); PRINTF("sumcheck=%x/n",sumcheck); c = 1; m_Step = 0; } break; case 5: //end if (b == 0xE7){ add(b); m_TotalPacket++; return 1; }else{ c = 1; m_PacketErrorCount++; m_Step = 0; return 0; } break; default: m_PacketErrorCount++; m_Step=0; break; } } return 0; } void CPowerControlBoard::PrintSerialPortStat(char *buff){ sprintf(buff,",%lu,%lu",m_PacketErrorCount,m_TotalPacket); } CPowerControlBoard::CPowerControlBoard(){ m_PacketErrorCount=0; m_TotalPacket=0; m_srl_state=0; memset(m_cmd, 0, sizeof(m_cmd)); m_cmd[0] = 0x1E; } CPowerControlBoard::~CPowerControlBoard(){ } void CPowerControlBoard::Start(void){ CSerialPort::Start(); } void CPowerControlBoard::Pause(void){ CSerialPort::Pause(); } int CPowerControlBoard::InitComPort(char *ttyName,unsigned short band){ return CSerialPort::InitComPort(ttyName,CLOCAL|CS8,band); } int CPowerControlBoard::ChangeLed(int channel, unsigned char on){ int fd; if( (fd=open(DEVICE_LED, O_RDWR | O_NONBLOCK)) < 0 ){ perror("CPowerControlBoard::ChangeLed():open(DEVICE_LED, O_RDWR | O_NONBLOCK)"); return 0; } switch(channel) { case 1: if (!on) ioctl(fd, SWITCH_O1 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O1, 1); break; case 2: if (!on) ioctl(fd, SWITCH_O2 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O2, 1); break; case 3: if (!on) ioctl(fd, SWITCH_O3 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O3, 1); break; case 4: if (!on) ioctl(fd, SWITCH_O4 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O4, 1); break; case 5: if (!on) ioctl(fd, SWITCH_O5 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O5, 1); break; case 6: if (!on) ioctl(fd, SWITCH_O6 | SWITCH_OFF, 1); else ioctl(fd, SWITCH_O6, 1); break; case 7: //allon ioctl(fd, SWITCH_O1, 1); ioctl(fd, SWITCH_O2, 1); ioctl(fd, SWITCH_O3, 1); ioctl(fd, SWITCH_O4, 1); ioctl(fd, SWITCH_O5, 1); ioctl(fd, SWITCH_O6, 1); break; case 8: //alloff ioctl(fd, SWITCH_O1 | SWITCH_OFF, 1); ioctl(fd, SWITCH_O2 | SWITCH_OFF, 1); ioctl(fd, SWITCH_O3 | SWITCH_OFF, 1); ioctl(fd, SWITCH_O4 | SWITCH_OFF, 1); ioctl(fd, SWITCH_O5 | SWITCH_OFF, 1); ioctl(fd, SWITCH_O6 | SWITCH_OFF, 1); break; default: break; } close(fd); return 0; } void CPowerControlBoard::SendControlSwitch(unsigned char channel, unsigned char on){ int i; char sum = 0; char cmdbuf[] = {0x1E, 0x21, 0x02, channel, on, 0x22, 0xE1}; /*此句不能移到开头定义 */ switch(channel) { case 0: channel = 0x01; break; case 1: channel = 0x02; break; case 2: channel = 0x04; break; case 3: channel = 0x08; break; case 4: channel = 0x10; break; case 5: channel = 0x20; break; case 6: channel = 0xff; break; } on = on ? channel : 0; cmdbuf[3]=channel; cmdbuf[4]=on; for (i = 1; i< 5; i++) { sum ^= cmdbuf[i]; } cmdbuf[5] = sum; SendData((const unsigned char*)cmdbuf, (int)sizeof(cmdbuf)); } void CPowerControlBoard::ControlSwitch(unsigned char channel, unsigned char on){ ChangeLed(channel, on); SendControlSwitch(channel, on); } void CPowerControlBoard::Reboot(unsigned char channel){ if (channel > 5) return; ChangeLed(channel, 1); ControlSwitch(channel, 0); sleep(2); ControlSwitch(channel, 1); } void CPowerControlBoard::Update61CMD(unsigned char* buff){ int i; unsigned char sw0,sw1; unsigned short cn[6]; unsigned short temp; sw0 = buff[0]; sw1 = buff[1]; for ( i = 0; i < 6; i++) { cn[i] = buff[2 + 2 * i] >> 8 | buff[3 + 2 * i] ; // PRINTF("%.2f ", (float)(cn[i]) / 0x30); } temp = buff[2 + 2 * i] >> 8 | buff[3 + 2 * i]; // PRINTF("temp=%d/n", temp); m_AlarmInfoFile.WriteCNAlarm(cn); m_AlarmInfoFile.WriteTempAlarm(temp); m_SwitchStatus.WriteSwitchStatus(sw0, sw1); }

 

/**************************************************************** Copyright(c) 2009-2010,Newkoom Net Tech.Co,.Ltd 模块名称(Filename): powercontrolboard.h 项目名称(Projectname): RPM(Remote Power Manager System) 版本号(Version): 1.0.0 创建日期(Date): 2009-11-22 作者(Author): ZMF(Zheng meifu) 功能描述(Description): powercontrolboard class header 其他说明(Others): 修改记录(History): 调试成功: ****************************************************************/ #ifndef NEWTECH_H_ #define NEWTECH_H_ #define DEVICE_LED "/dev/ledrpm" #define SWITCH_ON 0x07 #define SWITCH_OFF 0x80 #define SWITCH_O1 0x01 #define SWITCH_O2 0x02 #define SWITCH_O3 0x03 #define SWITCH_O4 0x04 #define SWITCH_O5 0x05 #define SWITCH_O6 0x06 #include "beep.h" #include "serial.h" #include "rcvbuff.h" #include "alarminfofile.h" #include "switchstatus.h" #include "led.h" #define SRL_HAVESENDBIT 4 #define SRL_HAVEACKBIT 0 #define SRL_PORTMASK 0XF000 #define SRL_TIMESMASK 0X0F00 /* m_srl_state: bit11-bit8: repeat send times per second. bit15-bit12:send switch port. bit4:be have send data. bit0:received ack signal. */ class CPowerControlBoard: public CReceiveBuffer<48>, public CSerialPort, public Cledcontrol, public Cbeep { protected: CSwitchStatus m_SwitchStatus; /*开关状态*/ CAlarmInfoFile m_AlarmInfoFile; /*报警信息文件*/ unsigned char m_cmd[20]; int addbyte(unsigned char b); /*解包函数*/ void ProcessOKPack(unsigned char *buff,unsigned char len); /*处理正确包*/ void ProcessBadPack(unsigned char *buff,unsigned char len); /*处理错误包*/ void CaleCheckSum(unsigned char* buff); /*计算校验字*/ void Update61CMD(unsigned char* buff); /*处理61号指令*/ public: /*增加串口接收数据,交由addbyte函数处理*/ int m_srl_state; virtual void addbytes(/*const*/ unsigned char *b,int size); CPowerControlBoard(); virtual ~CPowerControlBoard(); void Start(void); void CPowerControlBoard::Pause(void); unsigned long m_PacketErrorCount,m_TotalPacket; /*错误与正确包数*/ int InitComPort(char *ttyName,unsigned short band); /*初始化串口*/ void PrintSerialPortStat(char *buff); /*串口通讯状态*/ void ControlSwitch(unsigned char channel, unsigned char on); /*控制开关,包括LED灯状态与电源状态*/ void SendControlSwitch(unsigned char channel, unsigned char on);/*与控制板通讯,仅控制电源状态*/ int ChangeLed(int channel, unsigned char on); /*更改LED灯状态*/ void Reboot(unsigned char channel); /*发送命令重启某一路电源*/ }; extern CPowerControlBoard g_PowerControlBoard; #endif

你可能感兴趣的:(nand flash坏块多怎么解决?是我的应用程序有问题吗?高手请指点:Q:26451602)