Jelajahi Sumber

update:优化TF卡U盘模式下,PC对TF的写入速度

alienwalker 3 tahun lalu
induk
melakukan
3db53529ff

+ 14 - 0
application/src/luat_spi_air105.c

@@ -297,8 +297,14 @@ static void sdhc_spi_check(luat_fatfs_spi_t* userdata)
 
 static DSTATUS sdhc_spi_initialize(luat_fatfs_spi_t* userdata)
 {
+	int i;
 	if (luat_fatfs_spi_ctrl)
 	{
+		for(i = 0; i < USB_MAX; i++)
+		{
+			Core_UDiskDetachSDHC(i, luat_fatfs_spi_ctrl);
+		}
+		SDHC_SpiRelease(luat_fatfs_spi_ctrl);
 		free(luat_fatfs_spi_ctrl);
 		luat_fatfs_spi_ctrl = NULL;
 	}
@@ -310,6 +316,14 @@ static DSTATUS sdhc_spi_initialize(luat_fatfs_spi_t* userdata)
 	}else{
 		SPI_SetNewConfig(luat_spi[userdata->spi_id].id, userdata->fast_speed, 0);
 	}
+	if (SDHC_IsReady(luat_fatfs_spi_ctrl))
+	{
+		for(i = 0; i < USB_MAX; i++)
+		{
+			Core_UDiskAttachSDHCRecovery(i, luat_fatfs_spi_ctrl);
+		}
+	}
+
 	return SDHC_IsReady(luat_fatfs_spi_ctrl)?0:STA_NOINIT;
 }
 

+ 1 - 1
application/src/luat_usb_app_air105.c

@@ -78,5 +78,5 @@ void luat_usb_udisk_attach_sdhc(uint8_t usb_id)
 
 void luat_usb_udisk_detach_sdhc(uint8_t usb_id)
 {
-	Core_UDiskDetachSDHC(usb_id);
+	Core_UDiskDetachSDHC(usb_id,  NULL);
 }

+ 3 - 1
bsp/air105/test/test_sdcard.c

@@ -26,7 +26,9 @@ void prvSDHC_Test(void *p)
     GPIO_Iomux(GPIOC_15,2);
     GPIO_Config(SDHC.CSPin, 0, 1);
     SPI_MasterInit(SDHC.SpiID, 8, SPI_MODE_0, 400000, NULL, NULL);
-
+#ifdef __BUILD_OS__
+    SDHC.RWMutex = OS_MutexCreateUnlock();
+#endif
     SDHC_SpiInitCard(&SDHC);
     if (SDHC.IsInitDone)
     {

+ 2 - 0
bsp/common/include/core_service.h

@@ -81,4 +81,6 @@ void Core_VHIDUploadStop(uint8_t USB_ID);
 uint32_t Core_VHIDRxBufferRead(uint8_t USB_ID, uint8_t *Data, uint32_t Len);
 
 void Core_UDiskAttachSDHC(uint8_t USB_ID, void *pCtrl);
+void Core_UDiskDetachSDHC(uint8_t USB_ID, void *pCtrl);
+void Core_UDiskAttachSDHCRecovery(uint8_t USB_ID, void *pCtrl);
 #endif

+ 1 - 1
bsp/common/src/core_task.c

@@ -232,7 +232,7 @@ GET_NEW_EVENT:
 	}
 	if (Callback)
 	{
-		Callback(OutEvent, NULL);
+		Callback(OutEvent, TaskHandle);
 	}
 	goto GET_NEW_EVENT;
 WAIT_NEW_EVENT:

+ 57 - 14
bsp/common/src/core_usb_app.c

@@ -90,6 +90,8 @@ typedef struct
 	HANDLE hTaskHandle;
 	uint8_t *pHIDReport;
 	uint16_t HIDReportLen;
+	uint8_t IsUSBAttachSDHC;
+	uint8_t IsStart;
 }USB_AppCtrlStruct;
 
 static const uint8_t prvCore_StandardInquiryData[STANDARD_INQUIRY_DATA_LEN] =
@@ -860,6 +862,8 @@ void Core_USBDefaultDeviceStart(uint8_t USB_ID)
 {
 	uint8_t langid[2] = {0x09, 0x04};
 	int i;
+	USB_StackPowerOnOff(USB_ID, 1);
+	USB_StackStop(USB_ID);
 	prvLuatOS_VirtualHID.USB_ID = USB_ID;
 	prvLuatOS_VirtualHID.IsReady = 0;
 	prvLuatOS_VirtualHID.ToHostEpIndex = DEVICE_HID_KEYBOARD_EP_IN;
@@ -883,8 +887,7 @@ void Core_USBDefaultDeviceStart(uint8_t USB_ID)
 		prvLuatOS_VirtualHID.CB = prvCore_VHIDDummyCB;
 	}
 	OS_ReInitBuffer(&prvLuatOS_VirtualHID.TxCacheBuf, VIRTUAL_VHID_BUFFER_LEN);
-	USB_StackPowerOnOff(USB_ID, 1);
-	USB_StackStop(USB_ID);
+
 	USB_StackClearSetup(USB_ID);
 	USB_StackSetDeviceBusPower(USB_ID, 1);
 	USB_StackSetEpCB(USB_ID, 0, prvCore_USBEp0CB, NULL);
@@ -926,6 +929,7 @@ void Core_USBDefaultDeviceStart(uint8_t USB_ID)
 	USB_MSCReset(&prvUSBApp.tSCSI);
 
 	USB_StackStartDevice(USB_ID);
+	prvUSBApp.IsStart = 1;
 }
 
 
@@ -1288,31 +1292,70 @@ void Core_USBAction(uint8_t USB_ID, uint8_t Action, void *pParam)
 extern const USB_StorageSCSITypeDef prvSDHC_SCSIFun;
 void Core_UDiskAttachSDHC(uint8_t USB_ID, void *pCtrl)
 {
-	if (!prvUSBApp.pSDHC)
-	{
-		prvUSBApp.pSDHC = malloc(sizeof(SDHC_SPICtrlStruct));
-	}
-	memcpy(prvUSBApp.pSDHC, pCtrl, sizeof(SDHC_SPICtrlStruct));
+	prvUSBApp.pSDHC = pCtrl;
 	prvUSBApp.tSCSI.pSCSIUserFunList = &prvSDHC_SCSIFun;
 	prvUSBApp.tSCSI.pUserData = prvUSBApp.pSDHC;
 	prvUSBApp.tSCSI.ReadTimeout = 500;
 	DBuffer_ReInit(&prvUSBApp.DataBuf, 8 * 1024);
 	prvUSBApp.pSDHC->USBDelayTime = 0;	//如果USB不稳定,可调加大USBDelayTime
 	prvUSBApp.pSDHC->SCSIDataBuf = &prvUSBApp.DataBuf;
+	prvUSBApp.IsUSBAttachSDHC = 1;
+}
+
+void Core_UDiskAttachSDHCRecovery(uint8_t USB_ID, void *pCtrl)
+{
+	if (prvUSBApp.IsUSBAttachSDHC)
+	{
+		DBG("recovery attach %d, %x", USB_ID, pCtrl);
+		prvUSBApp.pSDHC = pCtrl;
+		prvUSBApp.tSCSI.pSCSIUserFunList = &prvSDHC_SCSIFun;
+		prvUSBApp.tSCSI.pUserData = prvUSBApp.pSDHC;
+		prvUSBApp.tSCSI.ReadTimeout = 500;
+		DBuffer_ReInit(&prvUSBApp.DataBuf, 8 * 1024);
+		prvUSBApp.pSDHC->USBDelayTime = 0;	//如果USB不稳定,可调加大USBDelayTime
+		prvUSBApp.pSDHC->SCSIDataBuf = &prvUSBApp.DataBuf;
+		if (prvUSBApp.IsStart)
+		{
+			DBG("reboot usb");
+			Core_USBDefaultDeviceStart(USB_ID);
+		}
+	}
 }
 
-void Core_UDiskDetachSDHC(uint8_t USB_ID)
+void Core_UDiskDetachSDHC(uint8_t USB_ID, void *pCtrl)
 {
-	prvUSBApp.tSCSI.pSCSIUserFunList = &prvCore_SCSIFun;
-	prvUSBApp.tSCSI.pUserData = NULL;
-	free(prvUSBApp.pSDHC);
-	prvUSBApp.pSDHC = NULL;
-	DBuffer_DeInit(&prvUSBApp.DataBuf);
+	if (pCtrl)
+	{
+		if (prvUSBApp.pSDHC != pCtrl)
+		{
+			return;
+		}
+	}
+
+	if (prvUSBApp.IsUSBAttachSDHC)
+	{
+		prvUSBApp.tSCSI.pSCSIUserFunList = &prvCore_SCSIFun;
+		prvUSBApp.tSCSI.pUserData = NULL;
+		prvUSBApp.pSDHC = NULL;
+		DBuffer_DeInit(&prvUSBApp.DataBuf);
+		DBG("detach %d, %x", USB_ID, pCtrl);
+		if (!pCtrl)	//NULL表示用户退出
+		{
+			prvUSBApp.IsUSBAttachSDHC = 0;
+			DBG("free attach %d, %x", USB_ID, pCtrl);
+		}
+	}
+	if (prvUSBApp.IsStart)
+	{
+		DBG("reboot usb");
+		Core_USBDefaultDeviceStart(USB_ID);
+	}
+
 }
 
 void Core_USBAppGlobalInit(void)
 {
-	prvUSBApp.hTaskHandle = Task_Create(prvCore_USBAppTask, NULL,2 * 1024, USB_TASK_PRO, "usb app");
+	prvUSBApp.hTaskHandle = Task_Create(prvCore_USBAppTask, NULL, 1024, USB_TASK_PRO, "usb app");
 }
 
 INIT_TASK_EXPORT(Core_USBAppGlobalInit, "2");

+ 4 - 0
bsp/device/include/dev_sdhc_spi.h

@@ -102,8 +102,10 @@ typedef struct
 	uint64_t SDHCReadBlockTo;
 	uint64_t SDHCWriteBlockTo;
 	Buffer_Struct DataBuf;
+	Buffer_Struct CacheBuf;
 	HANDLE NotifyTask;						//设置了NotifyTask,则会在大量传输SPI数据时,休眠任务但是仍然能接收Event并在CB中处理
 	CBFuncEx_t TaskCB;
+	HANDLE RWMutex;
 	uint32_t Size;							//flash的大小KB
 	uint32_t OCR;
 	DBuffer_Struct *SCSIDataBuf;
@@ -126,6 +128,7 @@ typedef struct
 	uint8_t IsPrintData;
 	uint8_t IsMMC;
 	uint8_t USBDelayTime;
+	uint8_t WaitFree;
 }SDHC_SPICtrlStruct;
 
 
@@ -136,6 +139,7 @@ void SDHC_SpiReadCardInfo(void *pSDHC);
 void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums);
 void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums);
 void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin);
+void SDHC_SpiRelease(void *pSDHC);
 uint8_t SDHC_IsReady(void *pSDHC);
 uint32_t SDHC_GetLogBlockNbr(void *pSDHC);
 #endif

+ 104 - 23
bsp/device/src/dev_sdhc_spi.c

@@ -84,7 +84,7 @@ extern const uint8_t prvCore_MSCModeSense6data[MODE_SENSE6_LEN];
 /* USB Mass storage sense 10  Data */
 extern const uint8_t prvCore_MSCModeSense10data[MODE_SENSE10_LEN];
 
-
+static void prvSDHC_WriteBlocksBackground(void *pSDHC, void *pData);
 
 static int32_t prvSDHC_SCSIInit(uint8_t LUN, void *pUserData)
 {
@@ -217,36 +217,24 @@ static int32_t prvSDHC_SCSIPreWrite(uint8_t LUN, uint32_t BlockAddress, uint32_t
 	}
 	pSDHC->CurBlock = BlockAddress;
 	pSDHC->EndBlock = BlockAddress + BlockNums;
-	DBuffer_SetDataLen(pSDHC->SCSIDataBuf, 0, 1);
+	OS_ReInitBuffer(&pSDHC->CacheBuf, pSDHC->Info.LogBlockSize * BlockNums);
+
 	return 0;
 }
 
 static int32_t prvSDHC_SCSIWrite(uint8_t LUN, uint8_t *Data, uint32_t Len, void *pUserData)
 {
 	SDHC_SPICtrlStruct *pSDHC = pUserData;
+	void *pData;
 	if (!SDHC_IsReady(pSDHC)) return -1;
 	if (pSDHC->EndBlock <= pSDHC->CurBlock) return -1;
-	memcpy(DBuffer_GetCache(pSDHC->SCSIDataBuf, 1) + DBuffer_GetDataLen(pSDHC->SCSIDataBuf, 1), Data, Len);
-	DBuffer_SetDataLen(pSDHC->SCSIDataBuf, DBuffer_GetDataLen(pSDHC->SCSIDataBuf, 1) + Len, 1);
-	return ERROR_NONE;
-}
-
-static int32_t prvSDHC_SCSIDoWrite(uint8_t LUN, void *pUserData)
-{
-	SDHC_SPICtrlStruct *pSDHC = pUserData;
-	uint32_t WriteBlocks = DBuffer_GetDataLen(pSDHC->SCSIDataBuf, 1) >> 9;
-	if (pSDHC->EndBlock <= pSDHC->CurBlock) return -1;
-	if (WriteBlocks)
+	OS_BufferWrite(&pSDHC->CacheBuf, Data, Len);
+	if (pSDHC->CacheBuf.Pos >= pSDHC->CacheBuf.MaxLen)
 	{
-
-		if (WriteBlocks > (pSDHC->EndBlock - pSDHC->CurBlock))
-		{
-			WriteBlocks = pSDHC->EndBlock - pSDHC->CurBlock;
-		}
-		SDHC_SpiWriteBlocks(pSDHC, DBuffer_GetCache(pSDHC->SCSIDataBuf, 1), pSDHC->CurBlock, WriteBlocks);
-		DBuffer_SetDataLen(pSDHC->SCSIDataBuf, 0, 1);
+		pData = pSDHC->CacheBuf.Data;
+		memset(&pSDHC->CacheBuf, 0, sizeof(pSDHC->CacheBuf));
+		prvSDHC_WriteBlocksBackground(pSDHC, pData);
 	}
-	pSDHC->CurBlock += WriteBlocks;
 	return ERROR_NONE;
 }
 
@@ -272,7 +260,6 @@ const USB_StorageSCSITypeDef prvSDHC_SCSIFun =
 		prvSDHC_SCSIReadNext,
 		prvSDHC_SCSIPreWrite,
 		prvSDHC_SCSIWrite,
-		prvSDHC_SCSIDoWrite,
 		prvSDHC_SCSIUserCmd,
 		&prvSDHC_StandardInquiryData,
 		&prvCore_MSCPage00InquiryData,
@@ -853,6 +840,13 @@ void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t B
 	uint8_t Retry = 0;
 	uint8_t error = 1;
 	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+#ifdef __BUILD_OS__
+	if (OS_MutexLockWtihTime(Ctrl->RWMutex, 1000))
+	{
+		DBG("mutex wait timeout!");
+		return;
+	}
+#endif
 	Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
 SDHC_SPIREADBLOCKS_START:
 	if (SDHC_SpiCmd(Ctrl, CMD18, StartLBA + Ctrl->DataBuf.Pos, 0))
@@ -900,11 +894,17 @@ SDHC_SPIREADBLOCKS_CHECK:
 		}
 		goto SDHC_SPIREADBLOCKS_START;
 	}
+#ifdef __BUILD_OS__
+	OS_MutexRelease(Ctrl->RWMutex);
+#endif
 	return;
 SDHC_SPIREADBLOCKS_ERROR:
 	DBG("!");
 	Ctrl->IsInitDone = 0;
 	Ctrl->SDHCError = 1;
+#ifdef __BUILD_OS__
+	OS_MutexRelease(Ctrl->RWMutex);
+#endif
 	return;
 }
 
@@ -912,6 +912,13 @@ void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uin
 {
 	uint8_t Retry = 0;
 	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+#ifdef __BUILD_OS__
+	if (OS_MutexLockWtihTime(Ctrl->RWMutex, 1000))
+	{
+		DBG("mutex wait timeout!");
+		return;
+	}
+#endif
 	Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
 SDHC_SPIREADBLOCKS_START:
 	if (SDHC_SpiCmd(Ctrl, CMD25, StartLBA + Ctrl->DataBuf.Pos, 0))
@@ -933,11 +940,17 @@ SDHC_SPIREADBLOCKS_START:
 		}
 		goto SDHC_SPIREADBLOCKS_START;
 	}
+#ifdef __BUILD_OS__
+	OS_MutexRelease(Ctrl->RWMutex);
+#endif
 	return;
 SDHC_SPIREADBLOCKS_ERROR:
 	DBG("!");
 	Ctrl->IsInitDone = 0;
 	Ctrl->SDHCError = 1;
+#ifdef __BUILD_OS__
+	OS_MutexRelease(Ctrl->RWMutex);
+#endif
 	return;
 }
 
@@ -947,11 +960,27 @@ void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin)
 	Ctrl->CSPin = CSPin;
 	Ctrl->SpiID = SpiID;
 	Ctrl->SDHCReadBlockTo = 50 * CORE_TICK_1MS;
-	Ctrl->SDHCWriteBlockTo = 250 * CORE_TICK_1MS;
+	Ctrl->SDHCWriteBlockTo = 50 * CORE_TICK_1MS;
+#ifdef __BUILD_OS__
+	Ctrl->RWMutex = OS_MutexCreateUnlock();
+#endif
 //	Ctrl->IsPrintData = 1;
+
 	return Ctrl;
 }
 
+void SDHC_SpiRelease(void *pSDHC)
+{
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	OS_DeInitBuffer(&Ctrl->CacheBuf);
+#ifdef __BUILD_OS__
+	OS_MutexRelease(Ctrl->RWMutex);
+	Ctrl->WaitFree = 1;
+	Task_DelayMS(100);
+#endif
+	DBG("free %x", pSDHC);
+}
+
 uint32_t SDHC_GetLogBlockNbr(void *pSDHC)
 {
 	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
@@ -972,3 +1001,55 @@ uint8_t SDHC_IsReady(void *pSDHC)
 	}
 }
 
+#ifdef __BUILD_OS__
+
+static HANDLE prvTask;
+
+enum
+{
+
+	SDHC_WRITE = USB_APP_EVENT_ID_START + 1,
+};
+
+static void prvSDHC_Task(void* params)
+{
+	OS_EVENT Event;
+	uint32_t *Param;
+	SDHC_SPICtrlStruct *pSDHC;
+	while(1)
+	{
+		Task_GetEventByMS(prvTask, CORE_EVENT_ID_ANY, &Event, NULL, 0);
+		switch(Event.ID)
+		{
+		case SDHC_WRITE:
+			pSDHC = (SDHC_SPICtrlStruct *)Event.Param1;
+			if (pSDHC->WaitFree)
+			{
+				DBG("sdhc wait reboot");
+				free(Event.Param2);
+				free(Event.Param3);
+				break;
+			}
+			Param = (uint32_t *)Event.Param3;
+			SDHC_SpiWriteBlocks(pSDHC, Event.Param2, Param[0], Param[1]);
+			free(Event.Param2);
+			free(Event.Param3);
+			break;
+		}
+	}
+}
+
+static void prvSDHC_WriteBlocksBackground(void *pSDHC, void *pData)
+{
+	uint32_t *Param = malloc(8);
+	Param[0] =((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
+	Param[1] = ((SDHC_SPICtrlStruct *)pSDHC)->EndBlock - ((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
+	Task_SendEvent(prvTask, SDHC_WRITE, pSDHC, pData, Param);
+}
+
+void SDHC_TaskInit(void)
+{
+	prvTask = Task_Create(prvSDHC_Task, NULL, 1024, SERVICE_TASK_PRO, "sdhc task");
+}
+INIT_TASK_EXPORT(SDHC_TaskInit, "2");
+#endif

+ 0 - 1
bsp/usb/include/usb_msc.h

@@ -136,7 +136,6 @@ typedef struct
 	int32_t (* ReadNext)(uint8_t LUN, void *pUserData);
 	int32_t (* PreWrite)(uint8_t LUN, uint32_t BlockAddress, uint32_t BlockNums, void *pUserData);
 	int32_t (* Write)(uint8_t LUN, uint8_t *Data, uint32_t Len, void *pUserData);
-	int32_t (* DoWrite)(uint8_t LUN, void *pUserData);
 	int32_t (* UserCmd)(USB_EndpointDataStruct *pEpData, MSC_SCSICtrlStruct *pMSC);
 	void *pStandardInquiry;
 	void *pPage00InquiryData;

+ 0 - 1
bsp/usb/src/core_usb_class_msc_scsi.c

@@ -298,7 +298,6 @@ static void prvUSB_SCSIHandleToDeviceData(USB_EndpointDataStruct *pEpData, MSC_S
 	{
 		prvUSB_SendCSW(pEpData, pMSC);
 	}
-	pUserFun->DoWrite(pMSC->CBW.bLUN, pMSC->pUserData);
 }
 
 static void prvUSB_SCSIHandleToHostData(USB_EndpointDataStruct *pEpData, MSC_SCSICtrlStruct *pMSC)