shkolnick-kun / bugurtos

Breaking backward compatibility since 2010!!!
GNU General Public License v3.0
132 stars 9 forks source link

SDCC STM8 port #13

Closed spth closed 8 years ago

spth commented 8 years ago

It seems, currently the STM8 is supported via the non-free IAR and Raisonance compilers only. The free C compiler SDCC supports STM8 since the 3.4.0 release in 2014.

Philipp

shkolnick-kun commented 8 years ago

Hi, Philipp! I'm sorry, but SDCC has very poor support of STM8, lack of docs, and yes, regressions are too often when we talk about SDCC.

I really like FREE software, but SDCC is a piece of c%#p!

shkolnick-kun commented 8 years ago

Sorry, I had a really BAD DAY!!! I shouldn't follow my anger!

In case of SDCC I have many unanswered quiestions:

  1. What code/data memory models are supported, what are plans for support of different code/data models?
  2. What is the working register concept, where can I read about it, will it be changed sometimes later?
  3. How does program execution get started in case of SDCC?
  4. Does SDCC support something like -ffunction-sections, -fdata-sections, and does linker support something like --gc-sections, what are plans?
  5. How about linker scripts?
  6. How about SWIM-debug support in debuger?
  7. Does SDCC have a simulator for STM8 core?
  8. If "Yes", then does it support debug and interrupts?
spth commented 8 years ago

On 29.12.2015 15:25, shkolnick-kun wrote:

Hi, Philip! I'm sorry, but SDCC has very poor support of STM8, lack of docs, and yes, regressions are too often when we talk about SDCC.

I really like FREE software, but SDCC is a piece of c%#p!

Sorry, but this does not look like an accurate characterization of the current state of SDCC when using the STM8 backend to me. Maybe you looked at something else (the old ST7/STM8 fork which at least for STM8 never got into a working state? The pic14 backend of SDCC? The STM8 backend in SDCC about 18 months ago?).

SDCC has regression tests (which include most of GCC's regression tests). Every night, SDCC is build on a variety of machines, and the regression tests are compiled an executed in the simulator. Results can be seen e.g. when clicking the litte green or red stars on the right side at http://sdcc.sourceforge.net/snap.php As you can see, currently all stars are green (which means all tests passed for all backends excluding pic14, pic16, tlcs90), with the exception of the x86_64-w64-mingw32 build, which AFAIK, is a problem with the machine executing the tests.

In terms of standard support SDCC still isn't up to GCC, but doing rather well compared to the other compilers for STM8: SDCC has (somewhat incomplete) support for C89/C90, C95, C99, C11. In particular, SDCC now supports all features introduced in C11 except for string literals of types char16_t and char32_t. IAR has better support for C89/C90 and C99 than SDCC. But AFAIK, SDCC does similar or better than Cosmic and Raisonance in C89/C90 support. No compiler other than SDCC even tries to support C11 or C95. IAR and SDCC are the only ones with C99 support.

On the other hand the STM8 backend in SDCC still is relatively new, and there is still a lot to be done.

Philipp

P.S.: I'm an SDCC developer, so I might be a bit biased when comparing SDCC to the other compilers. And I did most of the work on the stm8 backend, so the things that I cared about most are what got implemented first, so from my perspective SDCC is doing great, but for people who care more about other aspects the situation might be different.

shkolnick-kun commented 8 years ago

Dear @spth!

Yes, I looked at SDCC about 2 years and about a year ago.

At that time SDCC stm8 support wasn't in a good state, and I stoped to track SDCC project after I saw some bugs been opened for months or even years...

Now I've locked at SDCC-bug tracker on SF, and I think that You've made a great afford on fixing these things!

What about these questions?

spth commented 8 years ago

On 29.12.2015 16:07, shkolnick-kun wrote:

Sorry, I had a really BAD DAY!!! I shouldn't follow my anger!

Sorry for taking so long to reply. But with my 19 months old son around, it is sometimes hard to find a bit of free time. While I'm an SDCC developer, and wrote most of the STM8 stuff in the compiler, I am not that familiar with all the supporting stuff, such as linker and simulator.

In case of SDCC I have many unanswered quiestions:

  1. What code/data memory models are supported, what are plans for support of different code/data models?

Currently the only model supported is a 16-bit address space. Given the architecture, this seems to be by far the best memory model, and support for any others won't come anytime soon. However, support for 24-bit addresses via far-qualified pointers and support for code outside of the 16-bit address space via banked-qualified functions is planned.

  1. What is the working register concept, where can I read about it, will it be changed sometimes later?

The register allocator can use A,X,Y any way it wants. The only exception are functions with large or many local variables (i.e. there are variables on the stack outside the range of sp-relative addressing modes), when Y is used as frame pointer. All registers are saved by the caller. None of these is likely to change. Currently, all parameters are passed on the stack. This will probably change in the future.

  1. How does program execution get started in case of SDCC?

Global variables are initialized. If the program uses memory management, the heap data structured are initialized. Then program execution starts at main().

  1. Does SDCC support something like -ffunction-sections, -fdata-sections, and does linker support something like --gc-sections, what are plans?

None of these are supported. The functionality would be nice to have, but is currently not top priority. Currently, if you want unused stuff to not end up in your binary, it has to be in separate modules in a library.

  1. How about linker scripts?

I am not that familiar with the linker, so I don't know.

  1. How about SWIM-debug support in debuger?

Currently, there is no free software solution for debugging STM8 via ST-Link yet. However, SDCC added support for ELF/DWARF output for STM8 just a few days ago, which should allow to debug SDCC-compiled programs in non-free STVD.

  1. Does SDCC have a simulator for STM8 core?

Yes.

  1. If "Yes", then does it support debug and interrupts?

Debugging stuff like breakpoints should work. Don't know about interrupts. I don't really use the simulator, apart from it being involved in regression testing.

Philipp

shkolnick-kun commented 8 years ago

Currently the only model supported is a 16-bit address space. Given the architecture, this seems to be by far the best memory model, and support for any others won't come anytime soon. However, support for 24-bit addresses via far-qualified pointers and support for code outside of the 16-bit address space via banked-qualified functions is planned.

So, CALL and RET instructions are used... This effectively limits code size to 32k, as FLASH starts from 0x8000 and lower adresses are used for RAM, etc. I'm not familiar with SDCC internals but I would recommend using CALLR, RERF, and relative jump instructions instead, this should lead to 64k position independent code "out of the box", and if you use jump tables, then longer executables may be supported...

The register allocator can use A,X,Y any way it wants. The only exception are functions with large or many local variables (i.e. there are variables on the stack outside the range of sp-relative addressing modes), when Y is used as frame pointer. All registers are saved by the caller. None of these is likely to change. Currently, all parameters are passed on the stack. This will probably change in the future.

So, no "virtual geristers" are used. As I understand, you don't generate any special ISR prologues and epilogues. If you change this behavior, you should make people know about that, it's very important for low level programmers!

Currently, there is no free software solution for debugging STM8 via ST-Link yet. However, SDCC added support for ELF/DWARF output for STM8 just a few days ago, which should allow to debug SDCC-compiled programs in non-free STVD.

Thanks for the tip, @spth! It should help!

As I saw, STVD uses gdb for debug, but I couldn't find the sources for gdb and other GNU stuff in st-toolset, so this is likely to be a GPL violation...

Debugging stuff like breakpoints should work. Don't know about interrupts. I don't really use the simulator, apart from it being involved in regression testing.

Interrupt support is essential for OS-kernel testing, cause OS is all about interrupts. But with previous tip I could use hardware and STVD.

Is it possible to use SDCC as cross-tooolchain in STVD? I haven't seen much customization there...

spth commented 8 years ago

SDCC does not use virtual registers, and there are no plans to use any in the future. I don't see any real use for them. SDCC does not generate any special ISR epilogue apart from the "iret". Unless SDCC can be sure that the ISR does not contain divisions it generates prologue to work around the hardware bug documented in section "Unexpected DIV/DIVW instruction result in ISR" in various STM8 errata.

Philipp

spth commented 8 years ago

On 30.12.2015 05:21, shkolnick-kun wrote:

Is it possible to use SDCC as cross-tooolchain in STVD? I haven't seen much customization there...

ST is aware of SDCC (they even sent me a few eval boards for SDCC development a week ago). Maybe they'll support SDCC in STVD at some point in the future, if SDCC seems important enough for them.

Philipp

spth commented 8 years ago

On 30.12.2015 05:21, shkolnick-kun wrote:

As I saw, STVD uses gdb for debug, but I couldn't find the sources for gdb and other GNU stuff in st-toolset, so this is likely to be a GPL violation...

Providing the source the same way as the binary is IMO easiest. But AFAIK for GPL compliance, providing the source on request is sufficient.

Philipp

spth commented 8 years ago

On 30.12.2015 05:21, shkolnick-kun wrote:

So, CALL and RET instructions are used... This effectively limits code size to 32k, as FLASH starts from 0x8000 and lower adresses are used for RAM, etc.

Yes.

I'm mot familiar with SDCC internals but I would recommend using CALLR, RERF, and relative jump instructions instead, this should lead to 64k position independent code "out of the box", and if you use jump tables, then longer executables may be supported...

This would make sense to add as an additional memory model. I'll put it onto my todo list. On the compiler side the main effort would be the handling of 24-bit wide function pointers.

A few question on this (since I haven't used code outside the lower 64K so far):

Philipp

spth commented 8 years ago

Also, stm8flash, the AFAIK only free tool for use with the ST-Link, apparently cannot write flash outside the lower 64K yet (see https://github.com/shkolnick-kun/bugurtos/issues/13). There are other free tools to write the flash memory using a serial interface and the integrated bootloader (some, but not all STM8 have a bootloader that is active for a short time after reset).

Philipp

shkolnick-kun commented 8 years ago

SDCC does not use virtual registers, and there are no plans to use any in the future. I don't see any real use for them. SDCC does not generate any special ISR epilogue apart from the "iret". Unless SDCC can be sure that the ISR does not contain divisions it generates prologue to work around the hardware bug documented in section "Unexpected DIV/DIVW instruction result in ISR" in various STM8 errata.

So prologue is just CCR manipulations, and epilogue is IRET, nice!

Vregs in page0 may be usefull in case of 24bit pointers and in case of handling long data types, as page0 have single cycle access time, arch becomes more RICS-like. But in case of vregs there must be more compleх function calling conversions and ISR-prologues/epilogues...

This would make sense to add as an additional memory model. I'll put it onto my todo list. On the compiler side the main effort would be the handling of 24-bit wide function pointers. A few question on this (since I haven't used code outside the lower 64K so far): * Can relative jumps cross the (64K) segment boundaries? It is not clear to me from the STM8 documentation. If no, the linker would have to ensure that functions are placed to not cross the boundaries (on the otehr hand we could still use jp instead of jpf for intra-function jumps outside the range of relative jumps). * You say this would lead >to 64K position independent code. Shouldn't it work the same for the whole code space, even outside >of 64K (so we could fully use the 128K flash some STM8 have for code)?

Sorry, @spth, I've misunderstood STM8 instruction set docs. CALLR and JRxx instructions may have only 8bit signed offset, so you may forget what I wrote.

But it would be nice to finally have something like IARs medium code model...

Suddenly I failed to compile blinky example with Code::Blocks 10.05 and sdcc-snapshot-i586-mingw32msvc-20151226-9428.zip, here's a log:

Compiling: blinky.c
Caught signal 11: SIGSEGV
sdcc: Calling preprocessor...
sdcc: sdcpp.exe -nostdinc -Wall -std=c11 -I"C:\sdcc\include" -obj-ext=.rel -D__SDCC_STACK_AUTO -D__SDCC_INT_LONG_REENT -D__SDCC_FLOAT_REENT -D__SDCC=3_5_5 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=5 -D__SDCC_VERSION_PATCH=5 -DSDCC=355 -D__SDCC_REVISION=9428 -D__SDCC_stm8 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem "C:\Temp\sdcc\bin\..\include\stm8" -isystem "C:\Temp\sdcc\bin\..\include"  "blinky.c" 
sdcc: Generating code...
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings

So I'll focus on BuguRTOS-0.9.9...1.0.0, finally ELF/DWARF feature will get stable, then I probably write SDCC STM8 port :)

spth commented 8 years ago

On 30.12.2015 15:19, shkolnick-kun wrote:

SDCC does not use virtual registers, and there are no plans to use
any in the future. I don't see
any real use for them. SDCC does not generate any special ISR
epilogue apart from the "iret".
Unless SDCC can be sure that the ISR does not contain divisions it
generates prologue to work
around the hardware bug documented in section "Unexpected DIV/DIVW
instruction result in ISR"
in various STM8 errata.

So prologue is just CCR manipulations, and epilogue is IRET, nice!

Vregs in page0 may be usefull in case of 24bit pointers and in case of handling long data types, as page0 have single cycle access time, arch becomes more RICS-like. But in case of vregs there must be more compleх function calling conversions and ISR-prologues/epilogues...

According to the architecture manual, page 0 (lower 256 bit) has single cycle access, but so do segment 0 (lower 64K) and SP-relative addressing. Code size is the same for page 0 and sp-relative, So, for typical uses, code for on-stack variables is as compact and fast as code for virtual registers. However, I can see that a virtual register would be useful as a 24-bit pointer register, since ldf has a [longptr.e] addressing mode. When SDCC introduces a memory model with 24-bit generic data pointers, we might want to start using 3 bytes in page0 for virtual registers. I don't think it will happen soon though.

Philipp

spth commented 8 years ago

What would we need to add in ucsim? A timer interrupt and an UART?

Philipp

shkolnick-kun commented 8 years ago

Needs:

  1. A periodic timer interrupt support in simulator (usually TIM4 is used, as it's designed to be a system timer). 2.Trap support in compiler and simulator (optional, may be avoided using ASM bgrt_syscall implementation).
  2. Function calling conversion and register usage description (is partially done here, but I need more info on functions and on interfacing C and ASM code).
  3. Debug support in simulator (as I understand it's already there).
  4. I may need some additional information, if so, I'll write my questions here.
shkolnick-kun commented 8 years ago

Cast @spth!

Hi Philipp!

I have some questions:

  1. Does sdcc-stm8 support naked interrupts?
  2. Does it support variadic macros?
  3. How can I declare trap and timer interrupt service routines?

Best regards.

spth commented 8 years ago

Variadic macros are supported. Interrupt declarations need to visible in the file that contains main().

Trap interrupt:

void f(void) __trap { }

Normal interrupt number N:

void f(void) __interrupt(N) { }

Naked interrupt number N:

void f(void) interrupt(N) naked { }

Philipp

shkolnick-kun commented 8 years ago

Thanks for quick reply!

Interrupt declarations need to visible in the file that contains main().

So, do I need to place all the interrupt handlers in the same file with main, or I just can write something like

extern void f(void) trap naked;

?

cast @spth

Best Regards.

shkolnick-kun commented 8 years ago

OK, I've got a working prototype:

/**************************************************************************
    BuguRTOS-2.0.x (Bugurt real time operating system)
    Copyright (C) 2016 anonimous

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Please contact with me by E-mail: shkolnick.kun@gmail.com

    A special exception to the GPL can be applied should you wish to distribute
    a combined work that includes BuguRTOS, without being obliged to provide
    the source code for any proprietary components. See the file exception.txt
    for full details of how and when the exception can be applied.
**************************************************************************/

/*****************************************************************************************
```````````````````````````````..:+oyhdmNNMMMMMMNmmdhyo+:..```````````````````````````````
``````````````````````````.:oydNMMMMMMMMMNNNNNNNNMMMMMMMMMNdy+:.``````````````````````````
```````````````````````:sdNMMMMMNdys+/::----------::/osydNMMMMMNds:```````````````````````
```````````````````.+hNMMMMmho/-..........................-/shmMMMMNh/.```````````````````
````````````````./hNMMMNho:...................................-:ohNMMMNh/`````````````````
``````````````.smMMMNy/-.......:////ss++/+-.......................-+yNMMMmo.``````````````
````````````-sNMMMd+-.....:////:-...-/s::..............+o/-..........-odMMMNs.````````````
``````````.sNMMNh/....................................-o:--............./hMMMNo.``````````
`````````+mMMMh:-........................................-...............-/dMMMm/`````````
```````.yMMMm/...................-::--..................:-........--........+mMMMy.```````
``````:mMMMy-.......................-::-...............-:.........-::........-yMMMd:``````
`````/NMMN+-..................::-.....-:-............../--.........-:/-.......-+NMMN:`````
````+NMMm::o/-..--/+o+o+++++o+osys+//::-::.............:/....-:-::-..-++-.......:NMMN/````
```/NMMm:.-++-+yhs/-``       `dMMMMMmho+:-..............:-/+yho/:/+oyo//o-......./mMMN:```
``-NMMm/....-/--::/o+o+oo+oo++oosyss+smyo/.............:yyho-`     smMMddh-......./NMMN.``
`.hMMM/......-++:-.-:oooooooooosyyhhys/...............-+osyyyyysssssooo+ohhs-......+MMMh.`
`+MMMy.......-::/++:-.....-:/++++o+o/--................--/oooo+o++o+++////-y/.......hMMM/`
.mMMN:.........--:---...-::/+//::--.......................--//+//-...-.....+/......./NMMd`
/MMMy............-::----------....----/+-.....................-++/:---....-o-........hMMN:
yMMM/.............--:://///oo+++/+++oo+-.......................-://+/:--::::.........+MMMs
mMMN:................----:/h:::/:/::---.........................--/osss+++:..........:NMMd
MMMd-....................:mNs:-....................................--:odo:-..........:mMMN
MMMd-....................yoshyoso:--................................../mm/...........:mMMM
MMMm:..................../-o/h.y-:+dooo+/:--....................-/osydddmh...........:mMMN
mMMN:........................+mNs `h.  -d/:/+h++ooooy+++s++y+++mo+y` yh.do...........:NMMh
sMMM+........................-hmMo/ds  oMo`.-o     :h   s:`h` `Nysd.-Ny-h:...........+MMMo
/MMMh........................./smMMMMd+NMMNNMh`    sN: .mNNMddNMMMMNmN+..............hMMN:
.dMMN/........................./+hMMMMMMMMMMMMmhyyyNMNNMMMMMMMMMMMNsoo-............./NMMd`
`+MMMh.........................-/+omMMMMMMMMMMMMMMMMMMMMMMMMMMMMms-/+...............hMMM/`
`.hMMM+..........................:/-omMMMMMMMMMMMMMMMdmMdhMMMds/-..-...............oMMMy``
``.NMMN/............................--/hNN/h.`ys:dmsd:-syos+--+.................../NMMN.``
```/NMMm:...........................:+/--:+s++oo+osoo+/:-..-/+::-................/mMMN:```
````/NMMN:............................-/++/:-..........-//+/-..:+.--............/NMMN/````
`````:NMMN+-.............../+-.............-://////////:-.......+s+::.........-oNMMN:`````
``````:mMMMy-..............:/o-.................................:yo//........-hMMMd-``````
```````.yMMMm+.............:o:++-...............................+y+o-......-+mMMMs.```````
`````````/mMMMd/-...........-++:+/-.---........................-ho+/.....-/dMMMm/`````````
``````````.oNMMMh/............-++:++/////:....................-yo:o-...-+hMMMNo.``````````
````````````.sNMMMdo-...........-++::++:-:/+//:..............:o:/o-..-omMMMNo.````````````
``````````````.omMMMNy+-..........-/+-.:/+/:--:+++/++//:/::/+/-+/.-+hMMMMmo```````````````
`````````````````/hNMMMNho:-...............-:/:-....--::::--..-/ohNMMMNy:`````````````````
```````````````````./hNMMMMmhs/-..........................-/shNMMMMNy/.```````````````````
```````````````````````:sdNMMMMMNdhso+/:----------:/+oshdNMMMMMNho:```````````````````````
``````````````````````````.:+ydNMMMMMMMMMMNNNNNNMMMMMMMMMMmds+:```````````````````````````
````````````````````````````````.:/osyhdmNNMMMMNNmdhyso/:.````````````````````````````````
******************************************************************************************
*                                                                                        *
*                   This logo was graciously delivered by 10003-kun ITT:                 *
*                                                                                        *
*                           http://www.0chan.ru/r/res/9996.html                          *
*                                                                                        *
*****************************************************************************************/
#include "stm8l.h"
#include <stdint.h>

#define BGRT_INT_PTR unsigned short
typedef uint8_t bgrt_stack_t;
typedef void (*bgrt_code_t)(void*);

bgrt_stack_t * bgrt_proc_stack_init(
                            bgrt_stack_t * bgrt_stack_top,
                            bgrt_code_t pmain,
                            void * arg,
                            void (*return_address)(void)
                        )
{
    //main arg
    *bgrt_stack_top-- = (bgrt_stack_t)((unsigned short)arg & 0xFF);
    *bgrt_stack_top-- = (bgrt_stack_t)(((unsigned short)arg>>8)& 0xFF);
    // return address (func)
    *bgrt_stack_top-- = (bgrt_stack_t)(((BGRT_INT_PTR)return_address) & 0xFF);
    *bgrt_stack_top-- = (bgrt_stack_t)(((BGRT_INT_PTR)return_address>>8)& 0xFF);
    // process main
    *bgrt_stack_top-- = (bgrt_stack_t)(((BGRT_INT_PTR)pmain) & 0xFF);
    *bgrt_stack_top-- = (bgrt_stack_t)(((BGRT_INT_PTR)pmain>>8)& 0xFF);
    *bgrt_stack_top-- = 0x00;
    // Y
    *bgrt_stack_top-- = 0xAD;
    *bgrt_stack_top-- = 0xDE;
    /** WARNING: LARGE RAM MODEL IS NOT SUPPORTED IN THIS CODE!!! */
    // X - 1st argument is placed in X
    *bgrt_stack_top-- = 0xBE;
    *bgrt_stack_top-- = 0xAF;
    // A
    *bgrt_stack_top-- = 0xAA;
    // CCR
    *bgrt_stack_top-- = 0x20; //Interrupts are enabled
    //Dummy bytes, as after bgrt_isr_epilogue [addw sp, #2] is done
    *bgrt_stack_top-- = 0xFF;
    *bgrt_stack_top-- = 0xFF;
    return bgrt_stack_top;
}
static bgrt_stack_t * bgrt_isr_prologue(void) __naked
{
    __asm
        ldw X, SP
        ret
    __endasm;
}

static void bgrt_isr_epilogue(bgrt_stack_t * val) __naked
{
    (void)val;
    __asm
        ldw   X, (0x03, SP) /*Get new SP value   */
        popw  Y             /*pop return address */
        ldw   SP, X         /*Set SP             */
        pushw Y             /*push return address*/
        ret                 /*return             */
    __endasm;
}

static bgrt_stack_t * save_sp = (void *)0;

static bgrt_stack_t * main_sp = (void *)0;
static bgrt_stack_t * thread_sp = (void *)0;

static bgrt_stack_t ** restore_sp = &main_sp;

static void my_sched(void)
{
    *restore_sp = save_sp;
    if (&main_sp == restore_sp){
        restore_sp = &thread_sp;
    }else{
        restore_sp = &main_sp;
    }
    save_sp = *restore_sp;
}

static void my_trap(void) __trap __naked
{
    save_sp = bgrt_isr_prologue();
    my_sched();
    bgrt_isr_epilogue(save_sp);
    __asm__("iret");
}

bgrt_stack_t thread_stack[128];

uint16_t d_thr = 0;

static void thread(void * arg)
{
    d_thr = (int)(arg);
}

static void thread_end(void)
{
    int d;
    while(1)
    {
        PE_ODR &= ~0x80;
        for(d = 0; d < d_thr; d++) { }
        __asm__("trap");
    }
}

int main() {
    int d;
    // Configure pins
    PE_DDR = 0x80;
    PE_CR1 = 0x80;
    PE_ODR &= ~0x80;

    thread_sp = bgrt_proc_stack_init(&thread_stack[127], thread, (void *)30000, thread_end);
    // Loop
    do {
        PE_ODR |= 0x80;
        for(d = 0; d < 15000; d++) { }
        __asm__("trap");
    } while(1);
}
spth commented 8 years ago

So, do I need to place all the interrupt handlers in the same file with main, or I just can write something like

extern void f(void) trap naked;

A declaration is sufficient. The definition might be the same as the declaration, or in the same file, or in another file. It could even be implemented in asm instead of C.

Philipp

shkolnick-kun commented 8 years ago

The definition might be the same as the declaration

Can't understand... Did you mean must?

spth commented 8 years ago

I meant to say that there has to be a declaration in the file that contains main(). It doesn't matter if that declaration is also a definition (like in your example) or it is just a declaration with the definition residing elsewhere.

Philipp

shkolnick-kun commented 8 years ago

Thank you for information, Philipp! By the way, this is not just an example, it's a port prototype for stm8/sdcc. It was tested on stm8l discovery, and it works.

So, BuguRTOS-2.0.0 will support stm8/sdcc.

spth commented 8 years ago

Great. Do you need any other help with SDCC? Any improvements you'd like to see in SDCC?

Philipp

shkolnick-kun commented 8 years ago

Do you need any other help with SDCC?

If I need, I'll write a questions here.

Any improvements you'd like to see in SDCC?

I think no at the moment, only if I see some bug. In long term it would be great to have large code/data model.

shkolnick-kun commented 8 years ago

cast @spth

Hi, Philipp!

How do I place an array to a flash? How do I get a values from such array? Is there some weak qualifier? Are there some intrinsics for stm8?

Best regards.

spth commented 8 years ago

global and static arrays are placed in flash when const. Read as any other array.

Philipp

shkolnick-kun commented 8 years ago

Cast @spth, I need help!

Hi, Philipp!

I've tested BuguRTOS on stm8 with sdcc... Here is a branch: https://github.com/shkolnick-kun/bugurtos/tree/v.2.0.x-exp

I found a problem with sync test: https://github.com/shkolnick-kun/bugurtos/tree/v.2.0.x-exp/tests/arch/stm8/sdcc/sync

Target keeps reseting continuously when I run it... I'd tested the same code with STM8/IAR, STM8/Raisonance, Cortex-M variants and AVR everything worked well...

The only suspicious thing I saw is that output size was 43kb... Is that a legal output size for SDCC/STM8?

And yes, I could not get SDCC working with my Debian7 (even blinky example failed to run), so I had to use Win7.

spth commented 8 years ago

Unfortunately, I won't find time to look at the branch for the next few days. SDCC currently only supports a flat 64K address space. Since AFAIK all the STM8 have their flash above 32K that limits code size to 32 K. The .ihx file may be bigger though. Please check the exact code size (e.g. in the .map file).

A problem I encountered when porting Atomthreads was that the printf() that comes with current SDCC uses substantially more stack space than other STM8 printf(), so I had to increase per-thread stack size there for the test threads that use printf().

Philipp

shkolnick-kun commented 8 years ago

Hi, Philipp!

I've found the root of the problem: SDCC generates very bad stack-overflow-prone code for long functions: This file compiles to this. Here is a log:

sdcc: Calling preprocessor...
sdcc: sdcpp.exe -nostdinc -Wall -std=c99 -I"..\..\sdcc" -I"..\..\..\..\..\kernel" -I"..\..\..\..\..\kernel\default" -I"..\..\..\..\..\arch\stm8\sdcc" -I"..\..\..\..\..\..\thirdparty\libstm8\include" -I"C:\sdcc\include" -obj-ext=.rel -D__SDCC_STACK_AUTO -D__SDCC_CHAR_UNSIGNED -D__SDCC_INT_LONG_REENT -D__SDCC_FLOAT_REENT -D__SDCC=3_6_0 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=6 -D__SDCC_VERSION_PATCH=0 -D__SDCC_REVISION=9615 -D__SDCC_stm8 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem "C:\Program Files\SDCC\bin\..\include\stm8" -isystem "C:\Program Files\SDCC\bin\..\include"  "..\..\..\..\main\bsync\main.c" 
sdcc: Generating code...
sdcc: Calling assembler...
sdcc: sdasstm8.exe -plosgffw ""obj\Debug\main\bsync\main".asm"

The function main_0 is just a linear code sequence, but at the end of it you can see

;   ..\..\..\..\main\bsync\main.c: 972: tests_end();
    call    _tests_end
    addw    sp, #92
    ret

So sdcc allocated at least 92 for temporary vars!!! But the process № 0 has only 128 bytes in it's stack, so when BGRT_PROC_RUN gets called

    // 135 priority inheritance/ceiling
    BGRT_PROC_RUN( PID5 );
    bgrt_wait_time(5);

in test № 135, stack overflow happens and control doesn't get passed to process № 5.

IMHO, this is the reason of your troubles with Atomthreads, and I think it's a very serious bug in codegen, which effectively eliminates possibilities for usage of SDCC with any RTOS on STM8.

spth commented 8 years ago

Allocation of on-stack variables is a bit problematic. We'll look into it more in the future. For now, I guess you'll have to use a workaround: Use a higher optimization setting (via --max-allocs-per-node), so the register allocator does a better job and less variables get allocated to the stack.

Philipp

shkolnick-kun commented 8 years ago

Hi, Philipp! The option --max-allocs-per-node didn't help! So I had to edit an OS configuration and give 160 bytes per process stack. I also had to rewrite interrupt prologue to make the kernel stable... Looks like something is wrong with interrupt priorities on my STM8L...

Now kernel and native API lib work with STM8/SDCC, so I can say, that experimental STM8/SDCC port is added to BuguRTOS-2.0.x branch.

spth commented 6 years ago

While there is still further potential for reducing stack usage, the situation is much better now. Since SDCC revision 10659, a new stack allocator is used in the stm8 backend.

Philipp

shkolnick-kun commented 6 years ago

Cool! Thank you Philipp!

shkolnick-kun commented 6 years ago

How do I check it on Windows/Linux?

shkolnick-kun commented 6 years ago

Is there installation/package available?

spth commented 6 years ago

On the SDCC snapshots page:

http://sdcc.sourceforge.net/snap.php

Philipp