cancel
Showing results for 
Search instead for 
Did you mean: 

STM8 Standard Library and Cosmic produces huge code?

Willunen
Associate III

I'm using ST Visual develop and Cosmic to program a STM8S003K3 and I'm thought it would be nice to use the STM8 Standard Library (downloaded from ST.COM).

Within a very short time I got errors telling me that I tried to put more code in the MCU than possible (8K). I hadn't even finished the initialization of all the peripherals I intend to use.

So I took a look at the compiler settings and changed the optimizations from None to Minimize Code Size.

That did help.

For a few minutes.

A look at the map file shows this: (not the entire file)

                              --------
                               Segments
                               --------
 
start 00008080 end 00008103 length   131 segment .const
start 00008106 end 00009bab length  6821 segment .text
start 00004000 end 00004000 length     0 segment .eeprom
start 00000000 end 00000000 length     0 segment .bsct
start 00000000 end 0000000a length    10 segment .ubsct
start 0000000a end 0000000a length     0 segment .bit
start 0000000a end 0000000a length     0 segment .share
start 00000100 end 00000100 length     0 segment .data
start 00000100 end 00000100 length     0 segment .bss
start 00000000 end 00000584 length  1412 segment .info.
start 00008000 end 00008080 length   128 segment .const
start 00008103 end 00008106 length     3 segment .init
 
 
                               -------
                               Modules
                               -------
 
C:\Program Files (x86)\COSMIC\FSE_Compilers\CXSTM8\Lib\crtsi0.sm8:
start 00008106 end 00008156 length    80 section .text
start 00000100 end 00000100 length     0 section .bss
start 00000000 end 00000000 length     0 section .ubsct
start 00000000 end 00000034 length    52 section .info.
 
Release\main.o:
start 00008156 end 000081da length   132 section .text
start 00000034 end 000000c0 length   140 section .info.
 
Release\stm8s_it.o:
start 000081da end 000081ef length    21 section .text
start 000000c0 end 00000150 length   144 section .info.
 
Release\stm8s_clk.o:
start 000081ef end 000087a3 length  1460 section .text
start 00000150 end 000001e1 length   145 section .info.
start 00008080 end 000080b3 length    51 section .const
 
Release\stm8s_gpio.o:
start 000087a3 end 000088a1 length   254 section .text
start 000001e1 end 00000273 length   146 section .info.
start 000080b3 end 000080db length    40 section .const
 
Release\stm8s_tim1.o:
start 000088a1 end 00009a60 length  4543 section .text
start 00000273 end 00000305 length   146 section .info.
start 000080db end 00008103 length    40 section .const

The timer1 initialization takes 4k ?

This is worth 4k ?

static void TIM1_Config(void)
{
  TIM1_DeInit();																		
  TIM1_TimeBaseInit(15999, TIM1_COUNTERMODE_UP, 999, 0);
  TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
  TIM1_ARRPreloadConfig(ENABLE);
  TIM1_Cmd(ENABLE);
}

Do I have to go back to "bare-metal" register setting?

Now I'm only just starting with STM8, so it is more than likely that I'm doing something very wrong, am I?

Wilko

30 REPLIES 30
Xavi92
Associate II

@pacman​ @Community member​ @cs​ , we have created a fork of SDCC and stm8-binutils-gdb and we achieved:

  • Compile *.c files in GNU as format.
  • Link-time dead code elimination by splitting symbols into their own section, as well as implementing --gc-sections on stm8-ld.
  • Better compatibility with other tools from the GNU binutils package such size, nm, objdump, etc.

Since these changes are experimental, they have not been included into SDCC's main branch yet. See the links below for further reference.

https://github.com/XaviDCR92/sdcc-gas/

https://github.com/XaviDCR92/stm8-binutils-gdb/

See the link below for a small example:

https://github.com/XaviDCR92/stm8-dce-example/

So there is no longer need to use Cosmic or other propietary tools (unless you are doing it for other reasons), as SDCC now has total compatibility with the GNU toolchain and no longer depends on its custom *.rel object file format. Please provide me any questions or feedback you might have.

I think this is a very good opportunity to make SDCC the best available option for the STM8 among the existing compilers.

@Xavi92 - you, sir, definitely deserve some respect - both for replying to this thread and for all the work you've done. I will definitely have a look at all the links you've provided. Thank you on several levels! :)

I've attempted to build stm8-binutils. It seems that at least gcc-4.8 is required (gcc-4.2.1 fails, so I stepped up first to 4.8, then 4.9).

Unfortunately, I get the following errors (both with gcc-4.8 and 4.9):

elf32-stm8.c:252:5: error: ‘BFD_RELOC_STM8_LO8’ undeclared here (not in a function)
   { BFD_RELOC_STM8_LO8,             R_STM8_LO8},
     ^
elf32-stm8.c:253:5: error: ‘BFD_RELOC_STM8_HI8’ undeclared here (not in a function)
   { BFD_RELOC_STM8_HI8,             R_STM8_HI8},
     ^
elf32-stm8.c:254:5: error: ‘BFD_RELOC_STM8_HH8’ undeclared here (not in a function)
   { BFD_RELOC_STM8_HH8,             R_STM8_HH8},
     ^

-Do those errors sound familiar ?

(I'm using the cloned repositories, so I quickly found out I should not attempt to patch the binutils before configuring).

-Also, the web-site 'https://stm8-binutils-gdb.sourceforge.io/', I had to access via a proxy (vpnbook.com), because both Safari and Firefox complained that it was insecure and that I could not be allowed access (by the browser) before the issue has been fixed by the site-owner.

@pacman​ That's my fault, I'm sorry. Those missing definitions should be already there when calling "make", but for some unknown reason "cd bfd/ && make headers" had to be executed first. BTW, is there any reason why you are still using gcc-4.8? That version is 6 years old, whereas most Linux distros are currently shipping with gcc-7 or even gcc-8.

Anyway, I have cleaned up the whole repository in order to reduce server storage and also provided new patches that already provide these missing references, so this issue should not occur anymore. Please follow the instructions at https://github.com/XaviDCR92/stm8-binutils-gdb .

OTOH, I am surprised you got that (presumably) SSL certification check error, since that site is hosted on Sourceforge and I did not have any problems when accessing it from Firefox. In any case, everything you need is already included on my repository.

@Xavi92 - much better, I got a lot further.

(I'm still using old versions of gcc, as I haven't built versions 5.x and above; it's not a trivial task on my system, as I have to fix many build-errors first, then I have to make it build-farm compatible, so builds can be distributed and finally build it for the farm; it takes time and I'm only doing this when there is no easier solution).

... Back to the topic...

As I don't have wget (won't build on my system), I performed 'patch_binutils.sh' manually.

-I didn't pay much attention the first time, but found out that the depacking order is important. I have a suggestion for a short modification:

which wget 2>/dev/null 1&>2 && dl="wget -nc" || dl="curl -OLk --retry 5"
$dl ftp.gnu.org/gnu/binutils/binutils-2.30.tar.xz
$dl ftp.gnu.org/gnu/gdb/gdb-8.1.tar.xz

-That should work on more systems; even those that have SSL problems.

I get the following errors, which are related to 'C99'; I guess that the newer versions of gcc default to C99 or C11 ?

stm8-dis.c: In function ‘stm8_dis’:
stm8-dis.c:391:4: error: ‘for’ loop initial declarations are only allowed in C99 mode
    for (int curr_operand = 0; curr_operand < stm8_num_opcode_operands(stm8_opcodes[i]); curr_operand++)
    ^
stm8-dis.c:391:4: note: use option -std=c99 or -std=gnu99 to compile your code
stm8-dis.c:404:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
     for (int j = 0; j < stm8_num_opcode_operands(stm8_opcodes[i]); j++, operand += dir)
     ^

make CFLAGS=--std-gnu11 && sudo make install seem to fix this problem

(I could use gnu99, but I picked gnu11, since --std=gnu++11 is used elsewhere).

... After that, I got a new error;

infcall.c
dwarf2read.c: In member function ‘void debug_names::build()’:
dwarf2read.c:26088:32: error: ‘log2’ is not a member of ‘std’
       (std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
                                ^

Picking the quick solution: in dwarf2read.c, change std::log2 to log2, rebuild.

After that, it seems it builds and installs.

stm8-ld --version | head -n 1; stm8-gdb --version | head -n 1
GNU ld (GNU Binutils) 2.30
GNU gdb (GDB) 8.1

sdcc-gas is not installing any binaries (yet), I've started by disabling pic*, z80 and hc08, but it still doesn't complete the build. I'll return later, if/when I find a fix.

If I disable packihx, ucsim and all the ports except for STM8, then it builds. =)

I'm able to build both under gcc-4.8.5 and gcc-4.9.4.

sdcc --version | head -n 1
SDCC : stm8 0.0.0 #11345 (Mac OS X x86_64)

... And the stm8-dce-example gives the expected output, so it look like it's a working toolchain. :)

GCC4-x does not like C99 way of defining variables inside 'for' loops for some reason, yet apparently other C99 features such as compound literals or designated initializers are supported out of the box. In any case, it was easy enough to provide a new patch that uses ANSI C code instead, and also fixed a typo in stm8-opc.c that generated a missing operand error from the assembler. I added the changes you suggested to patch_binutils.sh, too. OTOH, std::log2() was added on C++11, so g++-4.8 might not support it.

I am glad the solution worked for you! @cs​ , I know there is already an accepted answer and you originally asked about cxstm8, but have you tried out SDCC instead?

Now it works very well, apart from a typo I introduced (sorry!).

which wget 2>/dev/null 1&>2 && dl="wget -nc" || dl="curl -OLk --retry 5"

In the above line, '1&>2' should have been '1>&2'.

I have another recommendation: for 'tar', it's good to specify xJf (or xJvf) if you're extracting .xz files, because on some systems, tar does not automatically detect xz. I didn't notice this at first, because I have a lovely frankenOSX.

I can now just run patch_binutils, then a sed-line to modify dwarf2read.c, followed by configure_binutils.sh, then make without specifying extra CFLAGS; very neat.

The std::log2 might be a libstdc++ thing, so I could/should probably just get an updated library there.

Now the only thing left is to get OpenOCD built; I've avoided this for the past few years as 10.0 made it incompatible with gcc-4.2, but STM8 support is too valuable to say no to... =)

I had a look inside the Makefile for the dce example; is the following line correct ...

LIBS = $(apprefix -l, stm8 stm8s)

... or was it intended to be addprefix ?

I have updated patch.binutils.sh with your suggestions.

Definitely LIBS definition is wrong and it was meant to be 'addprefix' instead. However, SDCC's run-time libraries are still being compiled in their own *.rel object file format, so https://github.com/XaviDCR92/sdcc-gas building process should be modified to compile such libraries in ELF format too. As a quick workaround, I copied the library sources into my project and compiled them there. Therefore, LIBS is doing no harm, either. =)

Also, the SDCC fork got some new bugfixes that might interest you.