• AVR Freaks

Hot!What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do?

Author
thoraz
Senior Member
  • Total Posts : 138
  • Reward points : 0
  • Joined: 2013/06/01 18:37:43
  • Location: 0
  • Status: offline
2021/02/26 14:21:32 (permalink)
0

What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do?

Maybe my question is trivial but I can't find an trivial and exaustive response, so don't be mad at me! My reference environment is XC16 compiler and PIC24FJ256GA106.
 
What the __builtin_enable_interrupts and __builtin_disable_interrupts function actually do? What about the registers involved? How they are related (if they are!) with the DISI instruction?
post edited by thoraz - 2021/02/26 14:22:51
#1

10 Replies Related Threads

    ric
    Super Member
    • Total Posts : 30223
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: What the __builtin_enable_interrupts and __builtin_disable_interrupts function actuall 2021/02/26 14:22:19 (permalink)
    +6 (6)
    Why not look at the assembly output from the compiler, and see precisely what instrucitons it outputs?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    dan1138
    Super Member
    • Total Posts : 4316
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 14:37:30 (permalink)
    +2 (2)
    The suggestion that ric offers is a good one but there are some other things that could be handy to know about.
     
    When Microchip introduced the PIC24/dsPIC33 controllers there was no way to disable the interrupt system by an atomic operation on a single bit.
     
    The available method using the DISI opcode will block interrupts for a maximum of 16383 instruction cycles.
     
    Newer controllers offer a more traditional method to disable the interrupt system indefinitely.
     
    Follow ric's suggestions to find out just what the __builtin_enable_interrupts and __builtin_disable_interrupts functions do for the controller you have asked about.
    #3
    thoraz
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2013/06/01 18:37:43
    • Location: 0
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 15:07:27 (permalink)
    0
    ric
    Why not look at the assembly output from the compiler, and see precisely what instrucitons it outputs?

     
    dan1138
    The suggestion that ric offers is a good one but there are some other things that could be handy to know about.
     
    When Microchip introduced the PIC24/dsPIC33 controllers there was no way to disable the interrupt system by an atomic operation on a single bit.
     
    The available method using the DISI opcode will block interrupts for a maximum of 16383 instruction cycles.
     
    Newer controllers offer a more traditional method to disable the interrupt system indefinitely.
     
    Follow ric's suggestions to find out just what the __builtin_enable_interrupts and __builtin_disable_interrupts functions do for the controller you have asked about.




     Thanks for the suggestions guys. I found that
     
    32: __builtin_disable_interrupts();
    001F5A FC0006 DISI #0x6
    001F5C 800212 MOV SR, W2
    001F5E B30E02 IOR #0xE0, W2
    001F60 880212 MOV W2, SR

     
    and
     
    19: __builtin_enable_interrupts();
    001F4C FC0006 DISI #0x6
    001F4E 800211 MOV SR, W1
    001F50 B241F1 AND.B #0x1F, W1
    001F52 880211 MOV W1, SR

     
    But I read, as dan1138 said, that the DISI instruction will block interrupts for a given instruction cycles. This mean that __buildin_disable_interrupt function doesn't disable indefinitely the interrupts? I know that it does, but the assembly is not clear about it. Sorry but I'm not a skilled asm coder and this is the reason of a doubt: the DISI #0x6 instruction sets the DISI bit of INTCON2 register?
    #4
    du00000001
    Just Some Member
    • Total Posts : 4145
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 15:17:12 (permalink)
    +2 (2)
    thoraz
    ...
    But I read, as dan1138 said, that the DISI instruction will block interrupts for a given instruction cycles. This mean that __buildin_disable_interrupt function doesn't disable indefinitely the interrupts? I know that it does, but the assembly is not clear about it.
    ...

     
    Don't ask me what the DISI is doing in detail (beyond disabling the interrupts for 6 instruction cycles)
    - - - long enough to modify the SR per R(ead)-M(odify)-W(rite) without being interrupted. Quasi-atomically.
    So following the execution of the __builtin_disable_interrupts() sequence interrupts are blocked until they are re-enabled per __builtin_enable_interrupts().
     
    To be honest - I consider the latter a bit of crap:
    when interrupts are disabled, there is no need for a DISI instruction to temporarily disable the interrupts (that are already disabled). This might have slipped the attention of the reviewers a long time ago  sad

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #5
    thoraz
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2013/06/01 18:37:43
    • Location: 0
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 15:26:05 (permalink)
    0
    du00000001
    thoraz
    ...
    But I read, as dan1138 said, that the DISI instruction will block interrupts for a given instruction cycles. This mean that __buildin_disable_interrupt function doesn't disable indefinitely the interrupts? I know that it does, but the assembly is not clear about it.
    ...

     
    Don't ask me what the DISI is doing in detail (beyond disabling the interrupts for 6 instruction cycles)
    - - - long enough to modify the SR per R(ead)-M(odify)-W(rite) without being interrupted. Quasi-atomically.
    So following the execution of the __builtin_disable_interrupts() sequence interrupts are blocked until they are re-enabled per __builtin_enable_interrupts().
     
    To be honest - I consider the latter a bit of crap:
    when interrupts are disabled, there is no need for a DISI instruction to temporarily disable the interrupts (that are already disabled). This might have slipped the attention of the reviewers a long time ago  sad




    Good point. I got it: the DISI instruction in the __builtin_disable_interrupts is enough to set the SR register and disable pemanently interrupts. And I got also the reverse (unless?) DISI instruction process.
    #6
    DuaneH
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2009/10/15 11:49:22
    • Location: Sandy, UT
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 15:42:46 (permalink)
    +2 (2)
    What is happening is that ints are disabled long enough to set the IPL (in the SR register) to 7, which disables all user interrupts (system traps are still active).  The state of the SR is saved in W1 so it can be restored by the enable interrupts function (i.e., the previous IPL is restored so the program will behave as it did).  Given the nature of interrupts and the fact that it's generally not advisable to leave them disabled for extended periods of time, you may just want to use the DISI instruction with a large number, then set the DISI count to 0 when you're ready to re-enable ints.  Also, read up on the IPL.  You can use this to 'tier' your program so that only the ints you want are allowed.
    Duane

    duaneh
    #7
    Antipodean
    Super Member
    • Total Posts : 2054
    • Reward points : 0
    • Joined: 2008/12/09 10:19:08
    • Location: Didcot, United Kingdom
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 15:59:57 (permalink)
    0
    duaneh
    What is happening is that ints are disabled long enough to set the IPL (in the SR register) to 7, which disables all user interrupts (system traps are still active).  The state of the SR is saved in W1 so it can be restored by the enable interrupts function (i.e., the previous IPL is restored so the program will behave as it did).  Given the nature of interrupts and the fact that it's generally not advisable to leave them disabled for extended periods of time, you may just want to use the DISI instruction with a large number, then set the DISI count to 0 when you're ready to re-enable ints.  Also, read up on the IPL.  You can use this to 'tier' your program so that only the ints you want are allowed.
    Duane



    I wonder what happens if one was to try and nest disable instructions at multiple places in the code without having enable instructions between them.
    I know you shouldn't disable interrupts for very long, but i envisage a code team where one coder has a subroutine which starts with a disable interrupt macro, but that routine is called from code written by another coder who uses a disable macro just before the call ... 
    I have the horrible feeling that the interrupt level stays stuck at 7, no matter how many enable macros are used. 
    post edited by Antipodean - 2021/02/26 16:01:10

    Do not use my alias in your message body when replying, your message will disappear ...

    Alan
    #8
    andersm
    Super Member
    • Total Posts : 2901
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 16:06:15 (permalink)
    +1 (1)
    du00000001To be honest - I consider the latter a bit of crap:
    when interrupts are disabled, there is no need for a DISI instruction to temporarily disable the interrupts (that are already disabled).

    The compiler has no way of guaranteeing that these functions are always used correctly.
    #9
    dan1138
    Super Member
    • Total Posts : 4316
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/02/26 18:01:06 (permalink)
    +3 (3)
    Ant-i-podean
    I wonder what happens if one was to try and nest disable instructions at multiple places in the code without having enable instructions between them. ...

    In my opinion any embedded application that implements nested critical sections is a broken application.
    #10
    cawilkie
    Administrator
    • Total Posts : 2003
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    Re: What the __builtin_enable_interrupts/__builtin_disable_interrupts function actually do 2021/03/31 10:03:09 (permalink)
    0
    The operation of these builtin functions depends upon the device.   Some 16-bit devices do have a very nice global interrupt enable bit, which will be used if available.   Otherwise the brute force method (as described elsewhere in this thread) is used.
     
    Generally its more efficient, and better, to disable only the interrupt sources (using the IEC bits) that will interfere with the critical section.    Though, that is highly application dependent.
     
    Regards
    Calum
    #11
    Jump to:
    © 2021 APG vNext Commercial Version 4.5