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