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.

FAXLIB: a question on critical section in fiuContext

FAXLIB, FIU module needs fiuContext_t fiuContext global variable set to operate.

Among other fields, fiuContext_t type has two pointers to functions: faxCriticalSectionBegin and faxCriticalSectionEnd. These pointers should be assigned to "externally supplied system function that suspends preemption of FIU processing". However, example code has empty implementation of these functions.

What kind of critical section FIU module requires? Right now, I used TSK_disable/TSK_enable for critical section and my code works, but what is exact use of these functions in FIU and what implementation is expected?

It'll be also very helpful if one could describe the meaning of other fields in fiuContext_t, because the use of external memory pool in FIU is neither explained in documentation nor present in demo code. Currently, I had to assign NULL or 0 to fields related to external buffers, because memory requirements are not clear for me.

  • The fiuContext_t is explained infiusim.c:

    00207 fiuContext_t fiuContext = {
    00208    NULL,                    /* Global allocBuffer function - external buffering not implemented */
    00209    NULL,                    /* Global freeBuffer function  - external buffering not implemented */
    00210    0,                       /* SupportedExternalBuffSize - external buffering not implemented */
    00211    siuGetTime,              /* Timer function pointer */
    00212    siuDebugInfo,            /* Debug function pointer */
    00213    siuCriticalSectionBegin, /* Critical section Begin macro */
    00214    siuCriticalSectionEnd    /* Critical section End macro */
    00215 };
    00216

    allocBuffer
    This is a function pointer to an externally supported routine that allocates a data buffer from a global memory pool  for use by the FIU.  If an external pool is unsupported, set this to NULL. 

    Prototype:   void* (*allocBuffer) (tuint MID)
    Description: Allocates a fax buffer from an external global memory pool.  The return address is a pointer to the allocated memory buffer, and shall be NULL if the allocation failed.  The parameter MID is a user-specified module ID.

    freeBuffer
    This is a function pointer to an externally supported routine that frees a data buffer no longer in use by FIU.  The data buffer is returned to the external memory pool.  If an external pool is unsupported, set this to NULL. 

    Prototype:   tbool (*freeBuffer) (tuint MID, void *gmp_gmc)
    Description: This function callout releases a fax buffer to an external global memory pool.  The void *gmp_gmc parameter is a pointer to the memory buffer to be freed.  The parameter MID is a user-specified module ID.

    faxCriticalSectionBegin
    Callout to externally supplied system function that suspends preemption of FIU processing.  This is a function pointer and must point to a valid function location who meets the API requirements. 

    Prototype:   void (*faxCriticalSectionBegin) (void)
    Description: Callout to an external function that prevents an FIU routine from being preempted.  Always followed by a call to faxCriticalSectionEnd().

    faxCriticalSectionEnd
    Callout to externally supplied system function that suspends preemption of FIU processing. This is a function pointer and must point to a valid function location who meets the API requirements.  See section 5.1.4.6 for more information.
    Prototype:   void (*faxCriticalSectionEnd) (void)
    Description: Callout to an external function that re-enables preemption of FIU  processing.  Always preceded by a call to faxCriticalSectionBegin().

    Since we only do the unit test in the package, so we didn't provide all the function implmentation.

    Regards, Eric

  • Hello Eric,
    thank you for reply.

    I see, you have NULL for allocBuffer, freeBuffer and 0 for SupportedExternalBuffSize and this is exactly what I have.
    My code works with these settings, however, I'd like to know, how one could implement external buffering. So, I need at least the following information:
    what external buffers are used for (and what memory is used if they're not implemented (current scenario)),
    what are requirements for external buffers (size, alignment, placement, etc.),
    what is argument for allocBuffer and how to determine, how much memory to allocate

    Regarding faxCriticalSectionBegin, faxCriticalSectionEnd, I see your citation "Callout to externally supplied system function that suspends preemption of FIU processing", but it's still not clear for me, what kind of protection is required for that. I see, you refer to section 5.1.4.6. Could you kindly say, what document are you referring to, please? I have faxlib 2.1.0.1 for C64P installed on my PC.
    Could you kindly mention, please, what functions use this critical section and what can cause preemption?
    For an instance, I call fiuTask from some BIOS task and I know that task can not be preempted by other tasks during call to fiuTask, but can be preempted by HWI and SWI (for a short period of time, of course). Should I take care about critical section?
  • In user guide:

    Global context initialization

    "Note that the supported external buffer size should be at least 22 words if an external global memory buffer pool is supported." I didn't see any info regarding to alignment and placement.

    In the fax processing task, if you don't want your task pre-empt by other interrupt, you need implement critical section begin, after you task, then do critical section end. "5.1.4.6" is a typo, not in the faxlib package.

    In critical section start: Save current interrupt enable/disable status, and disable all interrupts. Bit ST1_INTM is pushed in global variable. IER0 and IER1 are saved and restored.

    In critical section end: Restore interrupt enable/disable status encountered on entry to critical section. Bit ST1_INTM is poped from the global variable.

    Regards, Eric