本帖最后由 kokoromi 于 2019-5-16 08:38 编辑
项目中需要使用439的的HASH模块计算文件的MD5值,使用的DMA方式,为了提高CPU效率,让其他任务在DMA传输数据、硬件计算MD5期间可以得到运行,DMA的数据来自FMC外扩的SDRAM。
现在的问题是,经过多次调试发现,启动DMA传输后 CPU貌似没运行代码,而是等DMA传输和计算都完成了之后才运行后面的代码,我使用时间戳功能测量了函数 HAL_HASH_MD5_Start_DMA 的运行时间,得到的时间就是DMA传入数据和MD5计算的时间,也就是说,这个函数里面启动了DMA传输后 程序就停了,等整个MD5都计算完了才从这个函数中出来,很是费解,我看了下总线矩阵,也没冲突的地方啊,为什么会出现这个情况...有人知道吗?
下面的是HAL的程序,我在里面加入了测量时间功能,86-89行是我指出的有问题的地方:
- HAL_StatusTypeDef HASH_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
- {
- uint32_t inputaddr;
- uint32_t inputSize;
- HAL_StatusTypeDef status ;
- HAL_HASH_StateTypeDef State_tmp = hhash->State;
-
- #if defined (HASH_CR_MDMAT)
- /* Make sure the input buffer size (in bytes) is a multiple of 4 when MDMAT bit is set
- (case of multi-buffer HASH processing) */
- assert_param(IS_HASH_DMA_MULTIBUFFER_SIZE(Size));
- #endif /* MDMA defined*/
- /* If State is ready or suspended, start or resume polling-based HASH processing */
- if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
- {
- /* Check input parameters */
- if ( (pInBuffer == NULL ) || (Size == 0U) ||
- /* Check phase coherency. Phase must be
- either READY (fresh start)
- or PROCESS (multi-buffer HASH management) */
- ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HASH_PROCESSING(hhash)))))
- {
- hhash->State = HAL_HASH_STATE_READY;
- return HAL_ERROR;
- }
-
-
- /* Process Locked */
- __HAL_LOCK(hhash);
-
- /* If not a resumption case */
- if (hhash->State == HAL_HASH_STATE_READY)
- {
- /* Change the HASH state */
- hhash->State = HAL_HASH_STATE_BUSY;
-
- /* Check if initialization phase has already been performed.
- If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
- API is processing a new input data message in case of multi-buffer HASH
- computation. */
- if(hhash->Phase == HAL_HASH_PHASE_READY)
- {
- /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
- MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
-
- /* Set the phase */
- hhash->Phase = HAL_HASH_PHASE_PROCESS;
- }
-
- /* Configure the Number of valid bits in last word of the message */
- __HAL_HASH_SET_NBVALIDBITS(Size);
-
- inputaddr = (uint32_t)pInBuffer; /* DMA transfer start address */
- inputSize = Size; /* DMA transfer size (in bytes) */
-
- /* In case of suspension request, save the starting parameters */
- hhash->pHashInBuffPtr = pInBuffer; /* DMA transfer start address */
- hhash->HashInCount = Size; /* DMA transfer size (in bytes) */
-
- }
- /* If resumption case */
- else
- {
- /* Change the HASH state */
- hhash->State = HAL_HASH_STATE_BUSY;
-
- /* Resumption case, inputaddr and inputSize are not set to the API input parameters
- but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
- processing was suspended */
- inputaddr = (uint32_t)hhash->pHashInBuffPtr; /* DMA transfer start address */
- inputSize = hhash->HashInCount; /* DMA transfer size (in bytes) */
-
- }
-
- /* Set the HASH DMA transfert complete callback */
- hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
- /* Set the DMA error callback */
- hhash->hdmain->XferErrorCallback = HASH_DMAError;
-
- /* Store number of words already pushed to manage proper DMA processing suspension */
- hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
-
- /* Enable the DMA In DMA Stream */
- status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (((inputSize %4U)!=0U) ? ((inputSize+(4U-(inputSize %4U)))/4U):(inputSize/4U)));
-
- sts = OS_TS_GET(); //获取时间戳;
- /* Enable DMA requests */
- SET_BIT(HASH->CR, HASH_CR_DMAE); //就是这一句,执行完这一句按理说程序应该继续往下执行,但是实际上经过时间戳的测量,执行完这句耗费了约 4ms,这个时间正好是DMA传输数据+MD5的计算时间。
- ets = OS_TS_GET() - sts; //计算耗费的时间
-
- /* Process Unlock */
- __HAL_UNLOCK(hhash);
-
- /* Return function status */
- if (status != HAL_OK)
- {
- /* Update HASH state machine to error */
- hhash->State = HAL_HASH_STATE_ERROR;
- }
- else
- {
- /* Change HASH state */
- hhash->State = HAL_HASH_STATE_READY;
- }
-
- return status;
- }
- else
- {
- return HAL_BUSY;
- }
- }
复制代码
|
M0~M4 的DMA我都用过, 没发现过有你说的问题
评分
查看全部评分
我其他外设的DMA用着都没问题,就AHB2总线上的加密和哈西处理器由这个问题。