|
|
  |
MEMMAP = 2; на LPC2146 |
|
|
|
Jan 15 2008, 11:38
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Здравствуйте, код ниже работает с MEMMAP = 1 и не работает с MEMMAP = 2 (переключается препроцессором). Может, я какую мелочь упустил? Спасибо. Код #include <iolpc2146.h> #include <intrinsics.h>
#define BIT_(x) (1 << (x))
namespace { unsigned const DBG_PIN = 24; }
enum vec_id_t { VEC_RESET = 0, VEC_UNDEF = 1, VEC_SWI = 2, VEC_PREFETCH = 3, VEC_DATA_ABORT = 4, VEC_RESERVED__ = 5, VEC_IRQ = 6, VEC_FIQ = 7, VEC_TOTAL_NUM = 8 };
#define MEMMAP_OPTION (1)
#if 1 == MEMMAP_OPTION #define VIC_ISR __irq __arm #else #pragma location=0x40000000 __no_init unsigned intvec[VEC_TOTAL_NUM * 2]; #define VIC_ISR #endif
VIC_ISR void irq_timer(void); VIC_ISR void non_vectored_handler(void);
extern "C" __irq __arm void reset_handler(void) {} extern "C" __irq __arm void undef_handler(void) {} extern "C" __irq __arm void swi_handler(void) {} extern "C" __irq __arm void prefetch_handler(void) {} extern "C" __irq __arm void data_handler(void) {} extern "C" __irq __arm void fiq_handler(void) {}
#if 2 == MEMMAP_OPTION __irq __arm void irq_handler(void) { typedef void (VIC_ISR * handler_t)(void); handler_t h = reinterpret_cast<handler_t>(VICVectAddr); (*h)(); } #endif
void hw_init(void) { PCON = 0; PCONP = BIT_(1);
VPBDIV = 1; MAMCR = 0; MAMTIM = 2; MAMCR = 2; MEMMAP = MEMMAP_OPTION; #if 2 == MEMMAP_OPTION for (unsigned i = 0; i < VEC_TOTAL_NUM; ++i) { intvec[i] = 0x18F09FE5; // ldr pc, [pc, #24]; } intvec[VEC_TOTAL_NUM + VEC_RESET] = reinterpret_cast<unsigned>(&reset_handler); intvec[VEC_TOTAL_NUM + VEC_UNDEF] = reinterpret_cast<unsigned>(&undef_handler); intvec[VEC_TOTAL_NUM + VEC_SWI] = reinterpret_cast<unsigned>(&swi_handler); intvec[VEC_TOTAL_NUM + VEC_PREFETCH] = reinterpret_cast<unsigned>(&prefetch_handler); intvec[VEC_TOTAL_NUM + VEC_DATA_ABORT] = reinterpret_cast<unsigned>(&data_handler); intvec[VEC_TOTAL_NUM + VEC_IRQ] = reinterpret_cast<unsigned>(&irq_handler); intvec[VEC_TOTAL_NUM + VEC_FIQ] = reinterpret_cast<unsigned>(&fiq_handler); #endif
VICSoftIntClear = ~0; VICIntEnClear = ~0; VICIntSelect = 0;
VICVectAddr0 = reinterpret_cast<unsigned long>(&irq_timer); VICVectCntl0 = 4 + BIT_(5); VICIntSelect &= ~BIT_(4); VICDefVectAddr = reinterpret_cast<unsigned long>(&non_vectored_handler);
VICIntEnable = BIT_(4);
VICProtection = 1; VICVectAddr = 0;
T0IR = 0xFF; T0TCR = BIT_(0) + BIT_(1); T0CTCR = 0; T0PR = 0; T0PC = 0; T0MCR = 0; T0CCR = 0; T0EMR = 0; T0TCR = BIT_(0); SCS = BIT_(1); PINSEL2 &= ~BIT_(3); FIO1DIR |= BIT_(DBG_PIN); }
namespace { unsigned const TIMER_TICK = 20000000 / 1000; }
void start(void) { T0MR0 = T0TC + TIMER_TICK; T0MCR_bit.MR0INT = 1; __enable_interrupt(); }
int main(void) { hw_init(); start(); while (true) {} }
VIC_ISR void irq_timer(void) { T0MR0 += TIMER_TICK; FIO1PIN ^= BIT_(DBG_PIN); T0IR = T0IR; VICVectAddr = 0; }
VIC_ISR void non_vectored_handler(void) { VICVectAddr = 0; }
|
|
|
|
|
Jan 15 2008, 11:58
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(alexander55 @ Jan 15 2008, 14:53)  Для отладки в RAM кроме MEMMAP=2, нужно перестроить распределение памяти для линкера. Идей кроме как сдвинуть нижнюю границу RAM - нет. -DRAMSTART=40000040 -DRAMEND=40007FFF Не работает. Да и не используются у меня в этом фрагменте нижние адреса RAM.
Сообщение отредактировал meister - Jan 15 2008, 12:12
|
|
|
|
|
Jan 15 2008, 13:03
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(alexander55 @ Jan 15 2008, 15:48)  А что с ROM ? -DROMSTART=00000040 -DROMEND=0003FFFF -Z(CODE)INTVEC=00-3F -Z(CODE)ICODE,DIFUNCT=ROMSTART-ROMEND -Z(CODE)SWITAB=ROMSTART-ROMEND -Z(CODE)CODE=ROMSTART-ROMEND -Z(CONST)CODE_ID=ROMSTART-ROMEND -Z(CONST)INITTAB,DATA_ID,DATA_C=ROMSTART-ROMEND -Z(CONST)CHECKSUM=ROMSTART-ROMEND Но это же должно быть абсолютно без разницы, раз уж работает с MEMMAP = 1 - только место, откуда будут браться вектора прерываний изменится. Вот это у меня точно правильно? Код intvec[i] = 0x18F09FE5; // ldr pc, [pc, #24];
|
|
|
|
|
Jan 15 2008, 13:40
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(meister @ Jan 15 2008, 16:03)  -DROMSTART=00000040 -DROMEND=0003FFFF Сделайте так. -DROMSTART=0 -DROMEND=0
|
|
|
|
|
Jan 15 2008, 13:53
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(alexander55 @ Jan 15 2008, 16:40)  Сделайте так. -DROMSTART=0 -DROMEND=0 В общем-то ожидаемо: Building configuration: memmap2 - Debug Updating build tree... entry.cpp Linking Error[e16]: Segment ICODE (size: 0xec align: 0x2) is too long for segment definition. At least 0xec more bytes needed. The problem occurred while processing the segment placement command "-Z(CODE)ICODE,DIFUNCT=ROMSTART-ROMEND", where at the moment of placement the available memory ranges were "-none-" Reserved ranges relevant to this placement: 0-1f INTVEC Total number of errors: 1 Total number of warnings: 0
|
|
|
|
|
Jan 15 2008, 14:16
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(meister @ Jan 15 2008, 16:53)  У Вас жалуется линкер на ICODE. Рекомендую посмотреть примерчик для размещения в RAM и сделать по аналогии. М.б. -Z(CODE)INTVEC=40000000-4000003f
|
|
|
|
|
Jan 15 2008, 18:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(meister @ Jan 15 2008, 18:25)  Вся разница этих двух режимов - откуда процессор будет вынимать байты. На самом деле разницы никакой - он во обоих случаях берет байты из нулевых адресов. Отражен туда кусочек ОЗУ или нет - для него не важно. Посмотрите вот этот проект - мне удалось сделать выбор флеш/ОЗУ выбором скрипта линкера и скрипта отладчика (.mac). Исходники идентичны для обоих случаев.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 15 2008, 19:16
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(Сергей Борщ @ Jan 15 2008, 21:56)  На самом деле разницы никакой - он во обоих случаях берет байты из нулевых адресов. Я имел ввиду физические адреса ну или саму память. Код for( i = 0; i < 0x40; i += 4 ) { tmp = __readMemory32(0x40000000 + i, "Memory"); __writeMemory32(tmp,0x00000000 + i, "Memory"); } Ну это понятно, хоть мне так и не подойдет - у меня там branch стоят, да и перемапивание у мена делается не просто так - там нужно другие обработчики подставить (поменять основные на заглушки), пока основные будут стерты. Перед тем, как я сегодня ушел с работы - я поменял endian у 0x18F09FE5 и процессор стал заходить в прерывание. Один раз. Потом опять ломается. Попробовал собрать инструкцию ldr pc, [pc, #24] руками - так и получается.
|
|
|
|
|
Jan 15 2008, 19:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(meister @ Jan 15 2008, 21:16)  Ну это понятно, хоть мне так и не подойдет - у меня там branch стоят, да и перемапивание у мена делается не просто так - там нужно другие обработчики подставить (поменять основные на заглушки), пока основные будут стерты. ууууу... А надо ли стирать основные? Потенциальная возможность получить полностью нерабочее устройство после сбоя во время перепрошивки. Гляньте тут и тут Если я правильно догадался, и вы пишете загрузчик.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 16 2008, 06:36
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Проблема с MEMMAP = 2; была решена написанием "нормального" обработчика сброса Код org 0x00 __program_start: LDR pc, [pc, #24] undefvec: B undef_handler swivec: B swi_handler pabtvec: B prefetch_handler dabtvec: B data_handler
org 0x18 irqvec: B irq_handler fiqvec: B fiq_handler org 0x20 DC32 ?cstartup Код intvec[VEC_TOTAL_NUM + VEC_RESET] = ARM7TDMI_MEM_32(0x00000020); и только затем  Код MEMMAP = MEMMAP_OPTION; Цитата(Сергей Борщ @ Jan 15 2008, 22:56)  Если я правильно догадался, и вы пишете загрузчик. Правильно  Спасибо за ссылки, буду смотреть и думать.
|
|
|
|
|
Jan 16 2008, 08:01
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Я тут дебажил  и наткнулся на такой код: // 287 __enable_interrupt(); _BLF ??EnI_t,??rT??EnI_t который, я подозреваю, передает управление в стертый сектор и программа ломается. На что переписать __enable_interrupt и __disable_interrupt? Я попробовал на Код MODULE BOOTLOADER_UTIL; PUBLIC bootloader_enable_interrupt; PUBLIC bootloader_disable_interrupt; RSEG BOOTLOADERCODE CODE32
bootloader_enable_interrupt: PUSH {r0} MRS r0, cpsr ORR r0, r0, #192 MSR cpsr_c, r0 POP {r0} BX lr;
bootloader_disable_interrupt: PUSH {r0} MRS r0, cpsr bic r0, r0, #192 MSR cpsr_c, r0 POP {r0} BX lr;
LTORG; ENDMOD; не работает совсем
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|