aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/internals/ceilings.md
diff options
context:
space:
mode:
authorAndrey Zgarbul <zgarbul.andrey@gmail.com>2021-04-04 08:15:13 +0300
committerAndrey Zgarbul <zgarbul.andrey@gmail.com>2021-04-08 12:22:43 +0300
commit05bda2b1bd2e15f5a20cda1444992eb9b6c8887e (patch)
tree25330724d4e6d9ea3a62b592c07bfc5799c7da57 /book/ru/src/internals/ceilings.md
parent83cdf00eecb0f14857b5e0f28e884b2120eabb18 (diff)
update russian translation of the book
Diffstat (limited to 'book/ru/src/internals/ceilings.md')
-rw-r--r--book/ru/src/internals/ceilings.md93
1 files changed, 91 insertions, 2 deletions
diff --git a/book/ru/src/internals/ceilings.md b/book/ru/src/internals/ceilings.md
index 2c645a4..df9901a 100644
--- a/book/ru/src/internals/ceilings.md
+++ b/book/ru/src/internals/ceilings.md
@@ -1,3 +1,92 @@
-# Ceiling analysis
+# Анализ приоритетов
-**TODO**
+*Поиск максимального приоритета* ресурса (*ceiling*) - поиск динамического
+приоритета, который любая задача должна иметь, чтобы безопасно работать с
+памятью ресурсов. Анализ приоритетов - относительно прост,
+но критичен для безопасности памяти RTIC программ.
+
+Для расчета максимального приоритета ресурса мы должны сначала составить
+список задач, имеющих доступ к ресурсу -- так как фреймворк RTIC
+форсирует контроль доступа к ресурсам на этапе компиляции, он
+также имеет доступ к этой информации на этапе компиляции.
+Максимальный приоритет ресурса - просто наивысший логический приоритет
+среди этих задач.
+
+`init` и `idle` не настоящие задачи, но у них есть доступ к ресурсам,
+поэтому они должны учитываться при анализе приоритетов.
+`idle` учитывается как задача, имеющая логический приоритет `0`,
+в то время как `init` полностью исключается из анализа --
+причина этому в том, что `init` никогда не использует (не нуждается) критические
+секции для доступа к статическим переменным.
+
+В предыдущем разделе мы показывали, что разделяемые ресусы
+могут быть представлены уникальными ссылками (`&mut-`) или скрываться за
+прокси в зависимости от того, имеет ли задача к ним доступ.
+Какой из вариантов представляется задаче зависит от приоритета задачи и
+максимального приоритета ресурса.
+Если приоритет задачи такой же, как максимальный приоритет ресурса, тогда
+задача получает уникальную ссылку (`&mut-`) на память ресурса,
+в противном случае задача получает прокси -- это также касается `idle`.
+`init` особеннвй: он всегда получает уникальные ссылки (`&mut-`) на ресурсы.
+
+Пример для иллюстрации анализа приоритетов:
+
+``` rust
+#[rtic::app(device = ..)]
+mod app {
+ struct Resources {
+ // доступен из `foo` (prio = 1) и `bar` (prio = 2)
+ // -> CEILING = 2
+ #[init(0)]
+ x: u64,
+
+ // доступен из `idle` (prio = 0)
+ // -> CEILING = 0
+ #[init(0)]
+ y: u64,
+ }
+
+ #[init(resources = [x])]
+ fn init(c: init::Context) {
+ // уникальная ссылка, потому что это `init`
+ let x: &mut u64 = c.resources.x;
+
+ // уникальная ссылка, потому что это `init`
+ let y: &mut u64 = c.resources.y;
+
+ // ..
+ }
+
+ // PRIORITY = 0
+ #[idle(resources = [y])]
+ fn idle(c: idle::Context) -> ! {
+ // уникальная ссылка, потому что
+ // приоритет (0) == максимальному приоритету ресурса (0)
+ let y: &'static mut u64 = c.resources.y;
+
+ loop {
+ // ..
+ }
+ }
+
+ #[interrupt(binds = UART0, priority = 1, resources = [x])]
+ fn foo(c: foo::Context) {
+ // прокси-ресурс, потому что
+ // приоритет задач (1) < максимальному приоритету ресурса (2)
+ let x: resources::x = c.resources.x;
+
+ // ..
+ }
+
+ #[interrupt(binds = UART1, priority = 2, resources = [x])]
+ fn bar(c: foo::Context) {
+ // уникальная ссылка, потому что
+ // приоритет задачи (2) == максимальному приоритету ресурса (2)
+ let x: &mut u64 = c.resources.x;
+
+ // ..
+ }
+
+ // ..
+}
+```