This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: FLASH operation lock interrupt issue

Part Number: TDA4VM


In the MCAL+AUTOSAR BSW software using TDA4, we found that the processJobs function driven by flash did a lock interrupt operation during the operation of the flash. Due to the time-consuming FLASH operation, the interrupt and task scheduling were blocked.

May I ask: 1. What is the purpose of the lock interrupt?

2. If I can ensure the serializability of flash operations (as well as the serializability of the bus used by flash) in the upper layer application, can I remove the lock interrupt operation?

3. Or what better way to solve the problem.

The following are the relevant codes:

FLS_FUNC_TEXT_SECTION void processJobs(Fls_JobType job)
{
    uint32 chunkSize;
    Std_ReturnType retVal = E_NOT_OK;
    /*Get the MIN of two*/
    if (Fls_DrvObj.length < Fls_DrvObj.jobChunkSize)
    {
        chunkSize = Fls_DrvObj.length;
    }
    else
    {
        chunkSize = Fls_DrvObj.jobChunkSize;
    }

    SchM_Enter_Fls_FLS_EXCLUSIVE_AREA_0();

    switch(job) {
        case FLS_JOB_COMPARE:
            retVal = Fls_norCompare(chunkSize);
            break;
        case FLS_JOB_ERASE:
            retVal = Fls_norErase(chunkSize);
            break;
        case FLS_JOB_READ:
            retVal = Fls_norRead(chunkSize);
            break;
        case FLS_JOB_WRITE:
            retVal = Fls_norWrite(chunkSize);
            break;
        case FLS_JOB_BLANKCHECK:
            retVal = Fls_norBlankCheck(chunkSize);
            break;
        default:
            retVal = E_NOT_OK;
            break;
    }

    if (retVal == E_OK)
    {
        Fls_DrvObj.ramAddr = &Fls_DrvObj.ramAddr[chunkSize];
        if (job != FLS_JOB_ERASE)
        {
            Fls_DrvObj.flashAddr += chunkSize;
            /*Erase FlashAddr updated in Fls_norErase*/
        }
        Fls_DrvObj.length -= chunkSize;
        Fls_DrvObj.transferred += chunkSize;

        if( 0U == Fls_DrvObj.length )
        {
            Fls_DrvObj.jobResultType = MEMIF_JOB_OK;
            Fls_DrvObj.status = MEMIF_IDLE;
            Fls_DrvObj.jobType = FLS_JOB_NONE;
            Fls_DrvObj.transferred = 0;
            if( Fls_DrvObj.Fls_JobEndNotification != NULL )
            {
                Fls_DrvObj.Fls_JobEndNotification();
            }
        }
    }
    else /*if retval == E_NOT_OK or E_COMPARE_MISMATCH*/
    {
        if ((E_BLANKCHECK_MISMATCH == retVal) || (E_COMPARE_MISMATCH == retVal))
        {
            Fls_DrvObj.status = MEMIF_IDLE;
            Fls_DrvObj.jobType = FLS_JOB_NONE;
            Fls_DrvObj.transferred = 0;
            if (FLS_JOB_BLANKCHECK == job)
            {
                Fls_reportDetRuntimeError(FLS_SID_BLANK_CHECK, FLS_E_VERIFY_ERASE_FAILED);
            }
            else /*if (FLS_JOB_COMPARE == job)*/
            {
                Fls_DrvObj.jobResultType = MEMIF_BLOCK_INCONSISTENT;
                Fls_reportDetRuntimeError(FLS_SID_COMPARE, FLS_E_VERIFY_WRITE_FAILED);
            }
            if( Fls_DrvObj.Fls_JobErrorNotification != NULL )
            {
                Fls_DrvObj.Fls_JobErrorNotification();
            }
        }
        else /*if retVal == E_NOT_OK*/
        {
            /*Hardware/driver internal error occured*/
            ReportFlsError(job);
            if( Fls_DrvObj.Fls_JobErrorNotification != NULL )
            {
                   Fls_DrvObj.Fls_JobErrorNotification();
            }
        }
    }

    SchM_Exit_Fls_FLS_EXCLUSIVE_AREA_0();

    return;
}

  • Hello,

    Hope you are pointing out SchM_Enter_Fls_FLS_EXCLUSIVE_AREA_0() and SchM_Exit_Fls_FLS_EXCLUSIVE_AREA_0() as lock interrupt operation.

    The implementation requires one level of exclusive access to guard critical sections as per AUTOSAR standards. Invokes SchM_Enter_Fls_FLS_EXCLUSIVE_AREA_0 (), SchM_Exit_Fls_FLS_EXCLUSIVE_AREA_0 () to enter critical section and exit.

    In the example implementation (SchM_Fls.c) , all the interrupts on CPU are disabled. However, disabling of the enabled Fls interrupt should suffice.

    Regards

    Tarun Mukesh

  • Hello,

    The current project found that the Flash interruption time caused by the long erasing time is long (the SchM_Enter_Fls_FLS_EXCLUSIVE_AREA_0 mentioned in the code),
    Will reducing the subsector from 4KB size (#define NOR_SECTOR_SIZE (4U * 1024U)) to 2KB size shorten the time of single-cycle erase,
    Whether this method is feasible, or is there any way to shorten the erase time of a single cycle

  • Hello,

    The sector size is based on FLASH device and it cannot be modified .The Erase operation happens sector wise.

    As i mentioned 

    SchM_Fls.c

    all the interrupts on CPU are disabled in the example. You can modify it by disabling  the enabled Fls interrupts alone.

    Regards

    Tarun Mukesh

  • How to  disable  the enabled Fls interrupts alone? Use which function?TY

  • Hello,

    Currently we have 

    HwiP_disable() API being used .
    You can use below API to disable a particular interrupt
    You have  modify it by disabling all the enabled Fls interrupts.The Upper layer has to take care of it.
    Regards
    Tarun MUkesh