Re: ESP32 domácí automatizace

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Pondělí Srpen 2 16:11:13 CEST 2021


A zrovna nad tim badam a jedna vec mi nejde do hlavy:
v modulu port.c je obsluha

BaseType_t xPortSysTickHandler( void )
{
     BaseType_t ret;

     portbenchmarkIntLatency();
     traceISR_ENTER(SYSTICK_INTR_ID);
     ret = xTaskIncrementTick();
     if( ret != pdFALSE )
     {
         portYIELD_FROM_ISR();
     } else {
         traceISR_EXIT();
     }
     return ret;
}

Je logicky umistena v IRAM sekci ale proc??? Funkce nema specifikovany 
IRAM_ATTR, ani v hlavicce.
zrovna tak BaseType_t xTaskIncrementTick( void ) v tasks.c

Tady uz treba attribut je
void IRAM_ATTR esp_vApplicationTickHook(void)
{
     int n;
     int core = xPortGetCoreID();
     for (n=0; n<MAX_HOOKS; n++) {
         if (tick_cb[core][n]!=NULL) {
             tick_cb[core][n]();
         }
     }
}

Funkce se vnoruji v tomto poradi.

Zkousel jsem se povesit na hook od toho casovace a funguje to, jak z 
Flash, tak z IRAM (to je asi rozumnejsi, kdyz je to v ISR)


Dne 02.08.2021 v 12:32 Jaroslav Buchta napsal(a):
> At to ctu stale dokola, nevidim prostor pro zkraceni FreeRTOS - ESP32 
> - — ESP-IDF Programming Guide latest documentation (espressif.com) 
> <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html#task-api>
> Jen je tam upozorneni, ze je nejista prodleva, kdy bude zavolana 
> funkce a az od te doby se to pocita.  vTaskDelayUntil bude mit asi 
> jediny rozdil v tom, ze je tam dany cas ukonceni cekani jako parametr, 
> u vTaskDelay se tato hodnot asi ulozi v okamziku volani.
> A i tak by se jednalo spis o milisekundy nez sekundy...
>
> Koukam na to, ze ty funkce pracuji v principu uplne stejne, pouziji 
> pro uspani
> prvAddCurrentTaskToDelayedList(...);
>  jenom jinak pocitaji dobu pro uspani...
>
> Pokud opravdu muze dojit ke zkraceni intervalu, bylo by v systemu neco 
> velmi spatne. Neprobehne nahodou spis restart?
>
> //////////////////////////////
>
>     void vTaskDelay( const TickType_t xTicksToDelay )
>     {
>     BaseType_t xAlreadyYielded = pdFALSE;
>
>         /* A delay time of zero just forces a reschedule. */
>         if( xTicksToDelay > ( TickType_t ) 0U )
>         {
>             configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 );
>             taskENTER_CRITICAL( &xTaskQueueMutex );
>             {
>                 traceTASK_DELAY();
>
>                 /* A task that is removed from the event list while the
>                 scheduler is suspended will not get placed in the ready
>                 list or removed from the blocked list until the scheduler
>                 is resumed.
>
>                 This task cannot be in an event list as it is the 
> currently
>                 executing task. */
>                 prvAddCurrentTaskToDelayedList( xPortGetCoreID(), 
> xTicksToDelay );
>             }
>             taskEXIT_CRITICAL( &xTaskQueueMutex );
>         }
>         else
>         {
>             mtCOVERAGE_TEST_MARKER();
>         }
>
>         /* Force a reschedule if xTaskResumeAll has not already done 
> so, we may
>         have put ourselves to sleep. */
>         if( xAlreadyYielded == pdFALSE )
>         {
>             portYIELD_WITHIN_API();
>         }
>         else
>         {
>             mtCOVERAGE_TEST_MARKER();
>         }
>     }
>
>
>
>     void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const 
> TickType_t xTimeIncrement )
>     {
>     TickType_t xTimeToWake;
>     BaseType_t xAlreadyYielded = pdFALSE, xShouldDelay = pdFALSE;
>
>         configASSERT( pxPreviousWakeTime );
>         configASSERT( ( xTimeIncrement > 0U ) );
>         configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 );
>
>         taskENTER_CRITICAL( &xTaskQueueMutex );
>         {
>             /* Minor optimisation.  The tick count cannot change in this
>             block. */
>             const TickType_t xConstTickCount = xTickCount;
>
>             /* Generate the tick time at which the task wants to wake. */
>             xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
>
>             if( xConstTickCount < *pxPreviousWakeTime )
>             {
>                 /* The tick count has overflowed since this function was
>                 lasted called.  In this case the only time we should ever
>                 actually delay is if the wake time has also overflowed,
>                 and the wake time is greater than the tick time.  When 
> this
>                 is the case it is as if neither time had overflowed. */
>                 if( ( xTimeToWake < *pxPreviousWakeTime ) && ( 
> xTimeToWake > xConstTickCount ) )
>                 {
>                     xShouldDelay = pdTRUE;
>                 }
>                 else
>                 {
>                     mtCOVERAGE_TEST_MARKER();
>                 }
>             }
>             else
>             {
>                 /* The tick time has not overflowed.  In this case we will
>                 delay if either the wake time has overflowed, and/or the
>                 tick time is less than the wake time. */
>                 if( ( xTimeToWake < *pxPreviousWakeTime ) || ( 
> xTimeToWake > xConstTickCount ) )
>                 {
>                     xShouldDelay = pdTRUE;
>                 }
>                 else
>                 {
>                     mtCOVERAGE_TEST_MARKER();
>                 }
>             }
>
>             /* Update the wake time ready for the next call. */
>             *pxPreviousWakeTime = xTimeToWake;
>
>             if( xShouldDelay != pdFALSE )
>             {
>                 traceTASK_DELAY_UNTIL();
>
>                 /* prvAddCurrentTaskToDelayedList() needs the block 
> time, not
>                 the time to wake, so subtract the current tick count. */
>                 prvAddCurrentTaskToDelayedList( xPortGetCoreID(), 
> xTimeToWake - xConstTickCount );
>             }
>             else
>             {
>                 mtCOVERAGE_TEST_MARKER();
>             }
>         }
>         taskEXIT_CRITICAL( &xTaskQueueMutex );
>
>         /* Force a reschedule if xTaskResumeAll has not already done 
> so, we may
>         have put ourselves to sleep. */
>         if( xAlreadyYielded == pdFALSE )
>         {
>             portYIELD_WITHIN_API();
>         }
>         else
>         {
>             mtCOVERAGE_TEST_MARKER();
>         }
>     }
>
>
> Dne 02.08.2021 v 12:09 as5s napsal(a):
>>
>> Netusim ako to presne funguje, ale v dokumentacii na to upozornuju.
>>
>> ale je mi cudne ze sa to skrati. O kolko sa to skrati?
>>
>> Myre
>>
>>
>> On 2. 8. 2021 10:35, Jaroslav Buchta wrote:
>>> To jako opravdu vTaskDelay muze fungovat nespolehlive, teda jeste k 
>>> tomu se zkratit?
>>> To snad primo pocita systemova preruseni od casovace (default tusim 
>>> 100Hz), ze by se nejaky nestihly bych jeste pochopil...
>>>
>>> Dne 02.08.2021 v 9:49 as5s napsal(a):
>>>>
>>>> Dobry den,
>>>>
>>>> skuste pozriet na vTaskDelayUntil()
>>>>
>>>> https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html#_CPPv415vTaskDelayUntilPC10TickType_tK10TickType_t
>>>>
>>>> mozno vam to bude stacit.
>>>>
>>>> Myre
>>>>
>>>> On 2. 8. 2021 9:45, Jan Půhoný wrote:
>>>>> Dobrý den,
>>>>>
>>>>> mám tady další zádrhel - mějme funkci, která ovládá výstupní piny, 
>>>>> potřebuji po nastavení udžet cca 20 sekund v HIGH a pak vrátit vše 
>>>>> do low. Jedná se o otevítání a zavírání ventilu. Přidal jsem tedy 
>>>>> mezi to vTaskDelay(20000 / portTICK_PERIOD_MS); , problém je v 
>>>>> tom, že někdy se to zpoždění značně zkrátí a ventil zůstane napolo 
>>>>> otevřený. Jak se toto dá ošetřit aby se vTaskDelay(20000 / 
>>>>> portTICK_PERIOD_MS); nikdy nemohlo zkrátit a bylo dodrženo.
>>>>>
>>>>> Volám to pak standardně přes xTaskCreatePinnedToCore() ....
>>>>>
>>>>> void vent1On(void * parameter){
>>>>> for(;;){ // infinite loop
>>>>> button1.update(1);
>>>>> digitalWrite(ventMain1, HIGH);
>>>>> digitalWrite(ventOn1, HIGH);
>>>>> digitalWrite(ledPinRed, HIGH);
>>>>>     // Pause the task fo 20s
>>>>> vTaskDelay(20000 / portTICK_PERIOD_MS);
>>>>> digitalWrite(ventMain1, LOW);
>>>>> digitalWrite(ventOn1, LOW);
>>>>> digitalWrite(ledPinRed, LOW);
>>>>> vTaskDelete(NULL); //spustí se jen jednou
>>>>>   }
>>>>> }
>>>>>
>>>>>
>>>>> xTaskCreatePinnedToCore(
>>>>>     vent1On,    // Function that should be called
>>>>>     "vent1On",   // Name of the task (for debugging)
>>>>>     1000,            // Stack size (bytes)
>>>>>     NULL,            // Parameter to pass
>>>>>     1,               // Task priority
>>>>>     NULL,            // Task handle
>>>>>     0            // Core 1/0
>>>>>   );
>>>>>
>>>>> HP
>>>>>
>>>>>
>>>>> so 31. 7. 2021 v 8:27 odesílatel Jan Půhoný <konference na puhy.cz 
>>>>> <mailto:konference na puhy.cz>> napsal:
>>>>>
>>>>>     Díky, zkusil jsem jak 2000 tak 4000 ale stále stejné. Resetuje
>>>>>     se to pořád dokola s tímto:
>>>>>
>>>>>     rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
>>>>>     configsip: 0, SPIWP:0xee
>>>>>     clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
>>>>>     mode:DIO, clock div:2
>>>>>     load:0x3fff0018,len:4
>>>>>     load:0x3fff001c,len:1044
>>>>>     load:0x40078000,len:10124
>>>>>     load:0x40080400,len:5828
>>>>>     entry 0x400806a8
>>>>>
>>>>>     *Ale zjistil jsem, že to dělá jen pokud to napájím z USB. Když
>>>>>     to dám přímo do svého zapojení, kde je pořádná kapacita na
>>>>>     Vin, tak to drží. Takže skutečně jen problém s napájením.*
>>>>>
>>>>>     Teď už to budu programovat jen přes OTA, takže vyřešeno.
>>>>>
>>>>>     HP
>>>>>
>>>>>
>>>>>     so 31. 7. 2021 v 6:44 odesílatel Jaroslav Buchta
>>>>>     <jaroslav.buchta na hascomp.cz
>>>>>     <mailto:jaroslav.buchta na hascomp.cz>> napsal:
>>>>>
>>>>>         kod jsem nezkoumal ale na prvni pohled mi prijde maly
>>>>>         zasobnik pro
>>>>>         vlakno, tady je to tusim v btech. dal bych 2 nebo 4K na
>>>>>         zkousku
>>>>>         _______________________________________________
>>>>>         HW-list mailing list  -  sponsored by www.HW.cz
>>>>>         <http://www.HW.cz>
>>>>>         Hw-list na list.hw.cz <mailto:Hw-list na list.hw.cz>
>>>>>         http://list.hw.cz/mailman/listinfo/hw-list
>>>>>         <http://list.hw.cz/mailman/listinfo/hw-list>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> HW-list mailing list  -  sponsored bywww.HW.cz
>>>>> Hw-list na list.hw.cz
>>>>> http://list.hw.cz/mailman/listinfo/hw-list
>>>>
>>>> _______________________________________________
>>>> HW-list mailing list  -  sponsored bywww.HW.cz
>>>> Hw-list na list.hw.cz
>>>> http://list.hw.cz/mailman/listinfo/hw-list
>>>
>>>
>>>
>>> _______________________________________________
>>> HW-list mailing list  -  sponsored bywww.HW.cz
>>> Hw-list na list.hw.cz
>>> http://list.hw.cz/mailman/listinfo/hw-list
>>
>> _______________________________________________
>> HW-list mailing list  -  sponsored bywww.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>
>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list


------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210802/fbcc5a8a/attachment.html>


Další informace o konferenci Hw-list