4

I’m trying to port an application written for a micro to Visual Studio so I can more easily run the debugger and scan through the code, rather than debug on the chip which is a bit of a pain when you want to learn how the application was written. I’m not at all a programming guru, and I keep getting this error, listed below, which is related to a structure:

error C2059: syntax error : '.'

The code is listed below, can anyone point me in the right direction.

typedef struct usart_reg_map 
{
    volatile uint32 SR;
    volatile uint32 DR;
    volatile uint32 BRR;
    volatile uint32 CR1;
    volatile uint32 CR2;
    volatile uint32 CR3;
    volatile uint32 GTPR;
}usart_reg_map;

#define USART1_BASE ((struct usart_reg_map*))

typedef struct usart_dev 
{
    usart_reg_map *regs;
}usart_dev;

struct usart_dev usart1 =
{
    .regs = USART1_BASE, 
};

usart_dev *USART1 = &usart1;
  • @MortenJensen They do intend to, they have made the attempt in 2017-2018. But failed to get it compliant. While all other compilers fixed this correctly, 20 years before Microsoft. –  Feb 01 '19 at 13:49
  • EDIT: I just noticed the formatting is terrible, how can this be cleared up? –  Feb 01 '19 at 11:02
  • No, can you point it out. –  Feb 01 '19 at 11:20
  • 2
    It's probably `.regs = USART1_BASE,` which looks non-standard, but none of that UART code is going to work on a PC without a bunch of changes. – PeterJ Feb 01 '19 at 11:21
  • 3
    @PeterJ it is a `designated initializer`. The OP should make sure that compiler flags are set to support C99 which is the standard that added this. –  Feb 01 '19 at 11:23
  • Ok, got it C99. Yes PeterJ the error is .regs = USART1_BASE I just forgot to point it out. How do I make the change to Visual Studio IDE. I know I can start searching on it if the answer is not obvious. –  Feb 01 '19 at 11:27
  • 4
    My main point is if it compiles it won't work anyway on a PC - when you try to access 0x40013800 you'll get an access violation because that's not where a PC UART is and under Windows you need to access a com port an entirely different way, for example you open it with a Win32 `CreateFile` call. – PeterJ Feb 01 '19 at 11:31
  • PeterJ I was planning on removing that address (done), and simply allow the compiler to set the address. I only want to step through the actual code as an exercise. –  Feb 01 '19 at 11:34
  • Also, thanks to you both for your help, I'll get on to the C99 setting. –  Feb 01 '19 at 11:39
  • 1
    Visual Studio does not fully support C99 and does not intend to. I would strongly advice you to consider using another compiler, e.g. GCC. – Morten Jensen Feb 01 '19 at 13:40
  • 1
    Overall, it rather sounds like you should invest in a better in-circuit debugger for your MCU. Trust me, there is no better way to learn than to run the code on the actual hardware. It sounds like the root of your problem is some toxic tool chain like Eclipse, in which case the solution is to get something better. –  Feb 01 '19 at 14:00
  • @Lundin no they actually do not intend to do so. They intend to support "most of C99/C11 that is a subset of ISO C++98/C++11.". From the horse's own mouth: https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/ – Morten Jensen Feb 01 '19 at 14:44
  • This question belongs on Stack Overflow. It's a C programming question. While some languages are within scope here at Super User, C isn't one of those, and this is entirely a syntax issue. I have protected the question to prevent "me too" answers from being submitted. – Ramhound Feb 05 '19 at 11:20

3 Answers3

2

There's two issues to consider:

  • Most likely you are compiling the code as C++. But C++ is not C and vice versa - they are not compatible languages. You need to enforce C compilation, which is typically done by naming your file .c instead of .cpp.

  • Even in C mode, Visual Studio has horrible support for standard C. The . initialization syntax is known as designated initializers and was introduced in the language year 1999. Microsoft has however insisted not to upgrade their C compiler, until some half-hearted attempt a few years ago. They may or may not support designated initializers, I don't know.

I would strongly recommend any beginner programmer to use a standard-compilant compiler instead. You can tell VS to use the gcc compiler instead of the default crap one, or you can download another IDE such as Codeblocks, which comes with gcc/mingw pre-installed per default.

1

In all cases it is a lot of work, but it is possible:

  1. Find out which classes, structures, types and functions you need from the micro libaries.
  2. Create files for them, similar to the micros libraries, preferably about the same file structure, but in a different location. These will only run in the PC version.
  3. Create a new project for the non micro environment, where the files in step 2 are used instead of 1. This can be done by changing the include path probably.

In step 2, you can make even some intelligence in the functions if you want to test that. Also you do not need to change any file that runs on the micro that you created yourself, because only the micro libraries have a PC counterpart.

About C99, make sure that you don't use C99 specific features in the generic code (your microcontroller code), and if you need it, make that code in separate functions which you could either port to VS, or maybe they are not needed as they are part of the microcontroller libraries or facade functions.

Michel Keijzers
  • 439
  • 2
  • 9
  • 21
  • Good advice Michel. –  Feb 01 '19 at 12:11
  • about C99, make sure that you don't use C99 specific features in the generic code (your microcontroller code), and if you need it, make that code in separate functions which you could either port to VS, or maybe they are not needed as they are part of the microcontroller libraries or facade functions. – Michel Keijzers Feb 01 '19 at 12:07
  • Yep, your correct, its a lot of work. I just read in another post C99 is not supported in VS for C, so I just lost my enthusiasm, as there are dozens of these structures and some are very lengthy. –  Feb 01 '19 at 12:02
  • but you only need to add what you use directly. What you also could do but its also tricky is to make some generic functions with input parameter types which are known by both the microcontroller and VS, and in the microcontroller map them to the real microcontroller types; this means you have to make extra 'facade' classes/functions in between. – Michel Keijzers Feb 01 '19 at 12:04
0

Your specific problem is because, as you have discovered, the designated initializer .regs = USART1_BASE does not work in Visual Studio.

I usually use GCC and a makefile when testing my microcontroller projects on windows. This seems to work a lot better when trying to use features from a specific standard like C99.

As others have pointed out, you will likely have to do a lot of refactoring to make your entire project actually run on Windows. I usually break my project up into simple modules that I can compile and test on Windows with GCC, and then combine those well tested modules into a larger app that I can run and test on the target device.

cholz
  • 1
  • 1