А почему то никто и не обратился к Ляброссу и не сприсил у него , какого же фига он там наворотил? И все таки не смотря на эпитеты "меньшее зло" и "фуфло по сравнению с Билом Куцым" смею привести предложение из опуса многоуважаемого капиталиста :
The question is thus, which one is better? Well, that all depends on what you are willing to sacrifice. If you don’t care in your application whether interrupts are enabled after calling a μC/OS-II service then, you should opt for the first method because of performance. If you want to preserve the interrupt disable status across μC/OS-II service cal
Первый вартиант нравится многим и он здесь присутствует :
#if OS_CRITICAL_METHOD == 1
#define OS_ENTER_CRITICAL() _CLI() /* Disable interrupts */
#define OS_EXIT_CRITICAL() _SEI() /* Enable interrupts */
#endif
А третий вариант ставший предметом помидоромеетания описывается так :
#if OS_CRITICAL_METHOD == 3
#define OS_ENTER_CRITICAL() (cpu_sr = OS_CPU_SR_Save()) /* Disable interrupts */
#define OS_EXIT_CRITICAL() (OS_CPU_SR_Restore(cpu_sr)) /* Enable interrupts */
#endif
OS_CPU_SR_Save: IN R16,SREG ; Get current state of interrupts disable flag
CLI ; Disable interrupts
RET
OS_CPU_SR_Restore: OUT SREG,R16 ; Restore SREG
RET
То есть как пишет Ля или Лабросс третый вариант после OS_EXIT_CRITICAL()
дает нам состояние прерывания (запрешенное или разрешенное) кототое было перед тем как вызывалась функция OS_ENTER_CRITICAL()
Теперь, почему я у себя в программе использую 3ий вариант . У меня есть код который увеличивает значение семафора работая из ISR. To есть мне нравится вызывать функцию OSSemPost() когда прерывания запрешены . Если посмотреть на код OSSemPost() то там можно увидеть:
INT8U OSSemPost (OS_EVENT *pevent)
{
....
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore*/
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready HPT waiting on event */
OS_EXIT_CRITICAL();
....
}
из вышеприведенного получается что при использовании варианта 1 , я получаю разрешение прерывания при выполнении функции OSSemPost() то есть находясь в ISR и могу получить вложенное прерывание , с которым у меня свидание лишь после выполнения
ISR но не до него . Используя вариант 3 у меня с этим проблем не возникнет .
Надеюсь сказанное как то снимает вину с вышеупомянутого товарисча белогвардейца Лябросса.
Надеюсь мое занудство вам не надоело