2009-09-23

NXT新舊韌體差異--FileAccess

這是一篇NXT技術性文章,記錄1.28與1.05 FileAccess的差異。

論壇討論文章轉貼如下:

Actually, except when asked to test something under 2.0, I still use 1.1... mostly because I don't have a problem with it, and 2.0 has one very serious draw-back from my point of view; try logging a bunch of data rapidly, and you'll find that occasionally the FW stalls everything while (apparently) moving files. This can stall the FW for as much as a second in test I did earlier, which I think you can see would cause some... problems, with any program making use of file writing excessively. You can get around this if you know what you're doing by only opening fixed-sized files... but that only works, of course, if you already know what (how much) you are going to write before you write it.

The other thing to realize is that motor control occurs on the secondary processor in the NXT, which does not have updated FW... so at least some of the motor control issues will likely remain. On these, I'm honestly not sure - I've not done a detailed study of, say, edge-following under 1.1 vs 2.0. It would be interesting running the "same" program under the two version, to see if there's a discernible difference in performance.

Since at least this year, the LEGO color sensor isn't allowed in FLL, the ability to address it under 2.0 really has no impact for FLL. Personally, I don't think adding floating point helps in FLL at all (I rather think it detracts, actually), so to my way of thinking, that's another non-issue (or even drawback).

--
Brian Davis


What Brian is talking about is an artifact of the FileAccess block in NXT-G. Since the firmware does not have a native file growing operation the FileAccess block implements this feature in VM code. If you try to write to a file that is already full or does not contain enough free space for the amount of data you are trying to write then it performs a fairly complex algorithm in VM code to create a new larger file and copy all the data from the original file to the new file then writing the data you wanted to write and renaming the file and deleting the old file. It takes a lot of VM operations to do all that. In the 1.0x firmwares the VM would execute 20 operations no matter how long it took before allowing other modules to execute their code. In the 1.2x firmwares the VM is much better at keeping to the strict 1ms cycle for all the firmware modules. So what would happen in the 1.0x firmwares with fast dataloggging that did not specify a large file size to begin with is that whenever it needed to resize the datafile it would starve the other modules while it excecuted these 20-operation chunks of the FileAccess block's growth algorithm. In the 1.2x firmwares the growth algorithm takes a lot longer since sometimes only 1 operation will fit into the allotted time (since file writes can periodically take more than 1 ms). This makes the VM code appear to "stall" but it definitely does not stall other firmware module operations, in fact it is better behaving than it used to be with respect to "stalling" everything in the firmware.

Another thing that changed in the standard 1.28 firmware is that whenever a program ends it truncates any open files to just the filled space by calling CROPDATAFILE instead of CLOSE. As you can see below in the enhanced NBC/NXC 1.28 firmware I switched it back to the 1.0x way of just closing any open files. If you close a file programmatically then this code never executes since the file handle table entry will be zero and the standard FileClose system call does not perform any truncation.

CODE
  //Close any files we had opened programatically
  for (i = 0; i < MAX_HANDLES; i++)
  {
    //Copy i to tmp, because we pass a pointer to it to pFunc
    tmp = i;
    //Close file
    if (*(VarsCmd.FileHandleTable[i]) != 0)
      pMapLoader->pFunc(CLOSE, &tmp, NULL, NULL);
//      pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL);
  }


With respect to a native FileResize operation I began work on that for the enhanced NBC/NXC firmware but I did not finish it. There is a system function exposed in the NXC API but it currently does not do anything in the firmware. The problem is tricky. You don't want to write a single file resize function that attempts to do the entire operation in one fell swoop since that will take more than 1ms and would starve other firmware modules. So it probably needs to be written to operate in chunks as the firmware round-robins through all the modules, including the Loader module which is responsible for all file I/O. Which means you would need to have some sort of "resize is busy" status response code and a way to query the loader module for the current resize status so that in your VM code you could call FileResize and then loop while the Loader module is busy resizing your file. In any case, I need to figure out how long it actually takes the Loader module to create a file of size X (for various values of X), how long it takes the Loader module to read X bytes from a file, how long it takes to write X bytes to a file, and how long it takes to delete a file of size X.

If anyone wants to help me figure this all out I'd be happy for the assistance.

John Hansen


沒有留言:

張貼留言

探奇歡迎大家留言討論!謝謝分享你的意見。