Skip to content

Instantly share code, notes, and snippets.

@triffid
Last active December 28, 2015 02:29
Show Gist options
  • Select an option

  • Save triffid/7427973 to your computer and use it in GitHub Desktop.

Select an option

Save triffid/7427973 to your computer and use it in GitHub Desktop.
async fat description
/*
* Operation of Asynchronous FAT:
*
* All calls return immediately. We NEVER busyloop, waiting for data
*
* Whenever new data is required, we request a DMA transfer and return
*
* We maintain a queue of tasks. External tasks (eg open, read, readdir) are
* placed at the bottom of the queue.
* Internal tasks (eg traverse FAT, read directory, etc) are placed at the
* head of the queue.
*
* When a new block of data arrives, we examine the first item in the queue.
* Usually, it can do something useful with the newly arrived data.
*
* When a queue item has finished, it is removed from the queue, and the next
* item is activated.
*
* This, in combination with placing internal tasks on the top of the queue,
* means that the following sequence might occur:
*
* external -> f_open(&FIL, "/path/to/file.txt")
*
* [ add file_open action to TAIL of stack ]
* cache_test(root_dir_cluster) -> fail
* [ PUSH directory_traverse action to HEAD of stack ]
* request dir cluster from disk, return
*
* disk->read_complete()
* [ POP request from head of stack -> directory_traverse action ]
* cache_test(root_dir_cluster) -> success
* find "path/" in root_dir_cluster.
* cache_test(cluster for "path/") -> fail
* [ PUSH directory_traverse action to HEAD of stack ]
* request cluster from disk, return
*
* disk->read_complete()
* [ POP request from head of stack -> directory_traverse action ]
* cache_test(cluster for "path/") -> success
* find "to/" in cluster for "path/"
* cache_test(cluster for "to/") -> fail
* [ PUSH directory_traverse action to HEAD of stack ]
* request from disk, return
*
* disk->read_complete()
* [ POP request from head of stack -> directory_traverse action ]
* cache_test(cluster for "to/") -> success
* find "file.txt" in cluster for "to/" -> fail
* not in first 16 entries, cache_test(2nd cluster for "to/") ->fail
* [ PUSH directory_traverse action to HEAD of stack ]
* request from disk, return
*
* disk->read_complete()
* [ POP request from head of stack -> directory_traverse action ]
* cache_test(2nd cluster for "to/") -> success
* find "file.txt" in cluster -> success
* [ POP request from head of stack -> file_open action ]
* fill the FIL structure stored in the file_open action with data from the
* dir cluster
*
* fire callback stored in file_open action
*
* stack empty!
*
* external -> f_read(&FIL, buffer, size)
* cache_test(first cluster, from &FIL) -> fail
* [ PUSH file_read to TAIL of stack ]
* request from disk, return
*
* disk->read_complete()
* [ POP request from stack -> file_read ]
* cache_test(first cluster from &FIL) -> success
*
* fire read_complete callback
*
* stack empty!
*
* external -> f_read(&FIL, buffer, size)
* [ PUSH file_read to TAIL of stack ]
* find next cluster
* cache_test(FAT cluster map) -> fail
* [ PUSH cluster_traverse to HEAD of stack ]
* request cluster map from disk, return
*
* disk->read_complete()
* [ POP stack -> cluster_traverse ]
* find relevant cluster
* cache_test(FAT cluster map) -> success
* update file_read action
* [ POP stack -> file_read ]
* cache_test(2nd cluster) -> fail
* [ PUSH file_read action to HEAD of stack (not finished) ]
* request cluster from disk, return
*
* disk->read_complete()
* [ POP stack -> file_read ]
* cache_test(file data) -> success!
*
* trigger file_read callback
*
* stack empty!
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment