I was trying to create an equation that told me how many flash blocks (pages) it would take to store some data I need. This may take up exactly a certain number of Flash blocks (pages), but more likely there will be spillover and part of (well, all of) another flash block will be needed. The C preprocessor gives wrong calculations for 2 of the three methods I have tried. All 3 methods work on Compiler Explorer and the freebie IDE that comes from the chip manufacturer. Maybe there is something I am doing wrong, but so far it escapes me. Is this possibly a compiler bug?
// From stm32f1xx_hal_flash_ex.h:
// #define FLASH_PAGE_SIZE 0x400U
// From my code: **Choose only one of the NUM_ITEMS**
#define ITEM_SIZE 224UL
#define NUM_ITEMS 64 // 64*224=14336 : 14 flash blocks
#define NUM_ITEMS 66 // 66*224=14784 : 14.44 --> 15 flash blocks
// ORIGINAL MACRO: DOES NOT WORK. ALWAYS GIVES 14
#define BLOCKS_FULL ((NUM_ITEMS*ITEM_SIZE)/FLASH_PAGE_SIZE)
#define REMAINDER ((NUM_ITEMS*ITEM_SIZE)%FLASH_PAGE_SIZE)
#if REMAINDER == 0
#define NUM_BLOCKS1 BLOCKS_FULL
#define NUM_BLOCKS1 (BLOCKS_FULL+1) // Partial extra block
// ALTERNATE MACRO 1: OK (14 or 15)
#define NUM_BLOCKS2 (((NUM_ITEMS*ITEM_SIZE) + (FLASH_PAGE_SIZE-1)) / FLASH_PAGE_SIZE)
// ALTERNATE MACRO 2: NOPE, SAME ISSUE AS ORIG? ALWAYS GIVES 14
#define FLASH_TOTAL (NUM_ITEMS*ITEM_SIZE)
#define FLASH_BLOCKS (FLASH_TOTAL/FLASH_PAGE_SIZE)
#if FLASH_TOTAL == (FLASH_BLOCKS * FLASH_PAGE_SIZE)
#define NUM_BLOCKS3 FLASH_BLOCKS
#define NUM_BLOCKS3 (FLASH_BLOCKS+1)
Using default compiler version 5, C99 mode ON, Opt off (0).
I have tried all 3 of your methods in MDK v5.36 and they all work as expected.
Thank you, I appreciate it. I am on v5.34 but the problem is probably some other element of my code. Very strange...
Try what I tried, start with a clean project and check just that.
It would be very strange if such basic thing was not working correctly in preprocessor, that would have been spotted a million times before.
The trigger of the problem is most likely the number suffix "UL". The preprocessor does not know about those suffixes. Only the compiler proper does.
Method #2 works because you're not trying to use the preprocessor do evaluate the arithmetec, but rather the compiler proper.