This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

What assumption does this code make? Is it acceptable?

This is a snippet from a general-purpose library function that is (effectively) non-application specific and, by design, can make no assumptions about the context of the calling process.

Hint: The assumption the code makes has to do with interrupts. Do you see a problem?

_GenericFunctionA:
    MOV   A, R7
    RL    A
    ADD   A, #array_base
    MOV   R0, A
    CLR   EA
    MOV   A, @R0
    JNB   ACC.BIT_X, ?C0026
    JNB   ACC.BIT_Y, ?C0026
    SETB  ACC.BIT_Z
?C0026:
    SETB  ACC.BIT_N
    XCH   A, @R0
    SETB  EA
    JB    ACC.BIT_N, ?C0027
    MOV   R7, #0
    RET
?C0027:
    MOV   R7, #1
    RET

Parents Reply Children
  • Well, if it's from our library then we should fix this problem.

    Where did it come from? And, do you have a snippit of code I can compile to reproduce it?

    Jon

  • Its from RTX Tiny (oops). I changed the names in the example, but if search through the code you'll find several cases where global interrupts are disabled (via clr EA) and then reenabled (via setb EA) with no regards to the context of the calling process.

    Granted, when this happens within scope of the RTX interrupt itself, its no problem as this bit must have been set for the interrupt to happen in the first place.

    Other functions, however, such as _os_create_task, the wait functions, and pretty much every support function makes this mistake.

    Granted, most people will have interrupts enabled when things are up and running and these functions are being used, but IMO its a wrong for RTX to assume this. Perhaps the best example of when the forground process would require interrupts to remain disabled is during startup...but _os_create_task takes the liberty of SETB EA.

  • Robert,

    A URTOS such as Rtx will, in may cases, "know" what the interrupt status is and thus not have to worry about what you show.

    ANYONE that insist on using a URTOS that allow app control of interrupts will have to spend a lot of time on sorting out interrupt conflicts between the app and the URTOS.

    Thus, in my opinion, if an OS allow ANY interrupt handling by the app (i.e. does not control ALL I/O via device drivers), that URTOS should be trashed since sorting out using it takes more time than is saved by using it.

    Erik

  • Eric,

    I couldn't agree more. If it were my choice, I wouldn't be using an RTOS on in '51 in the first place. Kinda like dropping a 440 Hemi into a Geo Metor. Problem is, its not my decision.

    RTX for a '51 is never going to provide as complete an abstraction layer as, say, NT or similar. Its a microcontroller and applications are going to have to cooperate with the interrupt structure.

    All that aside; for the functions I mentioned, particularly os_create_task, to assume interrupts were enable coming into the function is not what I'd call the best programming technique.

    That's all.

  • All that aside; for the functions I mentioned, particularly os_create_task, to assume interrupts were enable coming into the function is not what I'd call the best programming technique.

    Why? Most of the embedded programs I've created used interrupts. I enable global intsrrupts (EA=1) and assume that they stay enabled all the time (except when there is some kind of critical section). For instance, when I call printf I still want my serial receive interrupt to work. If I disabled interrupts that would not happen.

    RTX51 Tiny is a Tiny RTOS. Like most RTOS, a timer tick interrupt service routine is used to manage tasks, events, and blocking. If you disable interrupts, RTX51 Tiny will fail to update this information and will stop switching tasks.

    For that reason, interrupts must be enabled at most all times. I have tried to clarify this in the documentation at http://www.keil.com/support/man/docs/tr51/tr51_interrupts.htm.

    Here's something to consider. If you need to disable interrupts for extended periods of time that extend beyond one task (the only real reason to call an RTX51 Tiny Library Routine is to switch tasks) then is your program REALLY real-time? And, is a real-time OS necessary?

    Jon

  • In nearly ALL program startup cases, I don't want interrupts enabled until everything is set up and ready to run. This includes module initialization as well as task instantiation. The last thing you do is hit the "let-er-rip" which basically does the final EA. Its a way to ensure that all cooperative operations wait until everything's ready to go.

    That the os_create_task forces interrupts to be set basically states that I can't write a driver that completely encapsulates all related hardware initialization...namely particular interrupts associated with that hardware. Instead, I have to put a note somewhere that says, "Oh, BTW, you have to add a separate line to actually enable this driver's interrupt AFTER any calls to os_create_task"...and hope the user reads it.

    None of this would be a problem if the the RTX code used the method your first reply illustrated.

  • In the RTX51 Tiny applications I've written, I do all of the hardware initialization in task 0 (which is called first). I disable interrupts while I do this.

    Then, I re-enable interrupts and call the os_create_task to create all of my remaining tasks.

    Jon

  • Yes, I can see where it can be a matter of technique.

    I've never used RTX before my current stint and I guess I'm just not that accustomed to giving up control of EA :o)

  • I'm just not that accustomed to giving up control of EA
    The moment you decide to use a URTOS, you give up that control. You can't have it both ways.

    Erik

  • The moment you decide to use a URTOS, you give up that control. You can't have it both ways.

    Yep. That's pretty much the way it is with all RTOS.

    Jon

  • The moment you decide to use a URTOS, you give up that control.

    Correction: The moment someone else decided to us a URTOS, they took that control away from me. >:(

  • The moment you decide to use a URTOS, you give up that control.

    Correction: The moment someone else decided to us a URTOS, they took that control away from me.


    If you were told to us a URTOS, then yoiur "correction" is correct. If your statement tries to blame the maker of the URTOS then blatantly incorrect. There is no way anyone can make something that uses interrupts and truly state "you can do with interrupts whatevere you want, it does not affect me". "truly" in bold, because I have seen that lie.

    Erik