DRNadler / FreeRTOS_helpers

Helpers for some common problems when using FreeRTOS, GCC, and newlib.
140 stars 21 forks source link

Unable to compile heap_useNewlib_ST.c #9

Closed begriffs closed 2 years ago

begriffs commented 2 years ago

Environment

I realize that my newlib is outside of the tested range (2.5 - 3.1), but some of these errors appear to be syntactical, and others are related to FreeRTOS identifiers. Do I simply need to define configISR_STACK_SIZE_WORDS?

Compiler output

I copied heap_useNewlib_ST.c with the rest of the heap_ options in /usr/local/freertos-202012.04/portable/MemMang.

$ arm-none-eabi-gcc -std=c99 -pedantic -Wall -Wextra -Wshadow  -g -Os -mcpu=cortex-m4 -mthumb  -mfloat-abi=hard -mfpu=fpv4-sp-d16 -I. -I/usr/local/freertos-202012.04/include -I/usr/local/freertos-202012.04/portable/GCC/ARM_CM4F -DSTM32F4 -I/usr/local/libopencm3-1.0.0/include  -c /usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:77:4: warning: #warning is a GCC extension
   #warning "This wrapper was verified for newlib versions 2.5 - 3.1; please ensure newlib's external requirements for malloc-family are unchanged!"
    ^~~~~~~
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:77:4: warning: #warning "This wrapper was verified for newlib versions 2.5 - 3.1; please ensure newlib's external requirements for malloc-family are unchanged!" [-Wcpp]
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:117:27: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'asm'
 register char * stack_ptr asm("sp");
                           ^~~
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c: In function '_sbrk_r':
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:64:33: error: 'configISR_STACK_SIZE_WORDS' undeclared (first use in this function); did you mean 'configMINIMAL_STACK_SIZE'?
 #define ISR_STACK_LENGTH_BYTES (configISR_STACK_SIZE_WORDS*4) // bytes to reserve for ISR (MSP) stack
                                 ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:166:82: note: in expansion of macro 'ISR_STACK_LENGTH_BYTES'
         TotalHeapSize = heapBytesRemaining = (int)((&__HeapLimit)-(&__HeapBase))-ISR_STACK_LENGTH_BYTES;
                                                                                  ^~~~~~~~~~~~~~~~~~~~~~
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:64:33: note: each undeclared identifier is reported only once for each function it appears in
 #define ISR_STACK_LENGTH_BYTES (configISR_STACK_SIZE_WORDS*4) // bytes to reserve for ISR (MSP) stack
                                 ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:166:82: note: in expansion of macro 'ISR_STACK_LENGTH_BYTES'
         TotalHeapSize = heapBytesRemaining = (int)((&__HeapLimit)-(&__HeapBase))-ISR_STACK_LENGTH_BYTES;
                                                                                  ^~~~~~~~~~~~~~~~~~~~~~
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:170:13: error: 'stack_ptr' undeclared (first use in this function)
             stack_ptr   :  // Before scheduler is started, limit is stack pointer (risky!)
             ^~~~~~~~~
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c: At top level:
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:206:46: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 char * _sbrk(int incr) { return sbrk(incr); };
                                              ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:220:2: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 };
  ^                                                                               
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:228:2: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 };          
  ^          
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:235:50: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 void __env_lock()    {       vTaskSuspendAll(); };
                                                  ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:236:50: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 void __env_unlock()  { (void)xTaskResumeAll();  };
                                                  ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:253:4: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
   };
    ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:263:4: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
   };
    ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:276:2: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 };
  ^
/usr/local/freertos-202012.04/portable/MemMang/heap_useNewlib_ST.c:287:58: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
 void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {};
                                                          ^

FreeRTOSConfig.h

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#ifndef NDEBUG
    // turn assertion failures into uninterrupted loops that we can pause
    // and look at in the debugger
    #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for(;;); }
#endif

// we use this to delay blinks
#define INCLUDE_vTaskDelay              1

// IDK, but copied from most similar demo, CORTEX_M4F_STM32F407ZG-SK.
// Many other demos use 128, so should be safe.
#define configMINIMAL_STACK_SIZE        130

// the device has 128k of SRAM, and I don't know how much the kernel
// uses, so let's just say 64k for now
#define configTOTAL_HEAP_SIZE           (64 * 1024)

// we'll use FreeRTOS with newlib for the C standard library,
// so be safe: https://nadler.com/embedded/newlibAndFreeRTOS.html
#define configUSE_NEWLIB_REENTRANT      1

#define configUSE_PREEMPTION            1
#define configUSE_IDLE_HOOK             0
#define configUSE_TICK_HOOK             0

// up to us to clock the chip to match using libopencm3
#define configCPU_CLOCK_HZ              96000000

// Up to us, not mandated by the device. Sets the smallest granularity
// of time that pdMS_TO_TICKS can specify. Need at least 1khz to get
// single-ms control
#define configTICK_RATE_HZ              1e3

// we're not on a restrictive 8- or 16-bit chip
#define configUSE_16_BIT_TICKS          0

// Tasks can be assigned a priority from zero, which is the lowest priority, to
// (configMAX_PRIORITIES – 1). Better use 5 because of the Cortex M priorities
// mentioned at the end of this file.
#define configMAX_PRIORITIES            5

// For user-defined descriptive task names. Pulled 16 from an example, and
// seems fine.
#define configMAX_TASK_NAME_LEN         16

/********* Cortex-M specific magic **********
 *
 * As advised by question 1 in
 * https://www.freertos.org/FAQHelp.html#faq
 *
 ********************************************/

#ifdef __NVIC_PRIO_BITS
    /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
    #define configPRIO_BITS             __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS             4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
 * function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0xf

/* The highest interrupt priority that can be used by any interrupt service
 * routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
 * INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
 * PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
 * to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
 * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* Definitions that map the FreeRTOS port interrupt handlers to their
 * libopencm3 names */
#define vPortSVCHandler sv_call_handler
#define xPortPendSVHandler pend_sv_handler
#define xPortSysTickHandler sys_tick_handler

#endif
Xenoamor commented 2 years ago

Is this the same as the issue raised in #3 ?

DRNadler commented 2 years ago

Yes, you simply need to define configISR_STACK_SIZE_WORDS...

begriffs commented 2 years ago

I got it to compile using these changes:

However, now malloc() crashes. I'm not even able to stop in it with a breakpoint. Not sure what to do, I guess I'll go without malloc(), and avoid newlib functions that would try to call it internally.

begriffs commented 2 years ago

OK, posting that code made me read it more closely, and it looks like I'm trying to put the heap in ROM, which obviously won't work so well. :man_facepalming:

I'll try it in RAM. Still an open question of where in there. I'll probably need to leave an offset from the start.

DRNadler commented 2 years ago

Look at the example LD file I provided. I try to put as much as possible in LD, and try avoid definitions in LD and also C source as inevitably they get out of sync and cause nasty bugs. Do make sure you understand positioning of ISR stack, FreeRTOS stacks, and heap, and document it clearly in your LD... Hope that helps!