ARM-software / CMSIS_5

CMSIS Version 5 Development Repository
http://arm-software.github.io/CMSIS_5/index.html
Apache License 2.0
1.33k stars 1.08k forks source link

SVDConv peripheral array / C Code generation error #735

Open vitkorob opened 4 years ago

vitkorob commented 4 years ago

I want to generate a peripheral array (using [%s]). If the structure ends with uint16_t after uint32_t, error M219 occurs.

CMSIS-SVD SVD Consistency Checker / Header File Generator V3.3.27
Copyright (C) 2010 - 2019 ARM Ltd and ARM Germany GmbH. All rights reserved.

Arguments: "C:\projects\regmaps\hammer\CMSIS\Utilities\Win32\end_uint16_t_error.svd" -o "C:\projects\regmaps\hammer\CMSIS\Utilities\Win32" --generate=header --fields=struct --fields=macro --fields=enum -x "M216" -x "M347" -x "M317" -x "M318" -x "M356" -x "M209"

*** ERROR M219: C:\projects\regmaps\hammer\CMSIS\Utilities\Win32\end_uint16_t_error.svd
  C Code generation error: Reserved bytes calculation error!

Found 1 Error(s) and 0 Warning(s).

end_uint32_t_normal.txt end_uint16_t_error.txt

JonatanAntoni commented 4 years ago

Hi @vitkorob,

Thanks for providing the reproducers. We'll have a look to it.

Cheers, Jonatan

thorstendb-ARM commented 4 years ago

Hi @vitkorob,

can you please try the attached version 3.3.30 ?

BR, /th. SVDConv.zip

vitkorob commented 4 years ago

Hi @thorstendb-ARM, thanks for the answer.

I have tested version 3.3.30. Please see the new example end_uint16_t_unaligned.txt. Now I use <dimIncrement>32</dimIncrement> (but struct size 12) and I see unaligned RESERVED1[4]. I think real increment will be 34.

/**
  * @brief [0..1] (INFO)
  */

typedef struct {                                /*!< (@ 0xA0000000) INFO Structure                                             */
  __IM  uint16_t  PCBREV;                       /*!< (@ 0x00000000) PCBREV                                                     */
  __IM  uint16_t  DEVID;                        /*!< (@ 0x00000002) DEVID                                                      */
  __IM  uint32_t  FIRMREV;                      /*!< (@ 0x00000004) FIRMREV                                                    */
  __IM  uint16_t  DATE;                         /*!< (@ 0x00000008) DATE                                                       */
  __IM  uint16_t  RESERVED[2];
  __IM  uint32_t  RESERVED1[4];
  __IM  uint16_t  RESERVED2;
} INFO_Type;                                    /*!< Size = 12 (0xc)                                                           */
typedef INFO_Type  INFO_ARRAYType[1];           /*!< max. 2 instances available                                                */
thorstendb-ARM commented 4 years ago

Hi @vitkorob,

thank you for testing! Seems that this requires some deeper investigation, as the code generation is somehow tricky (struct/union nesting, alignment, summarizing and aligning reserved(s), check calculations if everything went ok, and so on...). In your example this looks easy, but I have to deal with the possibility to nest struct/union combinations in all possible ways :-)

Do you need this urgently or are you able to work around a while using the prev. version of SVDConv (which reports an error)? I think I can have a closer look into this in a few days.

BR, /th.

vitkorob commented 4 years ago

I am using a previous version of SVDConv with a workaround (changing uint16_t to uint32_t). I understanding the complexity of code generation. You can do it as neatly as necessary.

vitkorob commented 4 years ago

Hi @thorstendb-ARM, maybe I can help if you open source SVDConv.

JonatanAntoni commented 4 years ago

Hi @vitkorob,

Thanks for volunteering. We currently don't have plans to open source SVDConv.

Cheers, Jonatan

vitkorob commented 4 years ago

Okay. What about plans to fix this issue?

JonatanAntoni commented 4 years ago

Hi @vitkorob,

Unfortunately we won't be able to solve this on the short run. Sorry for any inconvenience.

The reason causing our alignment algorithm to fail is having the address block not fully aligned to a 32-bit border. Is it feasible for you to work around this issue for the time being with the following SVD snippet?

        <register>
          <name>DATE</name>
          <description></description>
          <dataType>uint16_t</dataType>
          <addressOffset>0x08</addressOffset>
          <size>16</size>
          <resetValue>0x00001000</resetValue>
          <access>read-only</access>
        </register>
        <register>
          <name>RES</name>
          <description></description>
          <dataType>uint16_t</dataType>
          <addressOffset>0x0A</addressOffset>
          <size>16</size>
          <resetValue>0x00000000</resetValue>
          <access>read-only</access>
        </register>
      </registers>

Adding a RES field to the end of the register block, manually. This brings the whole block back to 32-bit alignment. Now the dimIncrement should work for all values larger than 12.

Thanks, Jonatan

vitkorob commented 4 years ago

Okay, as a temporary solution, I'll use your workaround.