Search code examples
armembeddedcortex-m

Is there a difference between how integers are interpreted between the Cortex M0 and M3 platforms?


I am moving my build system over to use the CMSIS files for the stm32F1 (from stm32F0) which is a cortex-m3 chip, and I am running into the following error when I try to compile core_cm3.h.

This is the function which is part of the core CMSIS:

static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
{
  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
  uint32_t PreemptPriorityBits;
  uint32_t SubPriorityBits;

  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
 
  return (
           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
         );
}
Error: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Werror=sign-conversion]
((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) 
                  ^ 

I am surprised there are issues compiling, since this is a core file with no changes made, and up to date. In addition, from what I've read online the same compiler (arm-none-eabi) can be used for the whole 'M' family. Is there some quirk about how integers are interpreted here I'm missing?


Solution

  • The size and representation of integers and long integers is the same between ARMv6M (including CortexM0) and ARMv7M (including CortexM3).

    The warning message you are getting is because the compiler thinks (1 << PreemptPriorityBits) could be negative (specifically if PreemptPriorityBits equals 31) but it then gets converted to unsigned type to be masked with PreemptPriority.

    In reality PreemptPriorityBits will always be less than or equal to 8, so nothing can ever be negative here. This means that in the short term you can just ignore the warning.

    If this warning were in your own code I would advise you to just change 1 << to 1u << which would produce the same binary output but tell the compiler there is nothing to worry about.

    In fact I notice that this exact change has already been made in the oldest version of CMSIS I can easily find a copy of (5.0.0 from September 2016). It looks like you are running some very old code against a new version of the compiler that it was not written for.

    I strongly suggest that you upgrade to a later version of CMSIS headers. Although this change is non-functional (an identical binary will be output) there have been a great many other changes made in the last 6 years which do matter and some which fix significant bugs.