Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по АРМ LPC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vesago
Хочу сделать первый проект на арм. Выбрал в частности 2214. С инструментарием определился - кейл.
Хочу спросить - программный мастер 1 варе хорошо будет работать на этом камне или лучьше взять мелкий сопроцессор типа 2313 и по уарту слать? Нормально lpc будет работать с max232? Знаю, что lpc толерантен к 5В, но спрошу на всякий случай. И вообще, действительно ли можно оперировать свободно с 5в цепями?
Ken@t
Цитата(vesago @ Jan 20 2006, 14:13) *
Хочу сделать первый проект на арм. Выбрал в частности 2214. С инструментарием определился - кейл.
Хочу спросить - программный мастер 1 варе хорошо будет работать на этом камне или лучьше взять мелкий сопроцессор типа 2313 и по уарту слать? Нормально lpc будет работать с max232? Знаю, что lpc толерантен к 5В, но спрошу на всякий случай. И вообще, действительно ли можно оперировать свободно с 5в цепями?

Програаммный мастер - как напишите, есть огранияения на скорость махания ногами.
лучше взять мах3232 , помнить что утилита писания флэша может сама вставать в режим ISP исли заведёте RTS и DTR иначе придётся делать перемычки.
Схема сброса вязть нормальную микруху с внешним сбросом или на худой конец R-C + тактовая кнопка.
Толерантен к выходам - входам 5V но зачем, сейчас 3.3 логики - как грязи. Да и мелкую логику - ну нах , Xelinx 9500XL ставте и будет счастье...
Помнить что некотрые линии без пуллапа SDL SDA , TxD
Если серьёзно думаете работать с ARM7TDMI возьмите МТ-ЛИнк , но есть инфа что проект закрыт.
можно и виглер, но это гамадризм...

Номинал кварц брать из даташита ..

вроде всё
vesago
Благодарю за такой развернутый ответ. А куда заводить DTR DSR? Почитал в um про заливку кода - не нашел таких тонкостей.
iit
Цитата(Ken@t @ Jan 20 2006, 15:16) *
Если серьёзно думаете работать с ARM7TDMI возьмите МТ-ЛИнк , но есть инфа что проект закрыт.


Откуда такая информация и по какой причине?
zltigo
Цитата(iit @ Jan 20 2006, 16:00) *
Откуда такая информация и по какой причине?

От автора. О причинах отказался сообщить.
VAI
Цитата(iit @ Jan 20 2006, 18:00) *
Цитата(Ken@t @ Jan 20 2006, 15:16) *

Если серьёзно думаете работать с ARM7TDMI возьмите МТ-ЛИнк , но есть инфа что проект закрыт.


Откуда такая информация и по какой причине?

http://electronix.ru/forum/index.php?showt...886&#entry77886
zltigo
Цитата(vesago @ Jan 20 2006, 15:20) *
Почитал в um про заливку кода - не нашел таких тонкостей.

Значит пора переходить к чтению an :-) и собственно описания LPC2000 Flash
или ее заменителя.
Ken@t
DTR заводится на RESET проца
RTS на P0.14
помнить что P0.14 = '1' для перехода в бутлодырь , в реальой жизни надо притягивать его к общему и следить если используется как вывод чтоб 1 небыло во время сброса.
сброс отрицательным фронтом. вообще читать даташит в первую очередь , вернее юзер мануал.
vesago
Спасибо, Kenat. Хотел еще спросить - существенно ли медленнее исполняется код из флеша? Стоит ли максимально грузить в рам или в большинстве случаев можно из флеши? И еще - можно как нибудь дистанционно запустить загрузку во флешь используя штатный загрузчик. Допустим прибор где нибудь в отдалении по 485 связан и надобно поменять прошивку? Я так понял 14 лапу сожают на землю только для того, чтоб после ресета камень перешел в область загрузчика.
makc
Цитата(vesago @ Jan 22 2006, 12:22) *
Спасибо, Kenat. Хотел еще спросить - существенно ли медленнее исполняется код из флеша? Стоит ли максимально грузить в рам или в большинстве случаев можно из флеши?


На этот и некоторые другие вопросы есть ответы в FAQ на сахаре: http://www.caxapa.ru/faq/lpc2000.html
Ken@t
Цитата(vesago @ Jan 22 2006, 12:22) *
Спасибо, Kenat. Хотел еще спросить - существенно ли медленнее исполняется код из флеша? Стоит ли максимально грузить в рам или в большинстве случаев можно из флеши? И еще - можно как нибудь дистанционно запустить загрузку во флешь используя штатный загрузчик. Допустим прибор где нибудь в отдалении по 485 связан и надобно поменять прошивку? Я так понял 14 лапу сожают на землю только для того, чтоб после ресета камень перешел в область загрузчика.

скорость выполнения программ зависит от ваших требований. Только учтите, что скорость махание лапками ограничено аппаратной реализацией .
Для загрузки своего кода можно применить технологию IAP + преназначение области встроенной RAM на вектора прерыванией MEMMAP ..
код IAP прилагаю с примером.


iap.h
Код
#ifndef _IAP_H
#define _IAP_H

// Results from flashInit()
#define LPC256K                 2
#define LPC128K                 1
#define LPCUNKN                -1

// (Philips) Status Codes
#define CMD_SUCCESS             0
#define INVALID_CMD             1
#define SRC_ADDR_ERROR          2
#define DST_ADDR_ERROR          3
#define SRC_ADDR_NOT_MAPPED     4
#define DST_ADDR_NOT_MAPPED     5
#define COUNT_ERROR             6
#define INVALID_SECTOR          7
#define SECTOR_NOT_BLANK        8
#define SECTOR_NOT_PREPARED     9
#define COMPARE_ERROR           10
#define BUSY                    11
#define PARAM_ERROR             12
#define ADDR_ERROR              13
#define ADDR_NOT_MAPPED         14
#define CMD_LOCKED              15
#define INVALID_CODE            16
#define INVALID_BAUD_RATE       17
#define INVALID_STOP_BIT        18
#define CODE_READ_PROT_ENABLED  19

int flashBlank(int startSector, int endSector);
int flashErase(int startSector, int endSector);
int flashInit(void);
int flashWrite(void *dst, void *src, unsigned byteCount);

#endif


iap.c
Код
#include <intrinsic.h>
#include "string.h"
#include "iap.h"


#define IAP_LOCATION 0x7ffffff1
typedef void (*IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;

static unsigned long    flashParams[5],
                 flashResult[2];
static int         lastSector;

#ifndef MIN
#define MIN(n,m)      (((n) < (m)) ? (n) : (m))
#endif


int GetProcessorClockFreq(void);
int GetPeripheralClockFreq(void);


int flashBlank(int startSector, int endSector)
{
  flashParams[0] = 53;                  // blank check
  flashParams[1] = startSector;         // start sector
  flashParams[2] = endSector;           // end sector
  iap_entry(flashParams,flashResult);
  return (int)flashResult[0];
}

int flashErase(int startSector, int endSector)
{
// unsigned long cpsr;
//  unsigned char memmap;

  __disable_interrupt();
// memmap = MEMMAP;                      // get current memory map
// MEMMAP = MEMMAP_FLASH;                // map User Flash into low 64 bytes

  flashParams[0] = 50;                  // prepare sector(s)
  flashParams[1] = startSector;         // start sector
  flashParams[2] = endSector;           // end sector

  iap_entry(flashParams,flashResult);

  if (flashResult[0] == CMD_SUCCESS)
  {
    flashParams[0] = 52;                // erase sector(s)
    flashParams[1] = startSector;       // start sector
    flashParams[2] = endSector;         // end sector
    flashParams[3] = GetProcessorClockFreq()/1000;         // cpu clock freq in KHz
    iap_entry(flashParams,flashResult);
  }

  //MEMMAP = memmap & 0x03;               // restore the memory map
  __enable_interrupt();
  return (int)flashResult[0];
}

int flashInit(void)
{
  lastSector = 0;                       // clear last usable sector #

  switch (flashBlank(16, 16))           // check last sector of 256K parts
    {
    case CMD_SUCCESS:
    case SECTOR_NOT_BLANK:
      lastSector = 16;                  // store last usable sector #
      return LPC256K;

    case INVALID_SECTOR:
      break;

    default:
      return LPCUNKN;
    }

  switch (flashBlank(14, 14))           // check last sector of 128K parts
    {
    case CMD_SUCCESS:
    case SECTOR_NOT_BLANK:
      lastSector = 14;                  // store last usable sector #
      return LPC128K;

    default:
      break;
    }

  return LPCUNKN;
}

int flashWrite(void *dst, void *src, unsigned byteCount)
{
//  unsigned char memmap;
  unsigned long count;    //  cpsr,;
  unsigned long buffer[512/sizeof (long)];

  if ((lastSector == 0) &&
      ( flashInit() == LPCUNKN))
    return BUSY;

  while (byteCount) {
//    cpsr = disableINTs();               // disable all interrupts
  __disable_interrupt();

//    memmap = MEMMAP;                    // get current memory map
//    MEMMAP = MEMMAP_FLASH;              // map User Flash into low 64 bytes

    // prepare all sectors for programing
   flashParams[0] = 50;                // prepare sectors
   flashParams[1] = 0;                 // start sector
   flashParams[2] = lastSector;        // last sector
   iap_entry(flashParams,flashResult);

   if (flashResult[0] != CMD_SUCCESS) {
//      MEMMAP = memmap & 0x03;           // restore the memory map
//      restoreINTs(cpsr);                // restore all interrupts
     __enable_interrupt();
    return flashResult[0];
   }

    // check if dst is on 512 byte boundary
   if ((unsigned long)dst & 0x1FF) {
      // no, copy 512 bytes from flash into buffer
    memcpy(buffer, (void *)((unsigned long)dst & ~0x1FF), 512);

      // copy src into buffer
    count = MIN(byteCount, (512 - ((unsigned long)dst & 0x1FF)));
    memcpy((char *)buffer + ((unsigned long)dst & 0x1FF), src, count);

    flashParams[0] = 51;              // copy RAM to Flash
    flashParams[1] = (unsigned long)dst & ~0x1FF; // destination
    flashParams[2] = (unsigned long)buffer; // source
    flashParams[3] = 512;             // byte count
    flashParams[4] = GetProcessorClockFreq()/1000;       // CCLK in KHz
    iap_entry(flashParams,flashResult);

//    MEMMAP = memmap & 0x03;           // restore the memory map
//      restoreINTs(cpsr);                // restore all interrupts
    __enable_interrupt();

    if (flashResult[0] != CMD_SUCCESS)
     return (int)flashResult[0];

     dst = (char *)dst + count;
     src = (char *)src + count;
     byteCount -= count;
     continue;                         // restart the loop to prepare sectors again
   }

   // dst is now aligned on a 512 byte boundary
   // find the biggest chunk we can program at a time
   if (byteCount >= 8192)
     count = 8192;
   else if (byteCount >= 4096)
     count = 4096;
   else if (byteCount >= 1024)
    count = 1024;
   else if (byteCount >= 512)
     count = 512;
   else
     count = byteCount;

   if (count < 512) {
    memcpy(buffer, dst, 512);           // copy current flash contents into buffer
    memcpy(buffer, src, count);          // update buffer with the new contents
    flashParams[2] = (unsigned long)buffer; // source
    flashParams[3] = 512;             // byte count
   } else  {
    flashParams[2] = (unsigned long)src;
    flashParams[3] = count;           // byte count
   }

   flashParams[0] = 51;                // copy RAM to Flash
   flashParams[1] = (unsigned long)dst; // destination
   flashParams[4] = GetProcessorClockFreq()/1000;         // CCLK in KHz

   iap_entry(flashParams,flashResult);

//    MEMMAP = memmap & 0x03;             // restore the memory map
//    restoreINTs(cpsr);                  // restore all interrupts
   __enable_interrupt();

   if (flashResult[0] != CMD_SUCCESS)
    return (int)flashResult[0];

   dst = (char *)dst + count;
   src = (char *)src + count;
   byteCount -= count;
  }

  return CMD_SUCCESS;
}


пример
Код
        // 1 Erase 16 block
     printf ("Erase calibration\r\n");
     rslt = flashErase(16, 16);
     printf ("Result = 0x%04X\r\n",rslt);
     printf ("Write calibration\r\n");
     rslt = flashWrite((int *)pCalibration, &ZerroREDOX, sizeof(int));
     printf ("Result = 0x%04X\r\n",rslt);
vesago
Большое спасибо! Буду переваривать.
А какую максимальную частоту SPI можно выжать из LPC? Судя по юзер мануалу - не более 8 МГц. Или я не правильно понял?
-=Space=-
Да, мудрено
вот тольок я не увидел код описания и инициализации переменных во флешь памяти
никак не пойму как сделать это правильно.

сейчас так:

"globals.h"
Код
typedef union {
int i;
unsigned char b[4];
float r;
} RealByte;


"IAP.cpp"
Код
#include <inarm.h>
#include <iolpc2214.h>
#include "globals.h"
#include "iap.h"
#include "string.h"

const RealByte ParamInEEPROM[6] @ "EEPROM" =
        {
        500, 2000, 10, 120, 0.1, 1.3        // Mic1 sensor
        };

RealByte const *  pParamInEEPROM = ParamInEEPROM;


EEPROM - один сектор flash, 16ый, адреса 0x0003 C000 - DFFF) в проце LPC2214

Код
-DEEPROMSTART=0x0003C000
-DEEPROMEND=0003DFFF

-Z(DATA)EEPROM=EEPROMSTART-EEPROMEND




pParamInEEPROM - используется в других модулях
Если делать extern сам массив , то линкер выдает ошибку , типа undefine external symbol

Сейчас просто Warning
"Warning[w29]: Parts of segment EEPROM are initialized (as in module IAP), even though it is of type DATA (and thus not promable)"

и что с ним делать? совсем не понятно


да , кстати при инициализации 0.1 , 1.3 преобразовываются в int
а мне это не нужно, может есть какие мысли по поводу как это исправить?


---------------------------------

по второму вопросу разобрался
надо делать так
Код
const RealByte ParamInEEPROM[6] @ "EEPROM" =
        {
          500, 2000, 10, 120, {.r = 0.1}, {.r = 1.3}        // Mic1 sensor
        };
elantra
Цитата(vesago @ Jan 22 2006, 14:18) *
Большое спасибо! Буду переваривать.
А какую максимальную частоту SPI можно выжать из LPC? Судя по юзер мануалу - не более 8 МГц. Или я не правильно понял?

Реально удалось пропустить 1.6 МБита на такте 2.5 МГц (тактовая процессора-60 МГц). Там получаются большие дырки между байтами. Слишком простой SPI.
zltigo
Цитата(vesago @ Jan 22 2006, 13:18) *
Большое спасибо! Буду переваривать.
А какую максимальную частоту SPI можно выжать из LPC? Судя по юзер мануалу - не более 8 МГц. Или я не правильно понял?

7,5 - 1/8 тактовой. Для 213x/4x SSP мастером - на 1/2 тактовой, есть FIFO и SSEL аппаратный работает.
Полную 30MHz скорость, естественно, не развить, ибо FIFO разгружается быстрее, чем его можно реально загружать.
-=Space=-
Что то я туплю, уже целый день туплю.
где то глюк есть.

Вообщем по UART запускаю процедуру IAP, зашиваю коэффициенты во флешь, результат выполнения этой процедуры запихиваю в буфер + устанавливаю счетчик байт на отправку
следущим запросом хочу получить этот результат, но !
при этом запросе получаю 000 , т.е. буфер пуст и счетчик кем то сброшен.
При пошаговой отладке место сброса буфера не обнаруживается, но стоит поставить breakpoint на прерывание от uarta, и я сразу вижу что буфер со счетчиком изменены

Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура
__segment_init() - стандартная процедура выполняется еще до main()
но кто вызывает ее и зачем мне выяснить не удалось
Если закоментировать процедуру IAP то проблемы нет

RAM юзается до адреса 0x87F, т.е. 0x0400_0000 - 0x0400_087F
В описании на IAP написано чт оюзаются последнии 16 байт RAM, вроде не пресекамся, даже близко

Ткните пальцем что я не правильно делаю.

-------------------
поставил точку останова не адрес 0 и она сработала
значит это ресет
вот тольок какой то задерженный, почему дает выйди из процедуры и не проявлется при пошаговой отладке?
всеравно не понятно
PLL выключен
zltigo
Цитата(-=Space=- @ Jun 6 2006, 17:09) *
Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура
__segment_init() - стандартная процедура выполняется еще до main()
но кто вызывает ее и зачем мне выяснить не удалось

Правильная процедура для инициализации неиспользуемой памяти нулями в инициализируемом сегменте даных . Располагайте свои буфера в неинициализированной памяти (смотрите __no_init
но будут проблемы при старте не через Вашу IAP процедуру), либо, что правильно, инициализируйте их самостоятельно данными из Flash уже в main() а не в IAP процедуре.
-=Space=-
я так почти везде и делаю
все глобальные пременные, которые я сам инициализирую, я объявляю как __no_init,
но с данным буфером и счетчиком такой фокус не пойдет
по значсению 0 я и определяю нужно мне что то отвечать на запрос или нет.
а если при включении там останется мусор?

Вопрос свелся не почему вызывается __segment_init() и зачем он нужен
а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?
zltigo
Цитата(-=Space=- @ Jun 6 2006, 19:05) *
Вопрос свелся не почему вызывается __segment_init() и зачем он нужен
а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?

Вопрос звучал _совсем_ не так.

По reset - вычитывайте исходники writeflash().
Прерывания, надеюсь, запрещены?
Watchdog - как у Вас?
Версия Bootloader какая? Без официальных багов с PLL?
GetSmart
Чую, прерывания разрешены и всё падает на ресет. Это если конечно writeflash() не кривая.
А в конце RAM зарезервированно 32 байта.
-=Space=-
Цитата
По reset - вычитывайте исходники writeflash().

Не совсем понял, это про что?
Цитата
Прерывания, надеюсь, запрещены?

прерывания отключаются при входе в flashwrite()
и вновь разрешаются при выходе из нее
Цитата
Watchdog - как у Вас?

никогда не использовался
в моем коде нет команд работы с WD, а после ресета он вроде выключен.
может его IAP включать?
Цитата
Версия Bootloader какая? Без официальных багов с PLL?

Команда 55 выдала 0x01 0x40
кстати PLL выключен , проц работает на частоте кварца 11,059МГц
(это из соображений минимизации потребления)
-=Space=-
Цитата(GetSmart @ Jun 7 2006, 03:29) *
Чую, прерывания разрешены и всё падает на ресет. Это если конечно writeflash() не кривая.
А в конце RAM зарезервированно 32 байта.


привожу свою процедуру flashWrite()
немного соптимизировал ее
1. стирание сектора включено в процедуру записи
2. массив данных во flash всегда начинается с начала сектораи размером не больше сектора
потом будет const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....}
т.е. 8K - ровно 1 сектор


Код
int flashWrite(void)
{
RealByte buffer[512/sizeof (long)];
int i,result;

__disable_interrupt();

flashParams[0] = 50;       // prepare sector
flashParams[1] = 16;        // start sector
flashParams[2] = 16;       // end sector

iap_entry(flashParams,flashResult);

if (flashResult[0] != CMD_SUCCESS) {
    __enable_interrupt();
    return flashResult[0];
       }

flashParams[0] = 52;       // erase sector)
flashParams[1] = 16;       // start sector
flashParams[2] = 16;       // end sector
flashParams[3] = GetProcessorClockFreq()/1000;         // cpu clock freq in KHz
iap_entry(flashParams,flashResult);

if (flashResult[0] != CMD_SUCCESS) {
    __enable_interrupt();
    return flashResult[0];
       }

// prepare all sectors for programing
flashParams[0] = 50;       // prepare sectors
flashParams[1] = 16;       // start sector
flashParams[2] = 16;        // last sector
iap_entry(flashParams,flashResult);

if (flashResult[0] != CMD_SUCCESS) {
    __enable_interrupt();
    return flashResult[0];
       }

// загрузка буфера
for(i=0;i<512/sizeof (long);i++) buffer[i].i = 0xffffffff;

buffer[0].i =  SensorMic.MicP1;
/* .......... */
/* здесь продолжается заполнятся массив  */
/* .......... */


flashParams[0] = 51;              // copy RAM to Flash
flashParams[1] = (unsigned long)ParamInEEPROM;     // destination
flashParams[2] = (unsigned long)buffer;             // source
flashParams[3] = 512;                                 // byte count
flashParams[4] = GetProcessorClockFreq()/1000;     // CCLK in KHz
iap_entry(flashParams,flashResult);

if (flashResult[0] != CMD_SUCCESS) {
    __enable_interrupt();
    return flashResult[0];
       }

__enable_interrupt();
return CMD_SUCCESS;
}
zltigo
Код
RealByte buffer[512/sizeof (long)];
....

// загрузка буфера
for(i=0;i<512/sizeof (long);i++) buffer[i].i = 0xffffffff;
.......
buffer[0].i =  SensorMic.MicP1;
.......

Что-то более чем мутное с буфером и адресацией в нем.


1. А в стеке место есть под буфер?
2. дабы все было непонятно используем sizeof(long);
3. Ну жуткая необходимость была называть элемент union 'i';
-=Space=-
Цитата(zltigo @ Jun 7 2006, 10:57) *
Что-то более чем мутное с буфером и адресацией в нем.

RealByte это union из 4 байт которым может читаться как int как float или как 4 отдельных байта
ну мне просто нужен не типизированный 4 байтовый буфер , и я так вышел из положения
исходники RealByte были выше

Кстати провел опыт:
сразу после reseta посылаю стаус WD, там должен появиться бит если сброс произошел из-за таймаута WD. Получаю 00, т.е. Reset "внешний", не WDшный.

Вот только происходит он не сразу, я успеваю отправить как минимум один байт - подтверждение что команда выполнена (просто байт 0x01)
Бывает что успеваю и запросить ответ - результат выполнения функции flashWrite
(всего по протоколу получается 9 байт)
но вероятность этого мала, получилось всего 1- 2 раза.
0x01 принимается всегда.
GetSmart
Покажите-ка как объявляется "iap_entry"
Ну и "RealByte" заодно.
И ещё "flashParams" и "flashResult".
В каком режиме скомпилена прога ARM or THUMB?
И не понял что это такое:
const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....}
Можно "дословно" это написать? Дело ведь в ИАРе происходит?
zltigo
А в стеке место есть под буфер?
100 против 1, что нет.
GetSmart
А можно увидеть вырезку из дизассемблера для процедуры flashWrite ?
-=Space=-
Вообщем выкладываю почти весь проект
в основном модули которые интересны
все остальные сенсорные модули имеют туже структуру что и sensor_radiation.cpp


Цитата
А в стеке место есть под буфер?
100 против 1, что нет.

в стеке 1024 байта, помоему более чем достаточно
а точно локальные переменные в стеке хранятся?
надо проверить
-=Space=-
И всетаки ошибка со стеком была
исправил.
функция flashwrite() вызывается по uart, а это в прерывании
т.е. стек юзается не CSTACK , а IRQ_STACK
а он размером 0x100
он затирает адресса возвратов из функций в модуле main()
увеличил стек IRQ_STACK до 0х400

после сделал
RealByte buffer[512/sizeof (long)]; глобальным

не помогло , всеравно reset походит

может быть нельзя вызывать функции IAP из пррываний?
GetSmart
Цитата
RealByte const * pParamInEEPROM;

А Вы уверены, что хотели именно так написать? Это будет указатель на variable (!!!) (а не FLASH), который нельзя будет изменять. Это если конечно в С++ всё не запутали окончательно. Я пишу на Си.

Думаю, надо так:
const RealByte *pParamInEEPROM;

Вызывать из прерываний IAP конечно можно. Однако. Для начала сделайте прерывание от UART с возможностью вложенных прерываний. Что-то типа этого:
Цитата
__arm __irq __nested void UART1Interrupt()
{
_enaIRQ();
switch(U1IIR & 0x0f)
{
.....
}
_disIRQ();
VICVectAddr = 0; // Clear interrupt in VIC.
}

Это сделает такой фокус, что внутри прерывания стек будет использоваться глобальный. Поэтому стек прерываний уменьшите до 128..256 байт обратно.

Цитата
typedef void (*IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;

исправьте на
typedef void (__interwork *IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;

Хотя прерывание не исправляйте. Чё-то у Вас оно как-то неуклюже написано. И лучше не напрягаться, а то долго объяснять мне придётся что к чему.

Почему-то нашёл только один вектор для таймера.
-=Space=-
Цитата(GetSmart @ Jun 7 2006, 15:23) *
Вызывать из прерываний IAP конечно можно. Однако.

я вот сечас думаю а чт опроизойдет после выполнения __enable_interrupt(); в функции flashWrite();?
прерывания должны разрешиться, а значит возможны вложенные прерывания
нет ли здесь какой заковырки?

Цитата(GetSmart @ Jun 7 2006, 15:23) *
Цитата
typedef void (*IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;

исправьте на
typedef void (__interwork *IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;

а это точно нужно? у меня в general options IARа стоит generete interwork code
+ весь код у меня в режиме Trumb (тамже в general options - processor mode )

Цитата(GetSmart @ Jun 7 2006, 15:23) *
Хотя прерывание не исправляйте. Чё-то у Вас оно как-то неуклюже написано. И лучше не напрягаться, а то долго объяснять мне придётся что к чему.
Почему-то нашёл только один вектор для таймера.

всмысле Interrupt.cpp
это один вектор на все прерывания - от уратов, таймеров, i2c


-------------------------добавлено

перенес функцию writeflash() из прерывания в main
и пререстало ресетить
что бы это занчило?
GetSmart
Вы угадали. Ваши прерывания написаны так, что не позволяют вложенности. А когда на выходе writeflash() вы их разрешаете, то рушится стек IRQ. Таки дела.

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

Цитата
всмысле Interrupt.cpp
это один вектор на все прерывания - от уратов, таймеров, i2c

Я говорил про векторизованные обработчики.
GetSmart
Самый простой вариант - напишите так:
__irq __arm __nested void IRQ_ISR_Handler (void)
{
...
}
-=Space=-
а в чем всетаки неуклюжесть?

это про эту функцию
#pragma vector=0x18
__irq __arm void IRQ_ISR_Handler (void)
{
void (*interrupt_function)();
unsigned int vector;

vector = VICVectAddr; // Get interrupt vector.
interrupt_function = (void(*)())vector;
(*interrupt_function)(); // Call vectored interrupt function.
}

можно было и так сделать
org 0x18
LDR PC,[PC, #-0x0FF0] /* Vector from VicVectAddr */

А лучше ли это?
кстати IRQ_ISR_Handler я не писал сам, скопипасил из какого то примера

или еще где криво написан код?

Да, еще, не разобрались с warningom
Warning[w29]: part of segment EEPROM are initialized (as in module IAP), even thought it is type DATA (and thus not promable)

пока он забит и вроде даже работает, но не красиво в проге варнинги иметь
zltigo
Цитата(-=Space=- @ Jun 7 2006, 16:18) *
а в чем всетаки неуклюжесть?

Использование офигенного количества кода вместо ОДНОЙ едиственной команды выполняющей
все, что надо.
GetSmart
Кривость именно в этих двух местах. Знаю, что это типичный пример в комплекте с компилером. Кривость - 1.медленность. 2.невозможность сделать несколько видов обработчиков, одни из которых будут допускать вложенность и работать на глобальном стеке, а другие не допускать вложенность и для максимума скорости работать на стеке IRQ. Я предпочитаю в startup'е ставить LDR PC,[PC, #-0x0FF0] и потом каждое прерывание "настраивать" на скорость или вложенность.

Попробуйте в xcl-файле изменить это:
-Z(DATA)EEPROM=EEPROMSTART-EEPROMEND
на это:
-Z(CODE)EEPROM=EEPROMSTART-EEPROMEND
или на это:
-Z(CONST)EEPROM=EEPROMSTART-EEPROMEND
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.