Цитата
Про "еще один байт" не понял. Если у Вас цель какие-то байты экономить, а не такты, то так и напишите.
Ну вообще в данный момент да, основа это байты. Ибо AVR Tiny, задачи две - три...ну пять в худший день.
Цитата
Для, например, 256 задач (реальный случай во времена i8080 2MHz) крутить 256 счетчиков - весь пар свисток уйдет.
Полностью согласен. Надеюсь поделитесь алгоритмом для такого случая? Интересно. Предполагаю, что надо крутить один счетчик в прерывании, а в задаче хранить переменную со значением счётчика при котором надо срабатывать.
Потом в RunScheduled() брать текущее значение счетчика, проходиться по задачам и сравнивать. После выполнения задачи переменную увеличивать вперед на период.
Я правильно мыслю или есть более оптимальный вариант? Просто так получается да, такты прерывания мы экономим, но имеем кучу сравнений(и сравнений не с константами) в RunScheduled().
Цитата
Такие тривиальные вещи вообще незачем делать "универсальными"
Согласен, но я тут просто добрался до шаблонов в С++ и конечно же страдаю "переиспользованием". Но всё равно полезно )
Цитата
Не верю! Если, вдруг, не одно и тоже, то первым шагом борьбы за что либо, следует выкинуть используемый компилятор.
Код
for(uint8_t i=0; i < TaskListLen; i++)
timers[i] = (timers[i]>0)? (timers[i]-1):(timers[i]);
Program Memory Usage : 160 bytes 15,6 % Full
Data Memory Usage : 2 bytes 3,1 % Full
{
00000019 PUSH R1 Push register on stack
0000001A PUSH R0 Push register on stack
0000001B IN R0,0x3F In from I/O location
0000001C PUSH R0 Push register on stack
0000001D CLR R1 Clear Register
0000001E PUSH R24 Push register on stack
RELOAD_TCNT0();
0000001F LDI R24,0x82 Load immediate
00000020 OUT 0x32,R24 Out to I/O location
--- D:\Poligon\Scheduler\TinyScheduler\TinyScheduler\Debug/.././TinyScheduler.hpp
timers[i] = (timers[i]>0)? (timers[i]-1):(timers[i]);
00000021 LDS R24,0x0060 Load direct from data space
00000023 CPSE R24,R1 Compare, skip if equal
00000024 SUBI R24,0x01 Subtract immediate
00000025 STS 0x0060,R24 Store direct to data space
00000027 LDS R24,0x0061 Load direct from data space
00000029 CPSE R24,R1 Compare, skip if equal
0000002A SUBI R24,0x01 Subtract immediate
0000002B STS 0x0061,R24 Store direct to data space
--- D:\Poligon\Scheduler\TinyScheduler\TinyScheduler\Debug/.././main.cpp -------
}
0000002D POP R24 Pop register from stack
0000002E POP R0 Pop register from stack
0000002F OUT 0x3F,R0 Out to I/O location
00000030 POP R0 Pop register from stack
00000031 POP R1 Pop register from stack
00000032 RETI Interrupt return
Предложенный вами вариант:
Код
for(uint8_t i=0; i < TaskListLen; i++)
if( timers[i] )
timers[i]--;
Program Memory Usage : 164 bytes 16,0 % Full
Data Memory Usage : 2 bytes 3,1 % Full
{
00000019 PUSH R1 Push register on stack
0000001A PUSH R0 Push register on stack
0000001B IN R0,0x3F In from I/O location
0000001C PUSH R0 Push register on stack
0000001D CLR R1 Clear Register
--- D:\Poligon\Scheduler\TinyScheduler\TinyScheduler\Debug/.././main.cpp -------
0000001E PUSH R24 Push register on stack
RELOAD_TCNT0();
0000001F LDI R24,0x82 Load immediate
00000020 OUT 0x32,R24 Out to I/O location
--- D:\Poligon\Scheduler\TinyScheduler\TinyScheduler\Debug/.././TinyScheduler.hpp
if( timers[i] )
00000021 LDS R24,0x0060 Load direct from data space
00000023 TST R24 Test for Zero or Minus
00000024 BREQ PC+0x04 Branch if equal
timers[i]--;
00000025 SUBI R24,0x01 Subtract immediate
00000026 STS 0x0060,R24 Store direct to data space
if( timers[i] )
00000028 LDS R24,0x0061 Load direct from data space
0000002A TST R24 Test for Zero or Minus
0000002B BREQ PC+0x04 Branch if equal
timers[i]--;
0000002C SUBI R24,0x01 Subtract immediate
0000002D STS 0x0061,R24 Store direct to data space
--- D:\Poligon\Scheduler\TinyScheduler\TinyScheduler\Debug/.././main.cpp -------
}
0000002F POP R24 Pop register from stack
00000030 POP R0 Pop register from stack
00000031 OUT 0x3F,R0 Out to I/O location
00000032 POP R0 Pop register from stack
00000033 POP R1 Pop register from stack
00000034 RETI Interrupt return
получилось даже 4 байта, а не 2.
Компилятор:
Цитата
Invoking: AVR8/GNU C Compiler : 4.9.2
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-g++.exe" -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.1.102\include" -I"../include" -Os -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=attiny13a -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.1.102\gcc\dev\attiny13a" -c -fno-threadsafe-statics -fno-exceptions -fno-rtti -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.cpp"