Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Файл OS.c
- #include <stm32l1xx.h>
- //--------------------STACKS---------------
- unsigned char Stacks[8][0x200]; // Объявляем стек и его размер
- //--------------------CONTEXTS-------------
- // выделяем память под контекст
- struct {
- unsigned int GRP[13];
- void * PC;
- void * LR;
- void * SP;
- unsigned int PSW;
- } contexts[8];
- //--------------------TASKS-------------
- // Импортировать в операционную систему список задач
- extern void * Tasks[];
- unsigned char tnum;
- unsigned char tcur;
- typedef void (*func)(void);
- // метод для инициализации таймера
- void OSinit(){
- int i;
- // реализация таймера
- RCC->APB1ENR |= 0x00000001;
- TIM2->CNT = 0; // счётчик
- TIM2->PSC = 0; // частота
- TIM2->ARR = 0x8000;
- TIM2->DIER |=0x00000001;
- TIM2->CR1 |= 0x00000001;
- i=0;
- // загружаем контекст
- while(Tasks[i] != 0){
- contexts[i+1].PC = (void *)(((int)(Tasks[i])) | (1));
- contexts[i+1].SP = &Stacks[i][0x200-4];
- contexts[i+1].PSW = 0x01000000;
- i++;
- }
- tnum = i;
- tcur = 0; //переменная для смены задач в прерывании
- //Enable NVIC
- NVIC->ISER[0] |= 0x10000000; //enable TIM2 IRQ reaction
- while(1);
- }
- void SaveContext (void * conptr); //метод для сохранения контекста
- void RestoreContext (void *conptr); //метод для загрузки контекста
- //функция void OSkernel (), которая будет
- //- вызывать функцию сохранения контекста для текущей задачи;
- //- реализовывать алгоритм планирования Round-Robin;
- // - вызывать функцию восстановления контекста для выбранной задачи.
- void OSkernel(){
- SaveContext(&(contexts[tcur]));
- tcur++;
- if(tcur>tnum){
- // переключатель между контекстами
- tcur=1;
- }
- RestoreContext(&(contexts[tcur]));
- return;
- }
- Файл Main.c
- #include <stm32l1xx.h>
- int Task1(int A) // 1 метод, которой выполняет ОС
- {
- while(1)
- {
- __NOP();
- }
- }
- int Task2(int A,int B) // 2 метод, который выполняет ОС
- {
- while(1)
- {
- __NOP();
- }
- }
- int main()
- {
- int A = 1;
- int B;
- *((unsigned int*)(0x40023800+0x20)) |= 0x00004000;
- *((unsigned int*)(0x40013800+0x08)) = 0x00000123;
- *((unsigned int*)(0x40013800+0x0C)) |= 0x0000200c;
- *((unsigned int*)(0x40023800+0x1C)) |= 0x00000001;
- *((unsigned int*)(0x40020000+0x00)) |= 0x00280000;
- *((unsigned int*)(0x40020000+0x24)) |= 0x00000770;
- B= *((unsigned int*)(0x40013800+0x00));
- while(1)
- {
- Task1(A);
- Task2(A,B);
- }
- }
- // массив, в который поместили адреса на написанные процедуры, а также ключевые метки. Приписка __attribute__((at(0x08001000))) необходима для того, чтобы структура была размещена в ПЗУ.
- void * const Tasks[] __attribute__((at(0x08001000)))={
- Task1,
- Task2,
- 0
- };
- Файл statup_stm312l1xx_mod.s
- Stack_Size EQU 0x00000400
- AREA STACK, NOINIT, READWRITE, ALIGN=3
- Stack_Mem SPACE Stack_Size
- __initial_sp
- Varlr DCD 0
- ALIGN
- PRESERVE8
- THUMB
- ; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
- __Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- space (0x000000B0 - 8)
- DCD TIM2_Handler
- __Vectors_End
- __Vectors_Size EQU __Vectors_End - __Vectors
- AREA |.text|, CODE, READONLY
- ; Reset handler routine
- Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT OSinit
- LDR R0,=OSinit
- BLX R0
- enable
- LDR R0,=0x40020400
- cpsid i
- LDR R1,[R0,#0x14]
- LDR R2,=0x00000080
- cmp1 ADD R4,#0x00000001
- CMP R4,R3
- BNE cmp1
- LDR R4,=0x00000000
- ;#1 GPIO _odr part 2
- EOR R1,R2
- STR R1,[R0,#0x14]
- cpsie i
- cmp2 ADD R4,#0x00000001
- CMP R4,R3
- BNE cmp2
- LDR R4,=0x00000000
- B enable
- ENDP
- // Процедура TIM2_Handler нужна для обработки прерываний
- TIM2_Handler PROC
- IMPORT OSkernel
- ;сохраняем LR которое меняется в OSkernel
- MOV R0, LR
- LDR R1, =Varlr
- STR R0, [r1]
- BL OSkernel
- ;TIMx_SR
- LDR R0,=0x40000000
- LDR R1,[R0,#0x10]
- LDR R2,=~0x00000001
- AND R1,R2
- STR R1,[R0,#0x10]
- ;востанавливаем значение LR
- LDR R1, =Varlr
- LDR R0, [r1]
- MOV LR, R0
- BX LR
- ENDP
- SaveContext PROC
- EXPORT SaveContext
- ;Save PSW from task[i] stack to context[i]
- LDR R1,[SP,#0x24]
- STR R1,[R0,#0x40]
- ;Save PC from task[i] stack to context[i]
- LDR R1,[SP,#0x20]
- STR R1,[R0,#0x34]
- ;Save LR from task[i] stack to context[i]
- LDR R1,[SP,#0x1C]
- STR R1,[R0,#0x38]
- ;Save R12 from task[i] stack to context[i]
- LDR R1,[SP,#0x18]
- STR R1,[R0,#0x30]
- ;Save R3 from task[i] stack to context[i]
- LDR R1,[SP,#0x14]
- STR R1,[R0,#0x0C]
- ;Save R2 from task[i] stack to context[i]
- LDR R1,[SP,#0x10]
- STR R1,[R0,#0x08]
- ;Save R1 from task[i] stack to context[i]
- LDR R1,[SP,#0x0c]
- STR R1,[R0,#0x04]
- ;Save R0 from task[i] stack to context[i]
- LDR R1,[SP,#0x08]
- STR R1,[R0,#0x00]
- ;Save R4 from current context to context[i]
- STR R4,[R0,#0x10]
- ;Save R5 from current context to context[i]
- STR R5,[R0,#0x14]
- ;Save R6 from current context to context[i]
- STR R6,[R0,#0x18]
- ;Save R7 from current context to context[i]
- STR R7,[R0,#0x1C]
- ;Save R8 from current context to context[i]
- STR R8,[R0,#0x20]
- ;Save R9 from current context to context[i]
- STR R9,[R0,#0x24]
- ;Save R10 from current context to context[i]
- STR R10,[R0,#0x28]
- ;Save R11 from current context to context[i]
- STR R11,[R0,#0x2C]
- ;Save SP from current context to context[i]
- STR SP,[R0,#0x3C]
- BX LR
- ENDP
- RestoreContext PROC
- EXPORT RestoreContext
- ;First stack item
- LDR R7,[SP,#0x00]
- ;Second stack item
- LDR R8,[SP,#0x04]
- ;Restore SP
- LDR SP,[R0,#0x3C]
- ;Load first value in new stack
- STR R7,[SP,#0x00]
- ;Load second value in new stack
- STR R8,[SP,#0x04]
- ;Restore R11
- LDR R11,[R0,#0x2C]
- ;Restore R10
- LDR R10,[R0,#0x28]
- ;Restore R9
- LDR R9,[R0,#0x24]
- ;Restore R8
- LDR R8,[R0,#0x20]
- ;Restore R7
- LDR R7,[R0,#0x1C]
- ;Restore R6
- LDR R6,[R0,#0x18]
- ;Restore R5
- LDR R5,[R0,#0x14]
- ;Restore R4
- LDR R4,[R0,#0x10]
- ;Restore R0
- LDR R1,[R0,#0x00]
- STR R1,[SP,#0x08]
- ;Restore R1
- LDR R1,[R0,#0x04]
- STR R1,[SP,#0x0c]
- ;Restore R2
- LDR R1,[R0,#0x08]
- STR R1,[SP,#0x10]
- ;Restore R3
- LDR R1,[R0,#0x0C]
- STR R1,[SP,#0x14]
- ;Restore R12
- LDR R1,[R0,#0x30]
- STR R1,[SP,#0x18]
- ;Restore LR
- LDR R1,[R0,#0x38]
- STR R1,[SP,#0x1C]
- ;Restore PC
- LDR R1,[R0,#0x34]
- STR R1,[SP,#0x20]
- ;Restore PSW
- LDR R1,[R0,#0x40]
- STR R1,[SP,#0x24]
- BX LR
- ENDP
- ALIGN
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement