memorycache.java
来自「这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统」· Java 代码 · 共 1,455 行 · 第 1/3 页
JAVA
1,455 行
{ // check if already in cache if ((pageState[page] == READ_CRC) || (pageState[page] == VERIFY) || (pageState[page] == WRITE)) break; // read the page with device generated CRC if (pmb.hasExtraInfo()) { pmb.readPageCRC(page, (lastPageRead == (page - 1)), cache [page], 0, tempExtra); // set the last page read lastPageRead = page; // get the redirection byte redirect [page] = ~tempExtra [0] & 0x00FF; } // OTP device that does not give redirect as extra info (DS1982/DS2502) else { pmb.readPageCRC(page, (lastPageRead == (page - 1)), cache [page], 0); // get the redirection redirect[page] = (byte)(((OTPMemoryBank)pmb).getRedirectedPage(page)); // last page can't be used due to redirect read lastPageRead = NONE; } // set the page state pageState[page] = READ_NO_CRC; //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_Page: " + page + "->" + redirect [page] + " local " + local_page + " with packet length byte " + (cache[page][0] & 0x00FF)); // not redirected so look at packet if (redirect [page] == 0) { // check if length is realistic if ((cache [page][0] & 0x00FF) > maxPacketDataLength) throw new OneWireIOException( "Invalid length in packet"); // verify the CRC is correct if (CRC16.compute(cache [page], 0, cache [page][0] + 3, page) == 0x0000B001) { // get the length len [page] = cache [page][0]; // set the page state pageState[page] = READ_CRC; break; } else throw new OneWireIOException( "Invalid CRC16 in packet read " + page); } } else page = redirect [page]; // check for looping redirection if (loopcnt++ > totalPages) throw new OneWireIOException( "Circular redirection of pages"); } //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_Data found (" + len [page] + "):"); debugDump(cache [page], 1, len [page]); } // get copy of data for caller if (readBuf != null) System.arraycopy(cache [page], 1, readBuf, offset, len [page]); return len [page]; } // not an EPROM else { // loop if get a crc error in packet data until get same data twice for (;;) { pmb.readPage(local_page, (lastPageRead == (page - 1)), tempPage, 0); //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_Page: " + page + " translates to " + local_page + " or device page " + local_device_page); // set the last page read lastPageRead = page; // verify length is realistic if ((tempPage [0] & 0x00FF) <= maxPacketDataLength) { // verify the CRC is correct if (CRC16.compute(tempPage, 0, tempPage [0] + 3, local_device_page) == 0x0000B001) { // valid data so put into cache System.arraycopy(tempPage, 0, cache [page], 0, tempPage.length); // get the length len [page] = tempPage [0]; // set the page state pageState[page] = READ_CRC; break; } } //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_Invalid CRC, raw: "); debugDump(tempPage, 0, tempPage.length); } // must have been invalid packet // compare with data currently in the cache boolean same_data = true; for (int i = 0; i < tempPage.length; i++) { if ((tempPage [i] & 0x00FF) != (cache [page][i] & 0x00FF)) { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_Differenet at position=" + i); same_data = false; break; } } // if the same then throw the exception, else loop again if (same_data) { // set the page state pageState[page] = READ_NO_CRC; throw new OneWireIOException( "Invalid CRC16 in packet read"); } else System.arraycopy(tempPage, 0, cache [page], 0, tempPage.length); } } //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_Data found (" + len [page] + "):"); debugDump(cache [page], 1, len [page]); } // get copy of data for caller if (readBuf != null) System.arraycopy(cache [page], 1, readBuf, offset, len [page]); return len [page]; } // page IS cached (READ_CRC, VERIFY, WRITE) else { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_In cache (" + len [page] + "):"); debugDump(cache [page], 1, len [page]); } // get from cache if (readBuf != null) System.arraycopy(cache [page], 1, readBuf, offset, len [page]); return len [page]; } } /** * Write a page packet into the cache. * * @param page page to write * @param writeBuf buffer container the data to write * @param offset offset into write buffer * @param buflen length of data to write */ public void writePagePacket(int page, byte[] writeBuf, int offset, int buflen) throws OneWireIOException, OneWireException { int log; //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("___writePagePacket on page " + page + " with data (" + buflen + "): "); debugDump(writeBuf, offset, buflen); } // check if have a cache (any memory banks) if (totalPages == 0) throw new OneWireException("1-Wire Filesystem does not have memory"); // check if need to read the page bitmap for the first time if (!pbmRead) readPageBitMap(); // OTP device if (canRedirect) { // get reference to memory bank OTPMemoryBank otp = (OTPMemoryBank)getMemoryBankForPage(page); // check redirectoin if writing to a page that has not been read if ((redirect[page] == 0) && (pageState[page] == NOT_READ)) redirect[page] = otp.getRedirectedPage(page); // check if page to write to is already redirected if (redirect[page] != 0) { // loop to find the end of the redirect chain int last_page = page, cnt = 0; lastPageRead = NONE; do { last_page = redirect[last_page]; redirect[last_page] = otp.getRedirectedPage(last_page); if (cnt++ > totalPages) throw new OneWireException("Error in Filesystem, circular redirection of pages"); } while (redirect[last_page] != 0); //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.print("___redirection chain ended on page " + last_page); // Use the last_page since it was not redirected System.arraycopy(writeBuf, offset, cache[last_page], 1, buflen); len [last_page] = buflen; cache [last_page][0] = (byte) buflen; int crc = CRC16.compute(cache[last_page], 0, buflen + 1, last_page); cache[last_page][buflen+1] = ( byte ) (~crc & 0xFF); cache[last_page][buflen+2] = ( byte ) (((~crc & 0xFFFF) >>> 8) & 0xFF); // set pageState flag pageState [last_page] = VERIFY; // change page to last_page to be used in writeLog page = last_page; } else { // Use the page since it is not redirected System.arraycopy(writeBuf, offset, cache[page], 1, buflen); len [page] = buflen; cache [page][0] = (byte) buflen; int crc = CRC16.compute(cache[page], 0, buflen + 1, page); cache[page][buflen+1] = ( byte ) (~crc & 0xFF); cache[page][buflen+2] = ( byte ) (((~crc & 0xFFFF) >>> 8) & 0xFF); // set pageState flag pageState [page] = VERIFY; } } // NON-OTP device else { // put in cache System.arraycopy(writeBuf, offset, cache [page], 1, buflen); len [page] = buflen; cache [page][0] = (byte) buflen; // set pageState flag pageState [page] = WRITE; } // record write in log // search the write log until find 'page' or EMPTY for (log = 0; log < totalPages; log++) { if ((writeLog [log] == page) || (writeLog [log] == EMPTY)) break; } // shift write log down 1 to 'log' for (; log > 0; log--) writeLog [log] = writeLog [log - 1]; // add page at top writeLog [0] = page; } /** * Flush the pages written back to the 1-Wire device. * * @throws OneWireException when the adapter is not setup properly * @throws OneWireIOException when an 1-Wire IO error occures */ public void sync() throws OneWireIOException, OneWireException { int page, log; //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("___sync"); // check if have a cache (any memory banks) if (totalPages == 0) return; // loop until all jobs complete boolean jobs; do { jobs = false; // loop through write log and write the oldest pages first for (log = totalPages - 1; log >= 0; log--) { // check if this is a valid log entry if (writeLog [log] != EMPTY) { // this was not empty so there is a job jobs = true; // get page number to write page = writeLog [log]; //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_page " + page + " in log " + log + " is not empty, pageState: " + pageState[page]); // get the memory bank PagedMemoryBank pmb = (PagedMemoryBank)getMemoryBankForPage(page); // get the local page number int local_page = getLocalPage(page); // Verify operation (only in EPROM operations) if (pageState[page] == VERIFY) { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_verify page " + page); // read the page with device generated CRC pmb.readPageCRC(page, (lastPageRead == (page - 1)), tempPage, 0); // set the last page read lastPageRead = page; //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_Desired data: "); debugDump(cache [page], 0, cache[page].length); System.out.print("_Current data: "); debugDump(tempPage, 0, tempPage.length); System.out.println("_len " + len[page]); } // check to see if the desired data can be written here boolean do_redirect = false; for (int i = 1; i < (len[page] + 2); i++) { if ((((tempPage[i] & 0x00FF) ^ (cache[page][i] & 0x00FF)) & (~tempPage[i] & 0x00FF)) > 0) { // error, data already on device, must redirect do_redirect = true; break; } } // need to redirect if (do_redirect) { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_page is occupied with conflicting data, must redirect"); // find a new page, set VERIFY job there // get the next available page int new_page = getFirstFreePage(); while (new_page == page) { System.out.println("_can't use this page " + page); markPageUsed(new_page); new_page = getNextFreePage(); } // verify got a free page if (new_page < 0) throw new OneWireException("Redireciton required but out of space on 1-Wire device"); // mark page used markPageUsed(new_page); // put the data in the new page and setup the job System.arraycopy(cache[page], 0, cache[new_page], 0, tempPage.length); pageState[new_page] = VERIFY; len[new_page] = len[page]; // add to write log for (int i = 0; i < totalPages; i++) { if (writeLog[i] == EMPTY) { writeLog[i] = new_page; break; } } // set old page for redirect pageState[page] = REDIRECT; cache[page][0] = (byte)(new_page & 0xFF); } // verify passed else pageState[page] = WRITE; } // Redirect operation if (pageState[page] == REDIRECT) { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) System.out.println("_redirecting page " + page + " to " + (cache[page][0] & 0x00FF)); // redirect the page (new page located in first byte of cache) ((OTPMemoryBank)pmb).redirectPage(page, cache[page][0] & 0x00FF); // clear the redirect job pageState [page] = NOT_READ; lastPageRead = NONE; writeLog [log] = EMPTY; } // Write operation if (pageState [page] == WRITE) { //\\//\\//\\//\\//\\//\\//\\// if (doDebugMessages) { System.out.print("_write page " + page + " with data (" + len [page] + "): "); debugDump(cache [page], 1, len [page]); } // check for new device, make sure it is at the correct speed
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?