vxworks的cache一致性問題分析

  1. dosFs文件系統
    1. 初始化dosfs文件系統庫

在用戶執行任何文件操作之前,必須先初始化dosFs文件系統庫。當在道6下包含了文件系統的組件後,這個初始化的過程就是自動執行的了。文件系統初始化庫函數一般在prjConfig.c文件中,調用過程爲:usrIosExtraInit--->usrDosfsInit()---->dosFsInit()----->dosFsLibInit()。

在初始化文件系統庫的過程中,會調用iosDrvInstall()函數註冊驅動程序到I/O系統的驅動程序表中,返回值爲驅動號,保存在全局變量dosFsDrvNum中。驅動程序表中保存着使用dosFs文件系統操作文件的函數指針。iosDrvInstall原型如下:

int iosDrvInstall

    (

    FUNCPTR pCreate,    /* pointer to driver create function */

    FUNCPTR pRemove,    /* pointer to driver remove function */

    FUNCPTR pOpen,      /* pointer to driver open function */

    FUNCPTR pClose,     /* pointer to driver close function */

    FUNCPTR pRead,      /* pointer to driver read function */

    FUNCPTR pWrite,     /* pointer to driver write function */

    FUNCPTR pIoctl      /* pointer to driver ioctl function */

    )

    1. 創建塊存取設備

此步驟可調用設備驅動功能函數創建相應的設備。函數名稱格式是xxxDevCreate(),xxx表示設備驅動程序的類型,如:xbdRamDiskDevCreate(),三代臺中瀏覽器模塊需要”/”和”/tmp”設備存儲一些用戶數據,設備的創建和格式化代碼如下:

int32_t  deviceId;

    deviceId = xbdRamDiskDevCreate

                (

                512,                /* number of bytes per block */

                20480 * 512,   /* number of bytes on this device */

                FALSE,

                "/"

                );

        if (deviceId == NULL)

            {

            printf("usbTargRbcBlockDevCreated:"

                   "ramDiskDevCreate returned NULL\n");



            return(ERROR);

            }

        /* format the RAM disk, ignore memory contents */



        if (dosFsVolFormat("/",

                           DOS_OPT_BLANK | DOS_OPT_QUIET | DOS_OPT_FAT16,

                           NULL) != OK)

            {

                  return ERROR;

            }
    1. 創建和使用磁盤分區

可以通過調用dcacheDevCreate()函數爲每一個塊存取設備創建磁盤cache高速緩衝區。原型如下:

CBIO_DEV_ID dcacheDevCreate

    (

    CBIO_DEV_ID  subDev,  /* block device handle */

    char  *   pRamAddr,   /* where it is in memory (NULL = KHEAP_ALLOC)  */

    int       memSize,    /* amount of memory to use */

    char *    pDesc       /* device description string */

    )

在宏INCLUDE_DISK_PART被定義後,可以通過調用usrFdiskPartCreate()和dpartDevCreate()函數在磁盤上創建分區。如下代碼所示,創建了cache緩衝,創建3個分區和dosfs文件系統設備並調用dosFsVolFormat()對其中一個分區進行格式化,該函數需要指定文件分配表(FAT)的格式和目錄的格式兩個參數。

CBIO_DEV_ID cbio, cbio1 ;

Int dcacheSize = 0x30000;

//創建磁盤緩衝區

if( (cbio = dcacheDevCreate(blkDevId, NULL, dcacheSize,”/sd0”)) == NULL)

return ERROR;

//創建3個分區,最多可以創建4個

usrFdiskPartCreate(cbio, 3, 50, 45);

if( (cbio1  = dpartDevCreate(cbio, 3, usrFdiskPartRead)) == NULL)

return ERROR;

//創建dosfs文件系統設備

if(dosFsDevCreate(“/sd0a”, dpartPartGet(cbio1, 0), 0x20, 0) == ERROR)

return ERROR;

if(dosFsVolFormat(“/sd0a”, DOS_OPT_BLANK | DOS_OPT_QUIET | DOS_OPT_FAT16, NULL) == ERROR)

return ERROR;

 

磁盤卷的文件分配表格式是在格式化過程中指定的。通過傳遞給dosFsVolFormat()函數參數來確定文件分配表格式。

FAT16:簇號用16bit表示,用於簇個數少於65524的磁盤;

FAT32:簇號用32bit表示,用於簇個數少於2^32-12的磁盤;

1.4磁盤卷的一致性問題

DOS文件系統容易受到磁盤更新過程中斷而導致的數據結構不一致的影響,它是一個不考慮容錯性能的文件系統。DOS文件系統包含一個可選的集成的一致性檢測機制,可以檢測文件的不一致性,並從不一致性狀態中復原。要是用一致性檢測機制,需要手動在dosFsDevCreate()函數中第四個參數添加自動檢測參數,參數爲0表示添加自動檢測機制,爲-1表示不執行自動檢測並強制執行copyback操作。或者調用chkdsk()函數。需要注意的是,一致性檢測機制會使系統訪問速度降低,特別是第一次訪問磁盤時。

STATUS dosFsDevCreate

    (

    char *    pDevName,            /* device name */

    device_t  device,              /* underlying XBD block device */

    u_int     maxFiles,            /* max no. of simultaneously open files */

    int       dosDevCreateOptions  /* write option & volume integrity */

    )

2.Cache一致性問題

Cache一致性問題是指高速緩衝存儲器中的數據必須與內存中的數據保持同步(一致) , 這個問題常發生在CPU內核與另一個設備異步訪問內存時。

高速緩衝存儲器可以工作在Write-through或copyback模式。

write through:CPU向cache寫入數據時,同時向memory(後端存儲)也寫一份,使cache和memory的數據保持一致。優點是簡單,缺點是每次都要訪問memory,速度比較慢。但該模式卻無法解決輸入時的高速緩衝存儲器一致性問題。

Copyback:系統只寫數據到高速緩衝存儲器中,因此對於數據輸入和輸出都存在高速緩衝存儲器一致性問題。

VxWorks下通常有兩種方法解決高速緩衝存儲器一致性問題。

1)Cache-safe buffer(即non-cacheable  的buffer):CPU讀數據會直接從內存讀物而不是從CACHE讀取,CPU寫數據會直接寫入內存和cache中。

方案可通過以下方法實現:

在內存段屬性中定義此段buffer,空間屬性爲non-cacheable; 在內存管理單元MMU支持下,用cache DmaMalloc()/cache DmaFree()獲得此段buffer。則此段buffer是non-cacheable的(注意無MMU時 )。

2)對於cacheabale的buffer,採用cacheFlush()/cacheInvalidate()或者宏定義CACHE_DMA_FLUSH()/CACHE_DMA_INVALIDATE()來操作此buffer空間。Cacheflush()將緩存內容寫入內存,cacheInvalidate()將內存數據寫入緩存器。這兩個函數可以保證內存和緩存器的數據保持一致。

發佈了28 篇原創文章 · 獲贊 19 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章