Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Если очень надо(+)

Отправлено Lameг 04 декабря 2006 г. 17:17
В ответ на: Помогите плз! отправлено <font color=gray>sma</font> 04 декабря 2006 г. 09:40

Из какой-то РТОСины, не помню.

// В Си
volatile unsigned char Context[44]; // Глобально
............
Save_Context();
_NOP(); // Сюда возвратится
............
............
Restore_Context(); // Из любой вложенности
---------------------------------------------


В Ассемблерном файле:
EXTERN Context
PUBLIC Save_Context
PUBLIC Restore_Context
RSEG CODE
SFR_B(__SP_H__, 0x3e ) ; high part of the stack pointer
SFR_B(__SP_L__, 0x3d ) ; low part of the stack pointer
#define __Rtmp_reg__ r0

; Do the context switch
;
; NOTE: The first 40 bytes of the seosTask_t struct are organized as follows:
; regs[32] -> bytes 0-31 are used to store the regs
; sreg -> byte 32 is used to store the status register
; sp -> bytes 33-34 are used to store the stack pointer
; RAMPZ -> byte 35 is RAMPZ
; MCUCR -> byte 36
; ret_address -> byte 37,38
; common_use -> byte 39-42
;---------------------------------------------------------------

;---------------------------------------------------------------
Save_Context:
;---------------------------------------------------------------
;--- save the contents of the Z register (r30 & r31)
push r28
push r29 ; save real Y
push r30
push r31 ; save real Z
;--- pointer distantion into the Z register (r30 & r31)
ldi r30,LOW(Context)
ldi r31,HIGH(Context)
;--- save the first 30 registers
std Z+0,r0
std Z+1,r1
std Z+2,r2
std Z+3,r3
std Z+4,r4
std Z+5,r5
std Z+6,r6
std Z+7,r7
std Z+8,r8
std Z+9,r9
std Z+10,r10
std Z+11,r11
std Z+12,r12
std Z+13,r13
std Z+14,r14
std Z+15,r15
std Z+16,r16
std Z+17,r17
std Z+18,r18
std Z+19,r19
std Z+20,r20
std Z+21,r21
std Z+22,r22
std Z+23,r23
std Z+24,r24
std Z+25,r25
std Z+26,r26
std Z+27,r27
std Z+28,r28
std Z+29,r29
;--- move Z to Y so we can resore Z
mov r28,r30
mov r29,r31
pop r31 ; real Z is restored
pop r30
;--- save real Z
std Y+30,r30
std Y+31,r31
;-- save tmp_reg
std Y+42,__Rtmp_reg__
;--- save the status register
in __Rtmp_reg__, SREG
std Y+32,__Rtmp_reg__
;--- save the stack pointer
in __Rtmp_reg__,__SP_L__ ; уменьшено на 2 за счет PUSHей !
std Y+33,__Rtmp_reg__
in __Rtmp_reg__,__SP_H__
std Y+34,__Rtmp_reg__
;--- update RAMPZ
in __Rtmp_reg__, RAMPZ
std Y+35,__Rtmp_reg__
;--- update MCUCR
in __Rtmp_reg__,MCUCR
std Y+36,__Rtmp_reg__
;--- restore tmp_reg
ldd __Rtmp_reg__, Y+42
;--- Эти регистры понадобятся
std Y+39,r17 ; save
std Y+40,r16
std Y+42,r19 ; save
std Y+41,r18
;--- restore Y
pop r17 ; Y
pop r16
;--- get return address
pop r19
pop r18
std Y+37,r19 ; save return address
std Y+38,r18
;--- return address - go home!
push r18
push r19
;--- restore r18, R19
ldd r19,Y+42
ldd r18,Y+41
;--- again save Y
push r16
push r17
;--- restore R16, R17
ldd r17,Y+39
ldd r16,Y+40
;--- ... and restore real Y
pop r29
pop r28
ret
;---------------------------------------------------------------

;---------------------------------------------------------------
Restore_Context:
;---------------------------------------------------------------
; Set the new context (stored in the Z register)
;---------------------------------------------------------------
;--- pointer distantion into the Z register (r30 & r31)
ldi r30,LOW(Context)
ldi r31,HIGH(Context)
;--- MCUCR
ldd __Rtmp_reg__,Z+36
out MCUCR,__Rtmp_reg__
;--- RAMPZ
ldd __Rtmp_reg__,Z+35
out RAMPZ,__Rtmp_reg__
;--- SP
ldi r16,2 ; в Save_Context, SP уменьшен за счет PUSHей на 2.
ldd __Rtmp_reg__,Z+33
add __Rtmp_reg__,r16
out __SP_L__,__Rtmp_reg__
ldd __Rtmp_reg__,Z+34
ldi r16,0
adc __Rtmp_reg__,r16 ; сделали SP += 2
out __SP_H__,__Rtmp_reg__
;--- SREG
ldd __Rtmp_reg__,Z+32
out SREG,__Rtmp_reg__
;----------------------
;--- setting new return address
pop __Rtmp_reg__
pop __Rtmp_reg__
ldd __Rtmp_reg__,Z+38
push __Rtmp_reg__
ldd __Rtmp_reg__,Z+37
push __Rtmp_reg__
;--- set the first 30 registers
ldd r0,Z+0
ldd r1,Z+1
ldd r2,Z+2
ldd r3,Z+3
ldd r4,Z+4
ldd r5,Z+5
ldd r6,Z+6
ldd r7,Z+7
ldd r8,Z+8
ldd r9,Z+9
ldd r10,Z+10
ldd r11,Z+11
ldd r12,Z+12
ldd r13,Z+13
ldd r14,Z+14
ldd r15,Z+15
ldd r16,Z+16
ldd r17,Z+17
ldd r18,Z+18
ldd r19,Z+19
ldd r20,Z+20
ldd r21,Z+21
ldd r22,Z+22
ldd r23,Z+23
ldd r24,Z+24
ldd r25,Z+25
ldd r26,Z+26
ldd r27,Z+27
ldd r28,Z+28
ldd r29,Z+29
;--- save Y
push r28
push r29
;--- move Z to Y so we can set Z
mov r28,r30
mov r29,r31
ldd r30,Y+30
ldd r31,Y+31
;--- restore Y
pop r29
pop r28
;---
ret
;------------------------------------
END


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа

Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 
если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
при вычитании трёх из шести получится:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru