ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
22 декабря
1013219 Топик полностью
LightElf (19.06.2020 12:42, просмотров: 1009) ответил fk0 на А какое должно быть решение? Можно подумать, что какие-то фундаментальные принципы в "computer science" чем-то отличны в зависимости от фирмы выпустившей микропроцессор. Может и не UART вовсе, а TCP/IP, и не микроконтроллер, а Core I9. Суть от этого не меняется. А ты хочешь сказать, мол в зависимости от того какой глубины UART в МК всё кардинально меняется... На верхнем уровне абстракции ничего о реализации нижнего знать не положено. Принято, что есть некий метод write,
Ну вот есть у тебя абстракция write, пользуй ее и не ломай голову как она внутри устроена. Конкретная реализация write будет зависеть от OS, а конкретная реализация драйвера UART - от конкретного железа. А если не UART, а Ethernet - там будут другие реализации и другие драйвера. Будет ли там условная переменная, два семафора или отдельный сопроцессор с блекджеком и программистками - это вопрос конкретной реализации, а не фундаментальных принципов. 

Про запрет прерываний - именно так и сделана критическая секция в FreeRTOS и прочих всяких TNeo.

 /* Critical section handling. */
#define portENABLE_INTERRUPTS()                __asm( "cli" )
#define portDISABLE_INTERRUPTS()            __asm( "sei" )

/*
 * Disable interrupts before incrementing the count of critical section nesting.
 * The nesting count is maintained so we know when interrupts should be
 * re-enabled.  Once interrupts are disabled the nesting count can be accessed
 * directly.  Each task maintains its own nesting count.
 */
#define portENTER_CRITICAL()                                      \
{                                                                \
    extern volatile UBaseType_t uxCriticalNesting;    \
                                                                \
    portDISABLE_INTERRUPTS();                                    \
    uxCriticalNesting++;                                        \
}

/*
 * Interrupts are disabled so we can access the nesting count directly.  If the
 * nesting is found to be 0 (no nesting) then we are leaving the critical
 * section and interrupts can be re-enabled.
 */
#define  portEXIT_CRITICAL()                                    \
{                                                                \
    extern volatile UBaseType_t uxCriticalNesting;    \
                                                                \
    uxCriticalNesting--;                                        \
    if( uxCriticalNesting == 0 )                                \
    {                                                            \
        portENABLE_INTERRUPTS();                                \
    }                                                            \
}

Про реализацию атомиков в libgcc - вопрос не ко мне, я без понятия как и чего там.

Понял что тебе не нравится, я этот момент не описал, считая самоочевидным. Любой поток, запихав свои данные в буфер проверяет, сколько там осталось места. Если осталось приличное количество - постит семафор. Описанная тобой беда-беда возникает ровно в одном случае: в буфере есть чуть-чуть свободного места, куда в принципе могли бы влезть какие-то из отправляемых сообщений. Если такая ситуация случается часто - нужно просто увеличить буфер. Если редко - да и пес с ним.

Не надо делать мне как лучше, оставьте мне как хорошо