im trying to do a multithreading library for atmega controller and firstly i try to manipulate the stack pointer and after the return of function "go_to_func" the program goes in function "func". The function "go_to_func" is written in asm1.s file and this is the function where the stack pointer is modify for the program to return at the start address of "func" but my program don't geos on "func" after the return of "go_to_func"(When the program arrive on "func" the PORTD bit 3 is turned on). Can anyone tell my what i have to write on "go_to_func" to make my program works fine. Here is the hole information of my code.
main.c
#include <avr/io.h>
#include <stdlib.h>
#include "asm1.h"
#define CALL_FCT __attribute__ ((noinline))
#define RETURN_SIZE 2
uint8_t fn_stack[128];
uint8_t addr_l;
uint8_t addr_h;
void CALL_FCT func( void )
{
PORTD = 0x08 ;
while(1)
{
}
}
void CALL_FCT init( void (*fn)(void), uint8_t* stack, uint16_t stack_size)
{
*(stack + stack_size - RETURN_SIZE ) = (uint16_t)fn >> 8;
*(stack + stack_size - RETURN_SIZE + 1) = (uint8_t)(uint16_t)fn;
addr_l = (uint8_t)(uint16_t)(stack + stack_size );
addr_h = (uint8_t)(uint16_t)(stack + stack_size + 1);
go_to_func(addr_l,addr_h);
}
int CALL_FCT main(void)
{
DDRD |= 0x0C ;
init(func,fn_stack,sizeof(fn_stack));
PORTD = 0x04 ;
while (1)
{
}
}
asm1.h
#ifndef HEADER_H_
#define HEADER_H_
#include <stdint.h>
extern void go_to_func(uint8_t,uint8_t);
#endif /* HEADER_H_ */
asm1.s
#include <avr/io.h>
.global go_to_func
go_to_func:
out _SFR_IO_ADDR(SPH), r22
out _SFR_IO_ADDR(SPL), r24
ret
/* *.lss the file of my program in assembly */
void CALL_FCT func( void )
{
PORTD = 0x08 ;
96: 88 e0 ldi r24, 0x08 ; 8
98: 8b b9 out 0x0b, r24 ; 11
9a: ff cf rjmp .-2 ; 0x9a <func+0x4>
0000009c <init>:
}
}
void CALL_FCT init( void (*fn)(void), uint8_t* stack, uint16_t stack_size)
{
*(stack + stack_size - RETURN_SIZE ) = (uint16_t)fn >> 8;
9c: 9b 01 movw r18, r22
9e: 24 0f add r18, r20
a0: 35 1f adc r19, r21
a2: f9 01 movw r30, r18
a4: 32 97 sbiw r30, 0x02 ; 2
a6: 90 83 st Z, r25
*(stack + stack_size - RETURN_SIZE + 1) = (uint8_t)(uint16_t)fn;
a8: 31 96 adiw r30, 0x01 ; 1
aa: 80 83 st Z, r24
addr_l = (uint8_t)(uint16_t)(stack + stack_size );
ac: 20 93 01 01 sts 0x0101, r18 ; 0x800101 <addr_l>
addr_h = (uint8_t)(uint16_t)(stack + stack_size + 1);
b0: 4f 5f subi r20, 0xFF ; 255
b2: 5f 4f sbci r21, 0xFF ; 255
b4: 64 0f add r22, r20
b6: 75 1f adc r23, r21
b8: 60 93 00 01 sts 0x0100, r22 ; 0x800100 <_edata>
go_to_func(addr_l,addr_h);
bc: 82 2f mov r24, r18
be: 0e 94 48 00 call 0x90 ; 0x90 <go_to_func>
c2: 08 95 ret
000000c4 <main>:
}
int CALL_FCT main(void)
{
DDRD |= 0x0C ;
c4: 8a b1 in r24, 0x0a ; 10
c6: 8c 60 ori r24, 0x0C ; 12
c8: 8a b9 out 0x0a, r24 ; 10
init(func,fn_stack,sizeof(fn_stack));
ca: 40 e8 ldi r20, 0x80 ; 128
cc: 50 e0 ldi r21, 0x00 ; 0
ce: 62 e0 ldi r22, 0x02 ; 2
d0: 71 e0 ldi r23, 0x01 ; 1
d2: 8b e4 ldi r24, 0x4B ; 75
d4: 90 e0 ldi r25, 0x00 ; 0
d6: 0e 94 4e 00 call 0x9c ; 0x9c <init>
PORTD = 0x04 ;
da: 84 e0 ldi r24, 0x04 ; 4
dc: 8b b9 out 0x0b, r24 ; 11
de: ff cf rjmp .-2 ; 0xde <main+0x1a>
000000e0 <_exit>:
e0: f8 94 cli
000000e2 <__stop_program>:
e2: ff cf rjmp .-2 ; 0xe2 <__stop_program>