As mentioned last week, the basic logic for the mechanism was devised within the PIC but it needed to be integrated to store and receive information on where the correct version of the file is saved onto the SD card from the card’s MBR itself. The biggest challenge to this problem was to safely store information onto the MBR of the SD card so that it is not damaged in the process. The MBR(Master Boot Record) is the boot sector at Sector 0 of the SD card. It contains information used to boot the card as well as information about the partitions on the card. Information on the MBR is used to initialize the SD card on devices, so any damage to it would cause the SD card to become unusable unless the MBR is overwritten again with the correct information.
Writing the MBR safely
This tricky task was the most time consuming during the week. The MBR is a 512-byte sector, addressed at 0 and in general is filled with null character except for some specified byte addresses which help the card to initialize its partitions. The last two bytes in the MBR is the unique signature for SD cards. Previously, my colleague modified a function called FSCreateMBR() to recreate the MBR to reserve 1MB of space and named it AesteCreateMBR()[https://blog.aeste.my/archives/2578]. By modifying this function further, it was possible to store a sector address, specified as an argument for the function, at a specified byte address within the MBR. The sector address would require 2 bytes. The information was stored in the byte space reserved for the number of sectors information for partition 3. This 2 bytes are reserved at bytes 506 and 507. The edited function was called AesteEditMBR. This function was tested by feeding in specified values and found that the two bytes were written correctly without damage to the MBR. The following is a screenshot of the hex-dump made to check whether the information was being written correctly into the MBR. The bytes 506 and 507 are highlighted, to show the value it contains.
The function does not only edit and write the two bytes into the MBR but recreates the MBR completely. The two bytes are the only new pieces of information stored in it, but the rest are just carried over from the previous version of the MBR.
Reading from MBR
The next task was comparatively easier to implement. The data stored into the MBR must be read out and the information used for the PIC to decide where the correct version of the bitstream is stored onto the SD card. A simple function was written to read the bytes specified for the sector address information (bytes 506 and 507) and store that information as a 16-bit sector address. The function created was MBRCheck, which takes in no arguments and returns a 16-bit sector address retrieved from the MBR.
Integration into the File Upload System
The functions created were integrated into the file upload section of the main program. The following flowchart describes the logic of how the mechanism works in conjunction with the File Upload seciton:
For the scenario depicted in the flowchart, there are two sections in the 1MB reserved for the bitstream, section A & B. The MBRCheck function is used to determine where the PIC should start reading from, and so it contains the sector address of the correct bitstream data. After this value is checked, a flag is used to determine where the bitstream should be downloaded. After the download is complete, the MBR is updated with the sector address of where the new bitstream data is stored. Since there are only two sections, an If/Else condition suffices for the check. An additional check is used so that if the MBR is not written with the value of the sector address, it will redirect the PIC to write into the second section (B).
Similar Problems arise
During the integration of the newly created functions into the main program, an old nemesis reared its ugly head. During initial testing of the file upload system with the newly created functions to read/write the MBR, the process failed to change the MBR at all. After some debugging, it was found that this was down to the fact that the data written to the MBR is also CRC protected and a valid 2 bytes of CRC need to be sent to the SD card in order to successfully complete the MBR write process. Thus a new function was made to write into the MBR by taking in 2 bytes of CRC as an argument and feeding it into the SD card when the block boundary is reached. The only bad thing about this is the CRC is hard coded and must be recalculated for the different sector address values stored within the MBR. As of now, there are only two values being used so the CRC values are fed in using a sector address flag to determine which value to use.
Another change that was needed was that the single block write command should be accompanied by a 1 byte CRC7 value and is unique, so it was hard coded into the writing stack.
Some work was also done to understand how the Master/Slave modes work done by colleague. The flow of the code was easy to understand and the implementation into the main program was also understood quite easily. Overall this week was quite productive as the upload mechanism reaches its completion.