# Анализ приоритетов *Поиск максимального приоритета* ресурса (*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; // .. } // .. } ```