Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
мьютекс для Twi
1. Очередь запросов TWI
(кольцевой буфер)
Массив структур TWI[] после
инициализации
так он выглядит физически
так мы его себе представляем
Массив структур в SRAM
TWI[0] TWI[1] TWI[2] TWI[3] TWI[4] TWI[5] TWI[6] TWI[7]
SLA pW nW pR nR
2. flag = 0
Переменные head и tail
Переменная head указывает куда
можно положить данные для
следующего фрейма.
Переменная tail указывает какой
фрейм будет следующим.
Обе переменные инициализируются
0 и указывают на начало масcива.
head
tail
TWI[0] TWI[1] TWI[2] TWI[3] TWI[4] TWI[5] TWI[6] TWI[7]
3. get_AC1 TWI[1] TWI[2] TWI[3] TWI[4] TWI[5] TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC1
Данные для этой функции
копируются в TWI[0].
Значение head увеличивается на 1,
становится равным head=1 и
указывает на следующую ячейку.
Так как head!=tail и переменная
flag=0 устанавливаем ее в 1 и даем
СТАРТ.
head
tail
4. get_AC1 get_AC2 TWI[2] TWI[3] TWI[4] TWI[5] TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC2
Данные для этой функции
копируются в TWI[1].
Значение head увеличивается на 1,
становится равным head=2 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
5. get_AC1 get_AC2 get_AC3 TWI[3] TWI[4] TWI[5] TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC3
Данные для этой функции
копируются в TWI[2].
Значение head увеличивается на 1,
становится равным head=3 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
6. get_AC1 get_AC2 get_AC3 get_AC4 TWI[4] TWI[5] TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC4
Данные для этой функции
копируются в TWI[3].
Значение head увеличивается на 1,
становится равным head=4 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
7. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 TWI[5] TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC5
Данные для этой функции
копируются в TWI[4].
Значение head увеличивается на 1,
становится равным head=5 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
Предположим в этот момент
функция get_AC1 полностью
отработана. Обработчик видит что
head!=tail, увеличивает tail на 1 и
дает СТОП-СТАРТ. Таким образом
обработчик сразу же начинает
отрабатывать get_AC2.
head
tail
8. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 TWI[6] TWI[7]
flag = 1
Выполнение функции get_AC6
Данные для этой функции
копируются в TWI[5].
Значение head увеличивается на 1,
становится равным head=6 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
9. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 TWI[7]
flag = 1
Выполнение функции get_B0
Данные для этой функции
копируются в TWI[6].
Значение head увеличивается на 1,
становится равным head=7 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
10. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 get_B1
flag = 1
Выполнение функции get_B1
Данные для этой функции
копируются в TWI[7].
В этом случае head сбросится на 0 и
будет указывать на нулевую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
head
tail
11. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 get_B1
flag = 1
Выполнение функции get_MB
Эта функция будет планировщиком
отброшена, так как выполняется
условие tail-head=1 || head-tail=size-1
(буфер переполнен).
СТАРТ не дается.
head
tail
12. get_AC1 get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 get_B1
flag = 1
Выполнение функции get_MC
Эта функция будет планировщиком
отброшена, так как выполняется
условие tail-head=1 || head-tail=size-1
(буфер переполнен).
СТАРТ не дается.
Предположим в этот момент
функция get_AC2 полностью
отработана. Обработчик видит что
head!=tail, увеличивает tail на 1 и
дает СТОП-СТАРТ. Таким образом
обработчик сразу же начинает
отрабатывать get_AC3.
head
tail
13. get_MD get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 get_B1
flag = 1
Выполнение функции get_MD
Данные для этой функции
копируются в TWI[0].
Значение head увеличивается на 1,
становится равным head=1 и
указывает на следующую ячейку.
Хоть head!=tail, переменная flag=1,
поэтому СТАРТ не дается.
Любая функция которая попытается
получить запрос на шину TWI будет
отброшена до тех пор пока функция
get_AC3 не будет отработана и место
в буфере не освободится.
head
tail
14. get_MD get_AC2 get_AC3 get_AC4 get_AC5 get_AC6 get_B0 get_B1
flag = 0
Через какое-то время
Обработчик будет отрабатывать
функцию за функцией, выплёвывая в
шину байты в заданной
последовательности. И только когда
tail догонит и станет равна head
выполнится условие буфер пуст и
вместо СТАРТ-СТОП выдастся СТОП
тем самым останавливая
обработчик. При этом flag сбросится
и станет равным 0. Как только в
буфер положатся данные, head
станет не равным tail, и так как flag=0
запустится СТАРТ и обработчик вновь
начнет отрабатывать очередь, пока
не выполнит последний элемент.
head
tail