@@ -33,7 +33,7 @@ type NrfxIpcHandler = extern "C" fn(event_mask: u32, ptr: *mut u8);
3333#[ derive( Debug , Copy , Clone ) ]
3434pub enum NrfxErr {
3535 ///< Operation performed successfully.
36- Success = ( 0x0BAD0000 + 0 ) ,
36+ Success = 0x0BAD0000 ,
3737 ///< Internal error.
3838 ErrorInternal = ( 0x0BAD0000 + 1 ) ,
3939 ///< No memory for operation.
@@ -147,33 +147,7 @@ pub extern "C" fn nrf_modem_irrecoverable_error_handler(err: u32) -> ! {
147147/// memory regions. This function allocates dynamic memory for the library.
148148#[ no_mangle]
149149pub extern "C" fn nrf_modem_os_alloc ( num_bytes_requested : usize ) -> * mut u8 {
150- let usize_size = core:: mem:: size_of :: < usize > ( ) ;
151- let mut result = core:: ptr:: null_mut ( ) ;
152- unsafe {
153- cortex_m:: interrupt:: free ( |cs| {
154- let num_bytes_allocated = num_bytes_requested + usize_size;
155- let layout =
156- core:: alloc:: Layout :: from_size_align_unchecked ( num_bytes_allocated, usize_size) ;
157- if let Some ( ref mut allocator) = * crate :: GENERIC_ALLOCATOR . borrow ( cs) . borrow_mut ( ) {
158- match allocator. allocate_first_fit ( layout) {
159- Ok ( real_block) => {
160- let real_ptr = real_block. as_ptr ( ) ;
161- // We need the block size to run the de-allocation. Store it in the first four bytes.
162- core:: ptr:: write_volatile :: < usize > (
163- real_ptr as * mut usize ,
164- num_bytes_allocated,
165- ) ;
166- // Give them the rest of the block
167- result = real_ptr. offset ( usize_size as isize ) ;
168- }
169- Err ( _e) => {
170- // Ignore
171- }
172- }
173- }
174- } ) ;
175- }
176- result
150+ unsafe { generic_alloc ( num_bytes_requested, & crate :: LIBRARY_ALLOCATOR ) }
177151}
178152
179153/// The Modem library needs to dynamically allocate memory (a heap) for proper
@@ -184,20 +158,8 @@ pub extern "C" fn nrf_modem_os_alloc(num_bytes_requested: usize) -> *mut u8 {
184158/// memory regions. This function allocates dynamic memory for the library.
185159#[ no_mangle]
186160pub extern "C" fn nrf_modem_os_free ( ptr : * mut u8 ) {
187- let usize_size = core:: mem:: size_of :: < usize > ( ) as isize ;
188161 unsafe {
189- cortex_m:: interrupt:: free ( |cs| {
190- // Fetch the size from the previous four bytes
191- let real_ptr = ptr. offset ( -usize_size) ;
192- let num_bytes_allocated = core:: ptr:: read_volatile :: < usize > ( real_ptr as * const usize ) ;
193- let layout = core:: alloc:: Layout :: from_size_align_unchecked (
194- num_bytes_allocated,
195- usize_size as usize ,
196- ) ;
197- if let Some ( ref mut allocator) = * crate :: GENERIC_ALLOCATOR . borrow ( cs) . borrow_mut ( ) {
198- allocator. deallocate ( core:: ptr:: NonNull :: new_unchecked ( real_ptr) , layout) ;
199- }
200- } ) ;
162+ generic_free ( ptr, & crate :: LIBRARY_ALLOCATOR ) ;
201163 }
202164}
203165
@@ -207,54 +169,16 @@ pub extern "C" fn nrf_modem_os_free(ptr: *mut u8) {
207169/// @return pointer to allocated memory
208170#[ no_mangle]
209171pub extern "C" fn nrf_modem_os_shm_tx_alloc ( num_bytes_requested : usize ) -> * mut u8 {
210- let usize_size = core:: mem:: size_of :: < usize > ( ) ;
211- let mut result = core:: ptr:: null_mut ( ) ;
212- unsafe {
213- cortex_m:: interrupt:: free ( |cs| {
214- let num_bytes_allocated = num_bytes_requested + usize_size;
215- let layout =
216- core:: alloc:: Layout :: from_size_align_unchecked ( num_bytes_allocated, usize_size) ;
217- if let Some ( ref mut allocator) = * crate :: TX_ALLOCATOR . borrow ( cs) . borrow_mut ( ) {
218- match allocator. allocate_first_fit ( layout) {
219- Ok ( real_block) => {
220- let real_ptr = real_block. as_ptr ( ) ;
221- // We need the block size to run the de-allocation. Store it in the first four bytes.
222- core:: ptr:: write_volatile :: < usize > (
223- real_ptr as * mut usize ,
224- num_bytes_allocated,
225- ) ;
226- // Give them the rest of the block
227- result = real_ptr. offset ( usize_size as isize ) ;
228- }
229- Err ( _e) => {
230- // Ignore
231- }
232- }
233- }
234- } ) ;
235- }
236- result
172+ unsafe { generic_alloc ( num_bytes_requested, & crate :: TX_ALLOCATOR ) }
237173}
238174
239175/// Free a shared memory buffer in the TX area.
240176///
241177/// @param ptr Th buffer to free.
242178#[ no_mangle]
243179pub extern "C" fn nrf_modem_os_shm_tx_free ( ptr : * mut u8 ) {
244- let usize_size = core:: mem:: size_of :: < usize > ( ) as isize ;
245180 unsafe {
246- cortex_m:: interrupt:: free ( |cs| {
247- // Fetch the size from the previous four bytes
248- let real_ptr = ptr. offset ( -usize_size) ;
249- let num_bytes_allocated = core:: ptr:: read_volatile :: < usize > ( real_ptr as * const usize ) ;
250- let layout = core:: alloc:: Layout :: from_size_align_unchecked (
251- num_bytes_allocated,
252- usize_size as usize ,
253- ) ;
254- if let Some ( ref mut allocator) = * crate :: TX_ALLOCATOR . borrow ( cs) . borrow_mut ( ) {
255- allocator. deallocate ( core:: ptr:: NonNull :: new_unchecked ( real_ptr) , layout) ;
256- }
257- } ) ;
181+ generic_free ( ptr, & crate :: TX_ALLOCATOR ) ;
258182 }
259183}
260184
@@ -302,7 +226,7 @@ pub extern "C" fn nrfx_ipc_init(
302226 let irq_num = usize:: from ( irq. number ( ) ) ;
303227 unsafe {
304228 cortex_m:: peripheral:: NVIC :: unmask ( irq) ;
305- ( * cortex_m:: peripheral:: NVIC :: ptr ( ) ) . ipr [ irq_num] . write ( irq_priority. into ( ) ) ;
229+ ( * cortex_m:: peripheral:: NVIC :: ptr ( ) ) . ipr [ irq_num] . write ( irq_priority) ;
306230 }
307231 IPC_CONTEXT . store ( p_context, core:: sync:: atomic:: Ordering :: SeqCst ) ;
308232 IPC_HANDLER . store ( handler as usize , core:: sync:: atomic:: Ordering :: SeqCst ) ;
@@ -316,6 +240,60 @@ pub extern "C" fn nrfx_ipc_uninit() {
316240 unimplemented ! ( ) ;
317241}
318242
243+ /// Allocate some memory from the given heap.
244+ ///
245+ /// We allocate four extra bytes so that we can store the number of bytes
246+ /// requested. This will be needed later when the memory is freed.
247+ ///
248+ /// This function is safe to call from an ISR.
249+ unsafe fn generic_alloc ( num_bytes_requested : usize , heap : & crate :: WrappedHeap ) -> * mut u8 {
250+ let sizeof_usize = core:: mem:: size_of :: < usize > ( ) ;
251+ let mut result = core:: ptr:: null_mut ( ) ;
252+ cortex_m:: interrupt:: free ( |cs| {
253+ let num_bytes_allocated = num_bytes_requested + sizeof_usize;
254+ let layout =
255+ core:: alloc:: Layout :: from_size_align_unchecked ( num_bytes_allocated, sizeof_usize) ;
256+ if let Some ( ref mut inner_alloc) = * heap. borrow ( cs) . borrow_mut ( ) {
257+ match inner_alloc. allocate_first_fit ( layout) {
258+ Ok ( real_block) => {
259+ let real_ptr = real_block. as_ptr ( ) ;
260+ // We need the block size to run the de-allocation. Store it in the first four bytes.
261+ core:: ptr:: write_volatile :: < usize > ( real_ptr as * mut usize , num_bytes_allocated) ;
262+ // Give them the rest of the block
263+ result = real_ptr. add ( sizeof_usize) ;
264+ }
265+ Err ( _e) => {
266+ // Ignore
267+ }
268+ }
269+ }
270+ } ) ;
271+ result
272+ }
273+
274+ /// Free some memory back on to the given heap.
275+ ///
276+ /// First we must wind the pointer back four bytes to recover the `usize` we
277+ /// stashed during the allocation. We use this to recreate the `Layout` required
278+ /// for the `deallocate` function.
279+ ///
280+ /// This function is safe to call from an ISR.
281+ unsafe fn generic_free ( ptr : * mut u8 , heap : & crate :: WrappedHeap ) {
282+ let sizeof_usize = core:: mem:: size_of :: < usize > ( ) as isize ;
283+ cortex_m:: interrupt:: free ( |cs| {
284+ // Fetch the size from the previous four bytes
285+ let real_ptr = ptr. offset ( -sizeof_usize) ;
286+ let num_bytes_allocated = core:: ptr:: read_volatile :: < usize > ( real_ptr as * const usize ) ;
287+ let layout = core:: alloc:: Layout :: from_size_align_unchecked (
288+ num_bytes_allocated,
289+ sizeof_usize as usize ,
290+ ) ;
291+ if let Some ( ref mut inner_alloc) = * heap. borrow ( cs) . borrow_mut ( ) {
292+ inner_alloc. deallocate ( core:: ptr:: NonNull :: new_unchecked ( real_ptr) , layout) ;
293+ }
294+ } ) ;
295+ }
296+
319297/// Call this when we have an IPC IRQ. Not `extern C` as its not called by the
320298/// library, only our interrupt handler code.
321299pub unsafe fn ipc_irq_handler ( ) {
0 commit comments