Author Topic: Code completion and STM32 peripheral registers  (Read 1031 times)

Offline 1essor1

  • Single posting newcomer
  • *
  • Posts: 4
Code completion and STM32 peripheral registers
« on: March 19, 2017, 04:19:49 pm »
Hello!

The problem is I want to registers name being autocompleted like normal fields of a struct.
For example, I write GPIOA, then -> and bang - there should be list of GPIOA regs like MODER, OTYPER and other displayed, but nothing happens.



Registers i want access are just memory regions and GPIOA is structure describing them :
Code: [Select]
typedef struct
{
  __IO uint32_t MODER;        /*!< GPIO port mode register,                                  Address offset: 0x00 */
  __IO uint16_t OTYPER;       /*!< GPIO port output type register,                           Address offset: 0x04 */
  uint16_t RESERVED0;         /*!< Reserved,                                                                 0x06 */
  __IO uint32_t OSPEEDR;      /*!< GPIO port output speed register,                          Address offset: 0x08 */
  __IO uint32_t PUPDR;        /*!< GPIO port pull-up/pull-down register,                     Address offset: 0x0C */
  __IO uint16_t IDR;          /*!< GPIO port input data register,                            Address offset: 0x10 */
  uint16_t RESERVED1;         /*!< Reserved,                                                                 0x12 */
  __IO uint16_t ODR;          /*!< GPIO port output data register,                           Address offset: 0x14 */
  uint16_t RESERVED2;         /*!< Reserved,                                                                 0x16 */
  __IO uint32_t BSRR;         /*!< GPIO port bit set/reset registerBSRR,                     Address offset: 0x18 */
  __IO uint32_t LCKR;         /*!< GPIO port configuration lock register,                    Address offset: 0x1C */
  __IO uint32_t AFR[2];       /*!< GPIO alternate function low register,                Address offset: 0x20-0x24 */
  __IO uint16_t BRR;          /*!< GPIO bit reset register,                                  Address offset: 0x28 */
  uint16_t RESERVED3;         /*!< Reserved,                                                                 0x2A */
}GPIO_TypeDef;

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)
#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)

Maybe I'm doing something wrong? Or there is some settings i don't know...

Offline yvesdm3000

  • Almost regular
  • **
  • Posts: 223
Re: Code completion and STM32 peripheral registers
« Reply #1 on: March 19, 2017, 06:36:44 pm »
Where is this struct declared and is that #include 'd ?

Yves
Clang based code completion for Code::Blocks:   http://github.com/yvesdm3000/ClangLib

Offline 1essor1

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion and STM32 peripheral registers
« Reply #2 on: March 19, 2017, 06:55:15 pm »
GPIO_TypeDef and all defines with addresses are in stm32f0xx.h. This file included to main.c where I write code for screenshots.
« Last Edit: March 19, 2017, 07:04:15 pm by 1essor1 »

Offline Quiss

  • Multiple posting newcomer
  • *
  • Posts: 32

Offline 1essor1

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion and STM32 peripheral registers
« Reply #4 on: March 20, 2017, 09:30:42 am »
http://forums.codeblocks.org/index.php/topic,15482.0.html
Thanks for link! Yes, this situation is similar to mine.

So, there is no way to deal with this problem? Maybe some CC tweaks that help it to do macro expansion deeper? If it will take more time, it still be ok.
« Last Edit: March 20, 2017, 09:32:48 am by 1essor1 »

Offline yvesdm3000

  • Almost regular
  • **
  • Posts: 223
Re: Code completion and STM32 peripheral registers
« Reply #5 on: March 20, 2017, 02:09:42 pm »
You might try the ClangCC plugin since it's based on a real compiler, but you'll have to build clang, build the plugin and know a little bit about clang compile options since it needs compile options on its own and I don't know how compatible they are with compilation options for a cross-compiler like for STM32

Yves

Clang based code completion for Code::Blocks:   http://github.com/yvesdm3000/ClangLib

Offline 1essor1

  • Single posting newcomer
  • *
  • Posts: 4
Re: Code completion and STM32 peripheral registers
« Reply #6 on: March 20, 2017, 03:27:08 pm »
Looks interesting! I'd like to get some more information about this. Where can I find this plugin and appropriate build instructions?

Offline stahta01

  • Lives here!
  • ****
  • Posts: 5779
    • My Best Post
Re: Code completion and STM32 peripheral registers
« Reply #7 on: March 20, 2017, 06:24:43 pm »
Looks interesting! I'd like to get some more information about this. Where can I find this plugin and appropriate build instructions?

https://github.com/yvesdm3000/ClangLib
http://forums.codeblocks.org/index.php/topic,20623.msg148278.html#msg148278
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 32 bit.
On Debian Testing, compiling CB Trunk against wxWidgets 3.0.2.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline BlueHazzard

  • Lives here!
  • ****
  • Posts: 1312
Re: Code completion and STM32 peripheral registers
« Reply #8 on: March 22, 2017, 08:33:23 pm »
it is quite tricky to build on windows...
Linux is izi..

Offline stahta01

  • Lives here!
  • ****
  • Posts: 5779
    • My Best Post
Re: Code completion and STM32 peripheral registers
« Reply #9 on: March 22, 2017, 08:50:30 pm »
it is quite tricky to build on windows...
Linux is izi..

If anybody wants a Window build; I might try building  ClangLib based CC Plugin.
Please reply in this thread; because I will NOT do it unless I have someone willing to test the custom CB build I will have to make.
It will likely be a 7Zipped file that just needs to be extracted.
It will likely based on MSys2 based files/DLLs.

Anyone want a custom build by me?

Edit: It will be an Windows 32 bit build, also.
Edit2: It will also be using wxWidgets 3.0.2 multilib DLLs.

Tim S.
« Last Edit: March 22, 2017, 08:53:09 pm by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 32 bit.
On Debian Testing, compiling CB Trunk against wxWidgets 3.0.2.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 4903
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion and STM32 peripheral registers
« Reply #10 on: April 03, 2017, 05:42:46 pm »
Some news about the expression handling:
I just test a simple expression parser, which is derived from the one I found here:
Expression parsing algorithm, it's kind of operator precedence parser(precedence climbing), it looks like parsing the "type cast" is tricky  ;).

Here is the result:
Code: [Select]
Enter expression: ((a*)b).c
        c
    .
            b
        CAST
            *
                a
You see, the binary tree shows some nice results, which may help the build-in CC to resolve the correct suggesting list. The current CC does not have the ability to parse the expression which have many parentheses, so even it knows the type of GPIO_TypeDef, it still don't understand the
Code: [Select]
((GPIO_TypeDef *) GPIOA_BASE)->CodeCompletionstatements.
« Last Edit: April 03, 2017, 05:44:32 pm by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline icequan233

  • Multiple posting newcomer
  • *
  • Posts: 31
Re: Code completion and STM32 peripheral registers
« Reply #11 on: April 04, 2017, 05:11:17 am »
it is quite tricky to build on windows...
Linux is izi..

If anybody wants a Window build; I might try building  ClangLib based CC Plugin.
Please reply in this thread; because I will NOT do it unless I have someone willing to test the custom CB build I will have to make.
It will likely be a 7Zipped file that just needs to be extracted.
It will likely based on MSys2 based files/DLLs.

Anyone want a custom build by me?

Edit: It will be an Windows 32 bit build, also.
Edit2: It will also be using wxWidgets 3.0.2 multilib DLLs.

Tim S.
@Tim, I want to try this plugin, but my C::B is built by wx3.1, can you give me your C::B built with wx3.0.2, I don't want to build cb again. Thanks.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 4903
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion and STM32 peripheral registers
« Reply #12 on: April 16, 2017, 03:21:16 pm »
Some progress about the code suggestion on a complex expression.
Code: [Select]
((GPIO_TypeDef*)((((uint32_t)0x40000000)+0x08000000)+0x00000000))->CCThis is the code when the parser actually see:
Code: [Select]
((GPIO_TypeDef *) GPIOA_BASE)->CCNow, here is the tree for code completion.
Code: [Select]
        CC
    ->
            (((uint32_t)0x40000000)+0x08000000)+0x00000000
        CAST
            *
                GPIO_TypeDef
For a type cast node(which shows "CAST" above), only the left tree is interesting, so tree traversal could have some steps
1, get the GPIO_TypeDef
2, get the pointer to GPIO_TypeDef
3, get the member of GPIO_TypeDef
With the step 3, you will list all the members of the GPIO_TypeDef.

The problem is that my test code is just some standalone program, it should be integrated(maybe replace) into the CC's source code, so there may be a lot of code changes.  :(
« Last Edit: April 17, 2017, 01:54:21 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 4903
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion and STM32 peripheral registers
« Reply #13 on: April 19, 2017, 05:08:35 pm »
I wrote a CC test case:
Code: [Select]
//Code completion and STM32 peripheral registers -
//http://forums.codeblocks.org/index.php/topic,21823.msg148685.html#msg148685

#define __IO

typedef struct
{
  __IO uint32_t MODER;        /*!< GPIO port mode register,                                  Address offset: 0x00 */
  __IO uint16_t OTYPER;       /*!< GPIO port output type register,                           Address offset: 0x04 */
  uint16_t RESERVED0;         /*!< Reserved,                                                                 0x06 */
  __IO uint32_t OSPEEDR;      /*!< GPIO port output speed register,                          Address offset: 0x08 */
  __IO uint32_t PUPDR;        /*!< GPIO port pull-up/pull-down register,                     Address offset: 0x0C */
  __IO uint16_t IDR;          /*!< GPIO port input data register,                            Address offset: 0x10 */
  uint16_t RESERVED1;         /*!< Reserved,                                                                 0x12 */
  __IO uint16_t ODR;          /*!< GPIO port output data register,                           Address offset: 0x14 */
  uint16_t RESERVED2;         /*!< Reserved,                                                                 0x16 */
  __IO uint32_t BSRR;         /*!< GPIO port bit set/reset registerBSRR,                     Address offset: 0x18 */
  __IO uint32_t LCKR;         /*!< GPIO port configuration lock register,                    Address offset: 0x1C */
  __IO uint32_t AFR[2];       /*!< GPIO alternate function low register,                Address offset: 0x20-0x24 */
  __IO uint16_t BRR;          /*!< GPIO bit reset register,                                  Address offset: 0x28 */
  uint16_t RESERVED3;         /*!< Reserved,                                                                 0x2A */
}GPIO_TypeDef;

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)
#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)


//GPIOA->MO      //MODER

And running this test case, I get the tree printed in the log window:
Code: [Select]
...
...
000079.         MO
000080.     ->
000081.             ((((uint32_t)0x40000000)+0x08000000)+0x00000000)
000082.         CAST
000083.             *
000084.                 GPIO_TypeDef

So, I use the Tokenizer to preprocess the tokens of the statement "GPIOA->MO".

Now, the next step is: try to traverse the tree, and make the type resolving. Some code should be changed, such as the below function:

Code: [Select]
// Here's the meat of code-completion :)
// This function decides most of what gets included in the auto-completion
// list presented to the user.
// It's called recursively for each component of the std::queue argument.
// for example: objA.objB.function()
// The queue is like: 'objA' 'objB' 'function'. We deal with objA first.
//
// No critical section needed in this recursive function!
// All functions that call this recursive function, should already entered a critical section.
size_t NativeParserBase::FindAIMatches(TokenTree*                  tree,
                                       std::queue<ParserComponent> components,
                                       TokenIdxSet&                result,
                                       int                         parentTokenIdx,
                                       bool                        isPrefix,
                                       bool                        caseSensitive,
                                       bool                        use_inheritance,
                                       short int                   kindMask,
                                       TokenIdxSet*                search_scope)
{
Note that the second parameter "std::queue<ParserComponent> components" should be replaced by the tree.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.