nrf52840dk_thread_tutorial/
main.rs1#![no_std]
8#![cfg_attr(not(doc), no_main)]
11#![deny(missing_docs)]
12
13use core::ptr::{addr_of, addr_of_mut};
14
15use kernel::component::Component;
16use kernel::platform::{KernelResources, SyscallDriverLookup};
17use kernel::{capabilities, create_capability};
18use nrf52840::gpio::Pin;
19use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
20use nrf52840dk_lib::{self, NUM_PROCS, PROCESSES};
21
22type ScreenDriver = components::screen::ScreenComponentType;
23
24const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
27 capsules_system::process_policies::PanicFaultPolicy {};
28
29type Ieee802154RawDriver =
30 components::ieee802154::Ieee802154RawComponentType<nrf52840::ieee802154_radio::Radio<'static>>;
31
32struct Platform {
33 base: nrf52840dk_lib::Platform,
34 ieee802154: &'static Ieee802154RawDriver,
35 eui64: &'static nrf52840dk_lib::Eui64Driver,
36 screen: &'static ScreenDriver,
37 nonvolatile_storage:
38 &'static capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
39 'static,
40 {
41 components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT
42 },
43 >,
44}
45
46impl SyscallDriverLookup for Platform {
47 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
48 where
49 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
50 {
51 match driver_num {
52 capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
53 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
54 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
55 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => {
56 f(Some(self.nonvolatile_storage))
57 }
58 _ => self.base.with_driver(driver_num, f),
59 }
60 }
61}
62
63type Chip = nrf52840dk_lib::Chip;
64
65impl KernelResources<Chip> for Platform {
66 type SyscallDriverLookup = Self;
67 type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
68 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
69 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
70 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
71 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
72 type ContextSwitchCallback =
73 <nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
74
75 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
76 self
77 }
78 fn syscall_filter(&self) -> &Self::SyscallFilter {
79 self.base.syscall_filter()
80 }
81 fn process_fault(&self) -> &Self::ProcessFault {
82 self.base.process_fault()
83 }
84 fn scheduler(&self) -> &Self::Scheduler {
85 self.base.scheduler()
86 }
87 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
88 self.base.scheduler_timer()
89 }
90 fn watchdog(&self) -> &Self::WatchDog {
91 self.base.watchdog()
92 }
93 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
94 self.base.context_switch_callback()
95 }
96}
97
98#[no_mangle]
100pub unsafe fn main() {
101 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
102
103 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
105 nrf52840dk_lib::start();
106
107 let device_id = (*addr_of!(nrf52840::ficr::FICR_INSTANCE)).id();
112
113 let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
114 .finalize(components::eui64_component_static!());
115
116 let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
117 board_kernel,
118 capsules_extra::ieee802154::DRIVER_NUM,
119 &nrf52840_peripherals.ieee802154_radio,
120 )
121 .finalize(components::ieee802154_raw_component_static!(
122 nrf52840::ieee802154_radio::Radio,
123 ));
124
125 const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
130 const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
131
132 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
133 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
134 nrf52840_peripherals.nrf52.twi1.configure(
135 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
136 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
137 );
138 nrf52840_peripherals
139 .nrf52
140 .twi1
141 .set_speed(nrf52840::i2c::Speed::K400);
142
143 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
145 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
146
147 #[cfg(feature = "screen_ssd1306")]
149 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
150 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
151
152 #[cfg(feature = "screen_sh1106")]
153 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
154 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
155
156 let screen = components::screen::ScreenComponent::new(
157 board_kernel,
158 capsules_extra::screen::DRIVER_NUM,
159 ssd1306_sh1106,
160 None,
161 )
162 .finalize(components::screen_component_static!(1032));
163
164 ssd1306_sh1106.init_screen();
165
166 kernel::storage_volume!(APP_STORAGE, 32);
172
173 let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new(
174 board_kernel,
175 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM,
176 &nrf52840_peripherals.nrf52.nvmc,
177 core::ptr::addr_of!(APP_STORAGE) as usize,
178 APP_STORAGE.len()
179 )
180 .finalize(components::isolated_nonvolatile_storage_component_static!(
181 nrf52840::nvmc::Nvmc,
182 { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT }
183 ));
184
185 let platform = Platform {
190 base: base_platform,
191 eui64,
192 ieee802154,
193 screen,
194 nonvolatile_storage,
195 };
196
197 extern "C" {
199 static _sapps: u8;
201 static _eapps: u8;
203 static mut _sappmem: u8;
205 static _eappmem: u8;
207 }
208
209 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
215 .finalize(components::app_checker_null_component_static!());
216
217 let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
219 .finalize(components::appid_assigner_names_component_static!());
220
221 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
223 .finalize(components::process_checker_machine_component_static!());
224
225 let storage_permissions_policy =
230 components::storage_permissions::individual::StoragePermissionsIndividualComponent::new()
231 .finalize(
232 components::storage_permissions_individual_component_static!(
233 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
234 kernel::process::ProcessStandardDebugFull,
235 ),
236 );
237
238 let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
243 checker,
244 &mut *addr_of_mut!(PROCESSES),
245 board_kernel,
246 chip,
247 &FAULT_RESPONSE,
248 assigner,
249 storage_permissions_policy,
250 )
251 .finalize(components::process_loader_sequential_component_static!(
252 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
253 kernel::process::ProcessStandardDebugFull,
254 NUM_PROCS
255 ));
256
257 board_kernel.kernel_loop(
258 &platform,
259 chip,
260 Some(&platform.base.ipc),
261 &main_loop_capability,
262 );
263}