⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.tex

📁 嵌入式文件系统 EFSL 0.3.5 / 嵌入式文件系统 EFSL 0.3.5
💻 TEX
字号:
\label{hwdriver}This section will describe step by step how to write an hardware endpoint.You will be required to write your own endpoint in case non of the existing endpointsmatches your hardware.First let's have a look at how EFSL is structured internally.\\\\\includegraphics[scale=0.4]{schematics/objectmodel.eps}\\As you can see we have created a linear object model that is quite simple.The file en filesystem object deal with handling the filesystem specific stuff.Below that we find the Partition object that is responsible for translating partitionrelative addressing into disc-based LBA addressing.The Disc object hold the partition table, and has a direct link to a cache manager, IOMan.In IOMan, all requests for disc sectors come together. IOMan will perform checks to seeif sectors have to be read from disc (or from memory), or written back to disc.In the latter case (reading or writing to disc), a request is made to the hardware layer.The hardware interface has 3 responsibilities :\begin{itemize}	\item Initialize the hardware	\item Read sectors from disc	\item Write sectors to disc\end{itemize}All requests are \textsl{sector}based, a sector is a 512 byte piece from the disc, that is aligned toa 512 byte boundary.\\\\\includegraphics[scale=0.4]{schematics/sector.eps}In this example we will create a new endpoint that will add support for data over pigeon carrierfor the EFSL. Initializing the hardware will require feeding the pigeon and telling it where thedata is. Reading/Writing will entail giving the bird the sector and letting it fly.Perform the following steps:\begin{enumerate}	\item Choose a name for your endpoint\\	You will need this name to create the required defines in the source code.	For our example I've chosen the name \code{PIGEON\_CARRIER}.	For consistency the final name is then \code{HW\_ENDPOINT\_PIGEON\_CARRIER}.	\item Verify the sizes of integers\\	Open \filename{inc/types.h} and create a new entry for pigeon carriers. Perhaps	one of the existing sets is identical to yours and you can copy-paste it.	\item Add your endpoint to \filename{interface.h}\\	Locate the file \filename{interface.h} located in the directory \filename{inc/}	Add a pigeon entry (located above the \code{\#else ... NO INTERFACE DEFINED})\begin{lstlisting}#if defined(HW_ENDPOINT_0)   		#include "interfaces/0.h"#elif defined(HW_ENDPOINT_1)        #include "interfaces/1.h"#elif defined(HW_ENDPOINT_PIGEON_CARRIER)        #include "interfaces/pigeon.h"#else        #error "NO INTERFACE DEFINED - see interface.h"#endif\end{lstlisting}	\item Select your endpoint in \filename{conf/config.h}		\item Create your sourcefiles\\	Create a header file in \filename{inc/} and a sourcefile in \filename {src/interfaces}.	In this example I'm using \filename{pigeon.h} and \filename{pigeon.c}.	\item Add your object file to the Makefile	Take the Makefile that works best on your platform (they should all work with	GNU/Make), or create a new one, using the existing one's as a template.	Make sure to include your new pigeon object to the library.	If you have an 'ar' like utility you can create a static library, else you may	have to create a new project containing all required source files.\end{enumerate}The basic framework is now complete, now all that's left to do is to write the codethat will perform the actual flying work.\subsubsection{hwInterface}This structure represents the underlying hardware. There are some field that are requiredto be present (because EFSL uses them), but you may put in as much or a little asyour driver requires to access the hardware.As always in embedded design it is recommended to keep this structure as smallas possible.Example:\begin{lstlisting}struct hwInterface{	/* Field created for THIS hardware */	Pigeon pigeon;	/* Obligatory fields */	euint32 sectorCount;};typedef struct hwInterface hwInterface;\end{lstlisting}\subsubsection{if\_initInterface}This function will be called one time, when the hardware object is initialized by \code{efs\_init()}. This code should bring the hardware in a ready to use state.The function's prototype is\\\code{esint16 if\_initInterface(hwInterface *hw, euint8* opts);}Optionally but recommended you should fill in the hw->sectorCount field with the numberof sectors. This field is used to validate sectorrequests.An example of a initInterface function :\begin{lstlisting}esint16 if_initInterface(hwInterface *hw, euint8* opts){	/* Parse options */	parse_options(opts); /* Your application may not need options */	/* Check hardware state */	if(!alive(hw->pigeon)){		//printf("Pigeon died! :-(\n");		return(DEAD_PIGEON); /* #define DEAD_PIGEON -1 */	}	/* Initialize hardware */	feed(hw->pigeon);	pet (hw->pigeon);	/* Get sectors count */	hw->numSectors = ask_pigeon_num_sectors(hw->pigeon);	return(0);}\end{lstlisting}\subsubsection{if\_readBuf}This function is responsible to read a sector from the disc and store it in a user supplied buffer. You will receive the hardware object, an address and a pointer to memory for storingthe buffer.Please be very careful to respect the boundaries of the buffers, since it will usually be IOMancalling this function, and if you have a buffer overflow you might corrupt the cache of thethe next buffer, which in turn may produce extremely rare and impossible to retrace behavior.The function prototype is:\\\code{esint16 if\_readBuf(hwInterface *hw,euint32 address, euint8* buf);}The address is an LBA address, relative to the beginning of the disc. Should you beaccessing an old hard disc, or a device which uses some other form of addressing you will have torecalculate the address to your own addressing scheme. Please note that there is no supportfor sectors that are not 512 bytes large.\begin{lstlisting}esint8 if_readBuf(hwInterface* hw,euint32 address,euint8* buf){	Message new_message;	new_message.address = address;	new_message.command = READ;	pigeon_send(hw->pigeon,new_message); /* Launches the pigeon */	while(!pigeon_returned(hw->pigeon)); /* Wait until the bird is back */	memcpy(new_message.data,buf,512); /* Copy buffer */	return(0);}\end{lstlisting}\subsubsection{if\_writeBuf}The function \code{if\_writeBuf} works exactly the same as it's reading variant.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -