ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
29 марта
672102 Топик полностью
Связанные сообщения
C-Startup
Стартап делает гораздо больше вещей. Вообще отчасти это задача операционной системы: как-то разместить в памяти аргументы програ...2020-09-11
Обработку прерывания от FSMC и таймаут на то что PLL (не)заведётся сделал? Я делал... Иногда срабатывало. Плохая пайка, плохой к...2020-09-10
Из функции _start (в C-стартапе, до main) пересчитывается CRC32 прошивки, например, и сравнивается с значениями записанными по с...2017-07-12
Вначале пишешь (вообще по LR, дальше исключительно для одептов оссемблира):2012-01-26
fk0, легенда (03.05.2016 21:54, просмотров: 859) ответил SciFi на Стартап для кортекс на асме - это трэш, угар и содомия. Всех расстрелять, адназначна.
Я для ARM7 писал на асме, и обработчик прерываний тоже. А он там, в отличии от жалких кортексов, достаточно замороченный.  /* $Id$ */ /* vim: set syntax=armasm: */ /* ROM mode, vectors in ROM */ #include "AT91SAM7X256_inc.h" #include "exits.h" .arm .text /* Секция содержит вектора прерываний и быстрые обработчики прерываний, * секция может быть размещена (скопирована) в ОЗУ */ .section .vectors, "ax" ldr pc, =_start /* 0x00 Reset */ ldr pc, =UNDEF /* 0x04 Undefined Instruction */ ldr pc, =SWI /* 0x08 Software Interrupt */ ldr pc, =ABORT /* 0x0C Prefetch Abort */ ldr pc, =DABORT /* 0x10 Data Abort */ nop /* 0x14 reserved */ ldr pc, =IRQ /* 0x18 IRQ */ FIQ: /* 0x1c FIQ */ /* переключение в режим супервизора для использования общего * с программой стека и запрет прерываний */ mov r11, r0 /* r0 прерванной программы, r7..r15 -- fiq */ ldr r0, [r12, #AIC_FVR] /* подтверждение/снятие запроса, чтение вектора AIC */ msr CPSR_c, #I_BIT|F_BIT|ARM_MODE_SVC /* см: http://www.chiark. …docs/CodeStds/APCS.txt * сохраняются регистры разрушаемые при вызове функций */ stmfd sp!, {r1-r3, r12, lr} mov lr, pc /* вызов функции обработки FIQ */ bx r0 ldmia sp!, {r1-r3, r12, lr} msr CPSR_c, #I_BIT|F_BIT|ARM_MODE_FIQ mov r0, r11 subs pc, lr, #4 /* Обработка ложных прерываний */ SPU: mov pc, lr .global _exit /* unhandled interrupts -- call _exit(code), code must be defined in exits.h */ SWI: mov r0, #EX_UNEXP_SWI b _exit ABORT: mov r0, #EX_CODE_ABORT b _exit DABORT: mov r0, #EX_DATA_ABORT b _exit UNDEF: mov r0, #EX_UNDEF b _exit .section .text .func IRQ IRQ: /* на IRQ-стеке сохраняется адрес возврата, SPSR_irq и регистры -- 3 слова */ sub lr, lr, #4 /* адрес возврата для загрузки в pc */ stmfd sp!, {lr} mrs lr, SPSR stmfd sp!, {lr} stmfd sp!, {r0} /* чтение вектора/подтверждение для данного прерывания */ ldr lr, =AT91C_BASE_AIC ldr r0, [lr, #AIC_IVR] str lr, [lr, #AIC_IVR] /* для поддержки отладки */ /* переключение и обработка прерывания на стеке пользователя */ msr CPSR_c, #ARM_MODE_SVC /* разрешаются вложенные прерывания */ stmfd sp!, {r1-r3, r12, lr} /* сохр. регистров, см. FIQ комментарий */ mov lr, pc bx r0 ldmia sp!, {r1-r3, r12, lr} /* переключение обратно в IRQ с запретом прерываний */ msr CPSR_c, #I_BIT|ARM_MODE_IRQ ldr lr, =AT91C_BASE_AIC str lr, [lr, #AIC_EOICR] /* сигнализация конца обработки для AIC */ /* загрузка 3 регистров из IRQ стека, см. выше */ ldmia sp!, {r0} ldmia sp!, {lr} msr SPSR_cxsf, lr ldmia sp!, {pc}^ /* и загрузка SPSR в CPSR -- возврат из прерывания */ .size IRQ, .-IRQ .endfunc .section .text .global _start .func _start .equ ARM_MODE_USR, 0x10 .equ ARM_MODE_FIQ, 0x11 .equ ARM_MODE_IRQ, 0x12 .equ ARM_MODE_SVC, 0x13 .equ ARM_MODE_ABT, 0x17 .equ ARM_MODE_UND, 0x1b .equ ARM_MODE_SYS, 0x1f .equ I_BIT, 0x80 .equ F_BIT, 0x40 _start: /* Установка стеков для IRQ и режима супервизора (FIQ не использует стек), * предполагается, что программа исполняются в режиме супервизора. */ /* Для FIQ в r8 сохраняется адрес AIC */ msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT ldr r8, =AT91C_BASE_AIC /* установка векторов по-умолчанию */ ldr r0, =UNDEF add r1, r8, #AIC_SVR mov r2, #31*4 set_irqvec0: str r0, [r1, r2] subs r2, r2, #4 bcc set_irqvec0 /* установка вектора SPU */ ldr r0, =SPU str r0, [r8, #AIC_SPU] /* сброс запросов прерывания всех уровней */ mov r0, #16 /* was 8 -- для надёжности. :-/ */ ldr r1, =AT91C_BASE_AIC clr_irqrq0: str r1, [r1, #AIC_EOICR] subs r0, r0, #1 bcc clr_irqrq0 /* режим IRQ имеет стек 3(слова)*4(sizeof)*8(уровней) минимум */ set_stacks: msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT ldr SP, =_ram_top-4 sub r0, SP, #128 /* размер стека IRQ */ msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT mov SP, r0 .global hardware_init /* функция hardware_init() осуществляет настройку watchdog, контроллера памяти, * тактового генератора, портов ввода-вывода -- всего, что должно * инициализироваться немедленно после сброса, до относительно медленной * инициализации libc и т.п. ВОЗМОЖНО, В Т.Ч. И ВЕКТОРОВ ПРЕРЫВАНИЙ! */ ldr r0, =hardware_init mov lr, pc bx r0 /* enable interrupts */ msr CPSR_c, #ARM_MODE_SVC /* XXX */ /* копирование содержимого секции .data из ПЗУ в ОЗУ: _etext --> _data.._edata */ .global __data_load__ .global __data_start__ .global __data_end__ copy_data: ldr r0, =__data_load__ ldr r1, =__data_start__ ldr r2, =__data_end__ copy_data1: cmp r1, r2 ldrlo r3, [r0], #4 strlo r3, [r1], #4 blo copy_data1 /* заполнение секции .bss нулём */ .global __bss_start__ .global __bss_end__ zero_bss: ldr r0, =__bss_start__ ldr r1, =__bss_end__ mov r2, #0 zero_bss1: cmp r0, r1 strlo r2, [r0], #4 blo zero_bss1 /* вызов конструкторов C++ */ .global __ctors_start__ .global __ctors_end__ call_ctors: ldr r0, =__ctors_start__ ldr r1, =__ctors_end__ b call_ctors2 call_ctors1: ldr r2, [r0], #4 stmfd sp!, {r0-r1} /* сохр. r0-r1 на стеке */ mov lr, pc bx r2 ldmia sp!, {r0-r1} call_ctors2: cmp r0, r1 blo call_ctors1 /* вызов функции main() */ .global main mov r0, #0 /* int argc, char *argv[] */ mov r1, r0 mov r2, r0 /* ? */ mov fp, r0 mov r7, r0 /* ? */ ldr r4, =main mov lr, #-4 /* возврат из main() по адресу 0 */ bx r4 .size _start, .-_start .endfunc .section .text .global di .global ei .func di di: msr CPSR_c, #ARM_MODE_SVC|I_BIT mov pc, lr .endfunc .func ei ei: msr CPSR_c, #ARM_MODE_SVC mov pc, lr .endfunc .end
[ZX]