/** @ingroup FLASH * フラッシュ書き込み * @param psFlash 書き込みたいデータ * @param sector 書き込みセクタ * @param offset 書き込みセクタ先頭からのオフセット * @return TRUE:書き込み成功 FALSE:失敗 */ bool_t bFlash_Write(tsFlash *psFlash, uint8 sector, uint32 offset) { bool_t bRet = FALSE; offset += (uint32)sector * FLASH_SECTOR_SIZE; // calculate the absolute address #ifdef USE_EEPROM psFlash->u32Magic = FLASH_MAGIC_NUMBER; psFlash->u8CRC = u8CCITT8((uint8*)&(psFlash->sData), sizeof(tsFlashApp)); if (EEP_6x_bWrite(0, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } #else if (bAHI_FlashInit(FLASH_TYPE, NULL) == TRUE) { if (bAHI_FlashEraseSector(sector) == TRUE) { // erase a corresponding sector. psFlash->u32Magic = FLASH_MAGIC_NUMBER; psFlash->u8CRC = u8CCITT8((uint8*)&(psFlash->sData), sizeof(tsFlashApp)); if (bAHI_FullFlashProgram(offset, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } } } #endif return bRet; }
uint8 commitCodeUpdate(uint8* inMsg, uint8* outMsg) { uint32 sectorSize; int rxbat=u16ReadADC(E_AHI_ADC_SRC_VOLT);//3838 4096 = 2.4*1.5 =3.6v rxbat=rxbat*360/4096; uint8 copyBuf[256]; uint32 maxUpload; #ifdef JN5148 sectorSize=0x10000; maxUpload=sectorSize; #else sectorSize=0x8000; maxUpload=2*sectorSize; #endif if(rxbat<300 ) { outMsg[0]=0x95;//fail outMsg[1]=3; return 2; } if(codeUpdateLength>maxUpload) { outMsg[0]=0x95;//fail outMsg[1]=2; return 2; } if(codeUpdateCrc!=inMsg[1]) { outMsg[0]=0x95;//fail outMsg[1]=1; return 2; } #ifdef JN5148 //copy flash sector 1 to sector 0 bAHI_FlashEraseSector(0); uint32 addr=0; while(addr<codeUpdateLength) { bAHI_FullFlashRead(addr+sectorSize,256,copyBuf); bAHI_FullFlashProgram(addr,256,copyBuf); addr+=256; } #endif vAHI_SwReset(); return 0; }
PUBLIC void vFlashSettings_write(void){ // Очистить сектор bAHI_FlashEraseSector(FLASH_INTERNAL_APPROPRIATE_USER_DATA_SECTOR-1); // Подсчитать контрольную сумму vFlashSettings_calculateCRC(); // Копировать настройки в буфер memcpy(FlashCash, CurrentSettingsContent, CurrentSettingsLength); // Записать весь буфер во Flash bAHI_FullFlashProgram(FLASH_INTERNAL_APPROPRIATE_USER_DATA_OFFSET, APPROPRIATE_SETTINGS_LENGTH_IN_BYTES, FlashCash); }
PUBLIC void FlashWrite(Object object) { uint8 data[CONFIG_OBJECT_SIZE]; // init FlashInit(data); data[0] = FLASH_HAS_DATA; ConverterUint32ToUint8(object.valControl, &data[1]); ConverterUint32ToUint8(object.sendDval, &data[5]); ConverterUint16ToUint8(object.readTime, &data[9]); ConverterUint16ToUint8(object.sendTime, &data[11]); ConverterUint32ToUint8(object.config, &data[13]); bAHI_FullFlashProgram(m_FlashStartAddress + DEVISEDESCRIPTOR_SIZE + object.objectID * CONFIG_OBJECT_SIZE, CONFIG_OBJECT_SIZE, data); vAHI_FlashPowerDown(); }
PUBLIC void FlashWriteDeviceDescriptor(DeviceDescriptor deviceDescriptor) { uint8 data[DEVISEDESCRIPTOR_SIZE]; // init FlashInit(data); bAHI_FlashEraseSector(3); data[0] = FLASH_HAS_DATA; ConverterStringToUint8(deviceDescriptor.name, &data[1]); data[33] = deviceDescriptor.netID; data[34] = deviceDescriptor.demoMode; data[35] = deviceDescriptor.testMode; ConverterStringToUint8(deviceDescriptor.descriptor, &data[36]); ConverterStringToUint8(deviceDescriptor.xdata, &data[49]); // запись даты поверки в датчиках и цифровой подписи в координаторах data[50] = deviceDescriptor.router; // 1-режим работы только с роутерами //bAHI_FullFlashProgram(m_FlashStartAddress+deviceDescriptor.objectID*CONFIG_OBJECT_SIZE, DEVISEDESCRIPTOR_SIZE, data); bAHI_FullFlashProgram(m_FlashStartAddress, DEVISEDESCRIPTOR_SIZE, data); vAHI_FlashPowerDown(); }
uint8 codeUpdateChunk(uint8* inMsg, uint8* outMsg) { //todo check no chunks are missed and probably use bigger crc uint32 sectorSize; uint32 writeBase; int i; #ifdef JN5148 sectorSize=0x10000; writeBase=sectorSize; #else sectorSize=0x8000; writeBase=0; #endif uint8 len=inMsg[1]; for(i=2;i<len+2;i++) { codeUpdateCrc^=inMsg[i]; } //copy in mac address and clear sectors on jn5139 if(codeUpdateLength==0) { bAHI_FullFlashRead(48,32,&inMsg[48+2]); #if (JENNIC_CHIP_FAMILY == JN514x) #else bAHI_FlashEraseSector(0); #endif } //write to flash buffer bAHI_FullFlashProgram(writeBase+codeUpdateLength,len,&inMsg[2]); codeUpdateLength+=len; //send ack outMsg[0]=0x93; return 1; }
static void appcall(void *p) { static struct bl_appstate s = { IDLE, 0x00, 0x00, false }; clock_time_t time = clock_time(); msg_t *msg = uip_appdata, *smsg = uip_sappdata; if(uip_connected()) { s.state = IDLE; s.reset_req = false; s.write_addr = 0; s.write_len = 0; s.msg_len = 0; GDB2_PUTS(" conn "); } if(uip_closed() || uip_aborted() || uip_timedout()) { uip_close(); if(s.reset_req && uip_closed()) vAHI_SwReset(); /* at this point the system RESETS */ s.state = IDLE; GDB2_PUTS(" close\n"); } if(uip_acked()) { if (s.state==SENDING) { s.msg_len = 0; s.state = IDLE; }; GDB2_PUTS("bootloader: acked\n"); } if(uip_newdata()) { if (s.state == FLASHING) { bAHI_FullFlashProgram(s.write_addr, uip_datalen(), (uint8_t*) msg); s.write_addr += uip_datalen(); if(s.write_addr >= s.write_len) { GDB2_PUTS("bootloader: write done\n"); s.write_len = 0; s.state = SENDING; smsg->type = RSP_FLASH_PROG2; smsg->len = MSG_SIZEOF(smsg->asFlashWrite2Rsp); smsg->asFlashWrite2Rsp = OK; } } else if(s.state != SENDING) { s.msg_len += uip_datalen(); if(s.msg_len == msg->len) { GDB2_PUTS("bootloader: send\n"); s.msg_len = 0; s.state = SENDING; switch(msg->type) { case REQ_FLASH_ERASE: smsg->asFlashEraseRsp = bAHI_FlashEraseSector(0) ? OK : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(1) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(2) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(3) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = OK; smsg->type = RSP_FLASH_ERASE; smsg->len = MSG_SIZEOF(smsg->asFlashEraseRsp); break; case REQ_FLASH_PROGR: smsg->asProgramRsp = bAHI_FullFlashProgram(msg->asProgramReq.addr, msg->len-MSG_HDR_SIZE-sizeof(msg->asProgramReq.addr), msg->asProgramReq.data) ? OK : NOT_SUPPORTED; smsg->type = RSP_FLASH_PROGR; smsg->len = MSG_SIZEOF(smsg->asProgramRsp); break; case REQ_FLASH_READ: smsg->type = RSP_FLASH_READ; smsg->len = MIN(MSG_SIZEOF(smsg->asReadRsp), MSG_HDR_SIZE+(sizeof(smsg->asReadRsp)-sizeof(smsg->asReadRsp.data)) +msg->asReadReq.len); smsg->asReadRsp.status = bAHI_FullFlashRead(msg->asReadReq.addr, MIN(sizeof(smsg->asReadRsp.data), msg->asReadReq.len), smsg->asReadRsp.data) ? OK : NOT_SUPPORTED; break; case REQ_SECTOR_ERASE: smsg->asSelectRsp = OK; smsg->asSectorRsp = bAHI_FlashEraseSector(msg->asSectorReq) ? OK : NOT_SUPPORTED; smsg->type = RSP_SECTOR_ERASE; smsg->len = MSG_SIZEOF(smsg->asSectorRsp); break; case REQ_SR_WRITE: smsg->asSRRsp = NOT_SUPPORTED; smsg->type = RSP_SR_WRITE; smsg->len = MSG_SIZEOF(smsg->asSRRsp); break; case REQ_RAM_WRITE: memcpy((uint32_t*) smsg->asRamWriteReq.addr, smsg->asRamWriteReq.data, smsg->len-MSG_HDR_SIZE); smsg->asRamWriteRsp = OK; smsg->type = RSP_RAM_WRITE; smsg->len = MSG_SIZEOF(smsg->asRamWriteRsp); break; case REQ_RAM_READ: smsg->type = RSP_RAM_READ; smsg->len = MIN(MSG_SIZEOF(smsg->asRamReadRsp), MSG_HDR_SIZE+ (sizeof(smsg->asRamReadRsp)-sizeof(smsg->asRamReadRsp.data))+msg->asRamReadReq.len); memcpy(smsg->asRamReadRsp.data, (uint32_t*) msg->asRamReadReq.addr, MIN(sizeof(smsg->asRamReadRsp.data), msg->asRamReadReq.len)); break; case REQ_RUN: s.reset_req = true; smsg->asRunRsp = OK; smsg->type = RSP_RUN; smsg->len = MSG_SIZEOF(msg->asRunReq); break; case REQ_FLASH_ID: smsg->asFlashIdRsp.status = OK; smsg->asFlashIdRsp.manufacturer = smsg->asFlashIdRsp.device = 0x10; smsg->type = RSP_FLASH_ID; smsg->len = MSG_SIZEOF(smsg->asFlashIdRsp); break; case REQ_FLASH_SELECT: smsg->asSelectRsp = bAHI_FlashInit(msg->asSelectReq.flashtype, (tSPIflashFncTable*) msg->asSelectReq.addr) ? OK : NOT_SUPPORTED; smsg->type = RSP_FLASH_SELECT; smsg->len = MSG_SIZEOF(smsg->asSelectRsp); break; case REQ_FLASH_PROG2: GDB2_PUTS("bootloader: flashing started\n"); s.state = FLASHING; s.write_addr = 0x00000000; s.write_len = msg->asFlashWrite2.len; break; default: smsg->asSRRsp = NOT_SUPPORTED; smsg->type = RSP_SR_WRITE; smsg->len = MSG_SIZEOF(smsg->asSRRsp); } } } } if(uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) { if(s.state==SENDING) uip_send(smsg, smsg->len); } /* this is odd but needed to get tcp throughput rate in sync with flash * write rate, otherwise rtt is calculated as the rtt of small packets which * is too fast when writing to the flash has started, therefore limiting * the overall throughput of the bootloader protocol. */ time = clock_time() - time; if (time < CLOCK_SECOND/12) clock_delay(CLOCK_SECOND/12 - time); }