打印
[Kinetis]

KL16使用Ymodem接收数据写flash时遇到问题,大神帮忙分析下

[复制链接]
1867|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
carlyang|  楼主 | 2015-8-15 15:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在用KL16做bootloader时,使用ymodem进行串口数据接收,在将数据写入flash时调用FTFA_PGM4(INT32U addr, INT32U data)一次写4字节,FTFA_PGM4(addr, 0x11223344);用常量写OK,一旦使用FTFA_PGM4(addr, *pdata);使用指针就挂掉跑到HardFault_Handler。
其他地方的函数调用FTFA_PGM4时使用指针代入也是OK,最大的差别只是ymodem接收函数判断比较多,其他地方函数结构简单点。为什么会跑到HardFault_Handler?
ymodem接收函数如下:
int8_t Ymodem_Receive_File(void)
{
    char     back,file_lenth[8]="",file_name[FILE_NAME_LENGTH]="";
        uint16_t i=0,ret,C_count=0;
    uint8_t  lenth_cnt, *file_ptr;
    int32_t  packet_length,packets_received, session_done, file_done,  errors, session_begin;
        uint32_t k,file_len=0;
    uint8    sector=0;
    uint16_t offset = 0;
    uint32   addr,*pdata;
   
        file_ptr = file_ptr;
//格式化APPBak区域
    DISABLE_INT();                          /* 关中断 */
    FTFA_ERSSCRS(AppBakSector,AppBakSectorNum);
    ENABLE_INT();                                  /* 开中断 */
  for (session_done = 0, errors = 0, session_begin = 0; ;)
  {
    for (packets_received = 0, file_done = 0/*, buf_ptr = buf*/; ;)
    {
      back = Ymodem_Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT);
      switch (back)
      {
        case 0:
          errors = 0;
          switch (packet_length)
          {
            /* Abort by sender */
            case - 1:
              Send_Byte(ACK);
              return 0;
            /* End of transmission */
            case 0://说明PC发送完了,单片机收到了EOT
              packets_received=0;//将本次文件接收到数据包计数清零
              Send_Byte(ACK);
              Send_Byte(CRC16);//此时发送方将会开启新的一次传输,若只发一个文件则会有一包全为0的数据。
              break;
            case -2: //CRC校验出错
                Send_Byte(NAK);
                break;
            /* Normal packet packet_size */
            default:
              if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
              {
                Send_Byte(NAK);
              }
              else
              {
                if (packets_received == 0)
                {
                  /*  接收文件名Filename packet */
                  if (packet_data[PACKET_HEADER] != 0)
                  {
                                                                               
                                        for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
                    {
                      file_name[i++] = *file_ptr++;
                    }
                    file_name[i] = '\0';
//                    uart2SendString((uint8 *)"file_name:");
//                    uart2SendString((uint8 *)file_name);
//                    uart2SendString((uint8 *)"\r\n");
                                        file_ptr++;//跳过0字节,指向文件长度起始字节
                                        lenth_cnt=0;
                                        while(*file_ptr != 0x20)//取出文件长度描述
                                        {
                                                file_lenth[lenth_cnt++]=*file_ptr++;
                                        }
                    file_lenth[lenth_cnt]=0;
//                    uart2SendString((uint8 *)"file_lenth:");
//                    uart2SendString((uint8 *)file_lenth);
//                    uart2SendString((uint8 *)"\r\n");
                                        k=1;
                                        while(lenth_cnt--)//
                                        {
                                               
                                                file_len+=(file_lenth[lenth_cnt]-0x30)*k;
                                                k=k*10;
                                        }
                    uart2SendIntNum(file_len);
//                    uart2SendData(packet_data,packet_length+PACKET_OVERHEAD);
                    
                    sector=AppBakSector;//APP备份去起始sector
                    addr = sector*4096;
                    pdata=(uint32 *)(packet_data + PACKET_HEADER);
                    Send_Byte(ACK);
                    Send_Byte(CRC16);//接收文件描述信息所在的第一包后需要发送一个C给PC,PC才会启动发送数据。
                  }
                                                                       
                  /* Filename packet is empty, end session */
                  //说明文件传输完毕,发送方无下一个传输文件可传
                  else
                  {
                    Send_Byte(ACK);//这个ACK回应后,本次通信正式结束,发送端将不再发送任何数据
                    file_done = 1;
                    session_done = 1;
                    break;
                  }
                }                                                                                                       
                /* Data packet */
                else
                {
                    //msDelay(100);
                                    if(packet_length == 1024)
                                        {
                        //DISABLE_INT();
                                                FTFA_PGM_Data(sector,offset,1024,packet_data + PACKET_HEADER);
                        //ENABLE_INT();
//                        FTFA_PGM4(addr, *pdata);
//                        FTFA_PGM4(addr, 0x11223344);
//                        addr+=4;
//                        pdata++;
                                                //根据本次写的数据量,计算准备好下一次写的地址
                                                offset +=1024;     //下一次的开始写地址
                                                if(offset == 1024)
                                                {
                                                        offset = 0;
                                                        sector++;
                                                }
                                    }
                                        else
                                        {
                                                FTFA_PGM_Data(sector,offset,128,packet_data + PACKET_HEADER);
//                        FTFA_PGM4(addr, *pdata);
//                        addr+=4;
//                        pdata++;
                                                offset +=128;
                                                if(offset == 1024)
                                                {
                                                        offset = 0;
                                                        sector++;
                                                }

                                        }
                    
                  Send_Byte(ACK);//数据包接收完后只需要ACK回复,PC就会发送下一个包
                }
                packets_received ++;
                session_begin = 1;
              }
          }
          break;
                                       
                                /*abort by user*/
        case 1:
          Send_Byte(CA);
          Send_Byte(CA);
          return -3;
                               
                                /*timeout or packet error*/
        default:
          if (session_begin > 0)
          {
              errors ++;
              if (errors > MAX_ERRORS)
              {
                Send_Byte(CA);
                Send_Byte(CA);
                return -2;
              }
          }
         if(packets_received == 0)// 第0包数据还没接收到,则继续发送‘C’
         {
//            LED_YELL_TOGGLE();
            Send_Byte(CRC16);
            C_count++;            
            if(C_count==800)//大约800*26ms=20.8s
            {
                C_count = 0;
                return -1;
            }
         }
      }
      if (file_done != 0)
      {
        break;
      }
    }
    if (session_done != 0)
    {
      break;
    }
  }
       
       
  return 1;
}

相关帖子

沙发
carlyang|  楼主 | 2015-8-15 17:01 | 只看该作者
已找到问题,是uint8指针转换转uint32时,uint8的首地址是奇地址,貌似uint32的指针是不能指向奇地址的,导致了出错。

使用特权

评论回复
板凳
春风的暖暖| | 2015-8-15 21:37 | 只看该作者
carlyang 发表于 2015-8-15 17:01
已找到问题,是uint8指针转换转uint32时,uint8的首地址是奇地址,貌似uint32的指针是不能指向奇地址的,导 ...

Ymodem和Xmodem的区别是什么啊

使用特权

评论回复
地板
carlyang|  楼主 | 2015-8-17 09:48 | 只看该作者
春风的暖暖 发表于 2015-8-15 21:37
Ymodem和Xmodem的区别是什么啊

貌似是多文件传输时,传完一个文件后,接收端再次发ACK和C可以使发送端继续传下一个文件。具体百度。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

35

帖子

0

粉丝