JZ2440 развитие голой доски практике # 7 прерывания и исключения (1)

прелиминарии

Перед входом прерывания и исключения упражнения тему, вам нужно прочитать чип S3C2440 ARM или справочное руководство, чтобы выяснить механизм статуса и исключения из ARM.

Во- первых нужно знать режим присутствия ARM и режим Thumb ARM, в котором Thumb режим длина инструкции 16bits для того, чтобы сохранить пространство памяти программ существует, 32бят команды в режиме ARM, схематично мы обычно используем, теперь из - за объем памяти больше большой, в состоянии удовлетворить потребности в хранении данных, использование режима ARM в основном из режима ARM в режим Thumb требует использование инструкции BX программы скачка, когда целевой адрес операнда BX младший бит равен 1, процессор будет включить режим Thumb, как следует, конечно, но и с компилятором присоединиться параметры Thumb -mthumb.

	adr r0, thumb_func
	add r0, r0, #1  /* bit0=1时, bx就会切换CPU State到thumb state */
	bx r0
	
.code 16	
thumb_func:	
	bl main

ARM и Thumb режим чуть выше, и соответствующая длина инструкции, есть набор из режима ARM работы, что соответствует ненормальности, но и ограничить доступ к ресурсам.

На приведенной выше рисунке сверху донизу пользовательский режим, режим быстрого прерывания, режим прерывания, режим управления, режим прекращения, режим работы системы и не определен режим, в котором режим Непривилегированного пользовательского режима, ограничение доступа к некоторым ресурсам и не может напрямую изменять соответствующее Регистр достижения режима преобразования. Режим Прекращения инструкция завершения предварительной выборка делится на считанные данные и заканчивается, входит в ненормальном режиме (например, не читает) операции в обеих. Неопределенная инструкция чтения средства не соответствуют с набором команд ARM, ARM не знает, процесс переходит в режим. FIQ и IRQ прерывания, необходимо иметь четкое представление, прерывание исключением принадлежит, FIQ прерывания обработки для передачи данных, по отношению к прошедшему времени меньше IRQ, FIQ часть той причине, что там, где есть регистры более специального назначения, не может зарегистрировать больше сохранить сцену. Ниже треугольник флага является специальный регистр режима.

Лично считаю, что присутствие аномальных моделей наибольшее значение является способность выполнять определенные действия для восстановления системы, необходимо, чтобы перейти к соответствующему обработчику после ввода исключения. ARM здесь, чтобы сделать работу в этой области, ARM установить вектор исключения таблицу, когда происходит исключение, PC будет указывать на адрес, соответствующий аномальные отклонения в таблице векторов, и нам нужно сделать, это установить исключение в соответствующем адресе таблица векторов.

ARM сделаны при входе выше аномальных моделей не просто прыгать исключение масштаба, прежде чем делать что-нибудь еще описать ARM, вы должны сначала понять CPSR и СПСР регистры. CPSR, Current Program Status Register, текущий регистр состояния программы, СПСР, сохраненная программа Регистры состояния, сохраненный регистр состояния программы. СПСР Это просто архив точки CPSR, когда необходимость использования или изменения CPSR, если последующая необходимость использования CPSR исходного значения, значение будет сохранено CPSR в СПСР, этот шаг должен быть сделано автоматически руки. А использование CPSR будет все больше и больше, 0-4bit режим бит устанавливается в значение, соответствующее соответствующей моды продолжается, вторая таблица может выглядеть. № 5 является ARM и Thumb режим бит состояния упоминались выше, следует отметить, что руководство не может быть установлено вручную, чтобы напомнить эту, в противном случае он будет ввести неизвестное состояние. 6 и бит 7 бит разрешения прерывания устанавливается в ответ на прерывание запрещено. 8-27 бит зарезервированы и должны быть установлены в 0, то предполагается, что ARM хочет расширить функции последующего до использования. 28-31-битная операция была результатом бит состояния, тем более распространенный не объясняются.

 

 Теперь мы можем говорить о делать вещи под ARM при переключении аномалии:

1. Возвращаемое значения (ПК +4, или ПК + 8) R14 для сохранения (LR) регистр (примечание: это соответствует LR имеет специальный режим регистра)

2. Сохраните CPSR в СПСР (СПСР также отображается в монопольном режиме)

3. Изменение режим CPSR биты, соответствующий режим (0-4) значения режима

4. Адрес точек исключения ПК соответствующие таблицы векторов исключений

До сих пор программа входит обработчик исключений. В качестве обработчика исключений, мы должны сделать программу, являются:

1. Из-R13 (SP), зарегистрировать для каждого уникального регистре режима, при этом в соответствующем режиме, необходимо установить обработчик стека, потому что мы намерены использовать язык C.

2. Перед входом в реальный обработчик, вам нужно сохранить сайт, который неисключительной регистры необходимо сохранить стек, чтобы гарантировать, что после окончания обработчика возвращается исключения, исходная программа может быть нормальной.

3. До конца возвращения потока программы в нормальное русло, вам нужно сохранить на месте восстановления, а также стоимость восстановления в СПСР к CPSR, в то время как ранее сохраненные точки ПК возврата LR-адрес. Если он прерывается, и вам необходимо очистить соответствующие прерывания бит, чтобы предотвратить повторное срабатывание.

Следует отметить, что между различными режимами обратного адреса, который отличается, потребности таблиц просмотровых быть обработаны соответствующим образом.

Кроме того, в дополнении к пользовательскому режиму, другие режимы могут непосредственно модифицировать биты режима CPSR для изменения текущего режима.

ненормальный

С учетом указанных выше предварительных знаний после этого, операция стала очень простой. Необходимые шаги:

1. Установить таблицу векторов исключений

Настройка стека и восстановить сайт, чтобы сохранить сцену до и после обработчика исключений 2

3. обработчик исключений

В связи с необходимостью увидеть явление, а затем в исходной программе, код может быть добавлен вполне достаточно сгенерирует исключение.

Причем выход Неопределенный код исключения следующим образом:

Start.S
---------------------------------
.text
.global _start

_start:
	B RESET	                        //异常向量表,参考芯片手册
	LDR pc,UNDEFIE                  //LDR取汇编的标号即取该地址内容,若为伪指令=,则为直接取地址
	LDR pc,SW_INTERRUPT             
	B ABORT_PREFETCH
	B ABORT_DATA
	B halt				            //reserve
	B IRQ_HANDLE
	B FIQ_HANDLE

UNDEFIE:                            //将目标地址放置在此处,防止编译器将地址放置在4k以外及其他
	.word DO_UND	                //因为硬件原因不能取到内容的地方
	
SW_INTERRUPT:
	.word DO_SWI
	

ABORT_PREFETCH:                    //此处未做实现,因此全部调到halt
ABORT_DATA:	
IRQ_HANDLE:
FIQ_HANDLE:
	B halt

DO_UND:
	//1.设置栈
	LDR SP,=0x34000000
	//2.保存现场
	STMDB SP!,{R0-R12,LR}

	//处理函数
	MRS R0,CPSR
	LDR R1,=UND_TEST_STRING
    BL ExecptionHandle
	
	//3.恢复现场,跳转回原来的位置
	LDMIA SP!,{R0-R12,PC}^              //^ 表示将SPSR恢复到CPSR中
	
DO_SWI:
	//1.设置栈
	LDR SP,=0x33e00000
	//2.保存现场
	STMDB SP!,{R0-R12,LR}
	
	//处理函数
	MRS R0,CPSR
	LDR R1,=SWI_TEST_STRING
    BL ExecptionHandle
	
	//3.恢复现场,跳转回原来的位置
	LDMIA SP!,{R0-R12,PC}^  //^ 表示将SPSR恢复到CPSR中

UND_TEST_STRING:
	.string "enter undefin mode!\n"    //汇编中定义带'\0'的字符串为.string
	
SWI_TEST_STRING:
	.string "enter swi mode!\n"

.align 4                                //4字节对齐。防止string的不对齐而取地址自动对齐造成的异常执行
RESET:
	MOV R0,#0
	LDR R1,[R0]
	
	STR R0,[R0]
	LDR R2,[R0]
	
	CMP R2,R0
	LDR SP,=0x40000000+4096
	MOVEQ SP,#4096
	STREQ R1,[R0]
	
	BL HardwareInitAll
	BL UartInit
	
TEST_UND:
	bl testPrint                    //调试时发现这里必须存在一个语句下面的未定义指令才会生效,
	.word 0xdeadc0de                //原因未知,已排除未对齐原因
	//bl testPrint
TEST_SWI:
	MRS R0,CPSR
	BIC R0,R0,#0x0F                //切换到usr模式
	MSR CPSR,R0
	SWI 0x123
	
	LDR pc,=main
halt:
    B halt
execption.h
----------------------------
#ifndef __EXCEPTION_H
#define __EXCEPTION_H

#include <stdint.h>

void UndExecptionHandle(uint32_t CPSR,char* string);

#endif
execption.c
------------------------

#include "execption.h"
#include "uart.h"

void ExecptionHandle(uint32_t CPSR,char* string)
{
	printHex(CPSR);
	puts(string);
}
uart.h
-----------------------------
#ifndef __UART_H
#define __UART_H

#include <stdint.h>

void UartInit(void);

void putc(uint8_t character);
uint8_t getc(void);

void printHex(uint32_t value);
void puts(char* string);
void testPrint();
#endif


#include "uart.h"


#include "s3c2440.h"


void UartInit(void)
{
	//GPIO init
	GPHCON &= ~((3<<6) | (3<<4));
	GPHCON |= (2<<6) | (2<<4);

	//UART init
	ULCON0 = 3;  //8n1
	UCON0 = (1<<2) | (1<<0);
	UBRDIV0 = (int32_t)( 50000000/ (115200 * 16) ) -1;
}


static uint8_t IsReadyToSend(void)
{
	return UTRSTAT0 & (1<<1);
}


static uint8_t IsReadyToReceive(void)
{
	return UTRSTAT0 & (1<<0);
}

void putc(uint8_t character)
{
	if(character==(uint8_t)('\n'))
	{
		while(!IsReadyToSend());
		UTXH0 = (uint8_t)'\r';
	}
	while(!IsReadyToSend());
	UTXH0 = character;
}

uint8_t getc(void)
{
	while(!IsReadyToReceive());
	return URXH0;
}

void printHex(uint32_t value)
{
	int i=0;	
	char output[8]={0};

	for(i = 0;i<8;i++)
	{
		output[i] = value & 0xf;
		value >>= 4;
	}

	puts("0x");
	for(i = 7; i>=0; i--)
	{
		if(output[i]>=0 && output[i]<=9)
			output[i] += '0';
		else
			output[i] = output[i] - 10 + 'A';
		putc(output[i]);
	}
	putc('\n');
}

void puts(char* string)
{
	while(*string)
	{
		putc(*string++);
	}
}

void testPrint()
{
	puts("111\n");
}

#include <stdint.h>

#include "s3c2440.h"
#include "led.h"
#include "uart.h"

int main()
{
	//HardwareInitAll();
	//UartInit();

	puts("main function!\n");
	while(1);
	return 0;
}

CPSR явление в свою очередь, определяется режим печати, основные функции строки и строки неопределенными строку, CPSR программные прерывания, программные прерывания.

Существует игра мягкого прерывания SWI активного триггера, вы можете принять ряд операций, так что наш обработчик может определить, что должно быть выполнено в соответствии с количеством операции действия. Здесь идея состоит в том, чтобы получить адреса SWI от LR, значение извлеченного адреса, ручной секции извлечения эталонного операнда в соответствии с инструкциями ARM, чтобы завершить операцию.

Вы можете увидеть количество работающих SWI является 0-23bit. Инструкция 4 байта, адрес может быть получен непосредственно с помощью вызова SWI LR-4.

Start.S

.text
.global _start

_start:
	B RESET	
	LDR pc,UNDEFIE
	LDR pc,SW_INTERRUPT

...//省略重复代码
	
DO_SWI:
	//1.设置栈
	LDR SP,=0x33e00000
	//2.保存现场
	STMDB SP!,{R0-R12,LR}
	
	//处理函数
	MRS R0,CPSR
	LDR R1,=SWI_TEST_STRING
	SUB R2,LR,#4                            //减去4,得到SWI地址
    BL SWIHandler
	
	//3.恢复现场,跳转回原来的位置
	LDMIA SP!,{R0-R12,PC}^  //^ 表示将SPSR恢复到CPSR中

UND_TEST_STRING:
	.string "enter undefin mode!\n"
	
SWI_TEST_STRING:
	.string "enter swi mode!\n"

...

TEST_SWI:
	MRS R0,CPSR
	BIC R0,R0,#0x0F
	MSR CPSR,R0
	SWI 0x123
	
	LDR pc,=main
halt:
    B halt
execption.c
-----------------------
#include "execption.h"
#include "uart.h"

void ExecptionHandle(uint32_t CPSR,char* string)
{
	printHex(CPSR);
	puts(string);
}


void SWIHandler(uint32_t CPSR,char* string,uint32_t* opera_address)
{
	ExecptionHandle(CPSR,string);
	printHex((*opera_address) & 0xFFFFFF);
}

Выход для печати является 0x123.

 
Опубликовано 19 оригинальных статей · вона похвала 7 · просмотров 6919

рекомендация

отblog.csdn.net/G_METHOD/article/details/104547407