Перейти к содержанию
    

stm8s003 размещение функции в озу

Для удаления блока в eeprom функцию удаления необходиом расположить в озу. Не получается. Делаю вроде согласно инструкции в stm8s_flash.c.

- For Cosmic Compiler:

1- Define a segment FLASH_CODE by the mean of " #pragma section (FLASH_CODE)". This segment is defined in the stm8s_flash.c file.

2- Uncomment the "#define RAM_EXECUTION (1)" line in the stm8s.h file, or define it in Cosmic compiler preprocessor to enable the FLASH_CODE segment definition.

3- In STVD Select Project\Settings\Linker\Category "input" and in the RAM section add the FLASH_CODE segment with "-ic" options.

4- In main.c file call the _fctcpy() function with first segment character as parameter "_fctcpy('F');" to load the declared moveable code segment (FLASH_CODE) in RAM before execution.

5- By default the _fctcpy function is packaged in the Cosmic machine library, so the function prototype "int _fctcopy(char name);" must be added in main.c file.

 

в первую страницу флеш записываю последовательность 0-32. потом пытаюсь стереть эту страницу.

main.c

    _fctcpy('f');
    adr=(u8 *)0x4000;
    FLASH->DUKR = FLASH_RASS_KEY2;
    FLASH->DUKR = FLASH_RASS_KEY1;
    for (i=0;i<32;i++){
        *(adr++)=i;
        while ((FLASH->IAPSR & FLASH_IAPSR_EOP)==0);
    }
    eeErase((u8*)0x4000);
    while ((FLASH->IAPSR & FLASH_IAPSR_EOP)==0);
    FLASH->IAPSR &= (uint8_t)(~FLASH_IAPSR_DUL);

 

функция eeErase

#pragma section (flash_code)
IN_RAM(void eeErase(u8 *adr)){
    FLASH->CR2 |= FLASH_CR2_ERASE;
    FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NERASE);
    *adr++ = 0;
    *adr++ = 0;
    *adr++ = 0;
    *adr++ = 0;
}
#pragma section ()

 

в файле stm8s003k3.lsf добавляю сегмент flash_code

+seg .data -b 0x100 -m 0x100  -n .data
+seg .in_ram -a .data -n .in_ram -ic
+seg .bss -a .in_ram  -n .bss
+seg .flash_code -a .bss  -n .flash_code

 

#define RAM_EXECUTION (1) в файле stm8s.h раскоментил.

в итоге в выходном hex файле функция располагается по адресам ОЗУ, на что STVP_CmdLine.exe ругается:

>>> Loading file out/project.hex in PROGRAM MEMORY image in computer

(API) WARNING : FILE : line 42: Address 0x12C is out of range and is ignored!

 

По сути вроде правильно ругается. Только тогда я не понимаю, как расположить код функции во флеш, чтобы потом функция _fctcpy('f') скопировала его в секцию flash_code и обращение было именно к функции расположенной в ОЗУ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так будет кузявее:

/*
void
block_erase(uint8_t *dst)
{
       FLASH_CR2 = 0x20;
       FLASH_NCR2 = 0xDF;
       *dst++ = 0;
       *dst++ = 0;
       *dst++ = 0;
       *dst = 0;
}
*/

static uint8_t block_erase_code[] = {
       0x35, 0x20, 0x50, 0x5B, /* MOV FLASH_CR2, #0x20  */
       0x35, 0xDF, 0x50, 0x5C, /* MOV FLASH_NCR2, #0xDF */
       0x4F,                   /* CLR A                 */
       0xF7,                   /* LD (X), A             */
       0x5C,                   /* INCW X                */
       0xF7,                   /* LD (X), A             */
       0x5C,                   /* INCW X                */
       0xF7,                   /* LD (X), A             */
       0x5C,                   /* INCW X                */
       0xF7,                   /* LD (X), A             */
       0x81,                   /* RET                   */
};

static void (*const block_erase)(uint8_t *dst) = (void (*)(uint8_t *dst))block_erase_code;

void
flash_eraseblock(void* addr)
{
       block_erase(addr);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

static void (*const block_erase)(uint8_t *dst) = (void (*)(uint8_t *dst))block_erase_code;

ух....

Спасибо. Работает. Красивое решение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

static void (*const block_erase)(uint8_t *dst) = (void (*)(uint8_t *dst))block_erase_code;

ух....

Похоже, я там лишний шаг сделал. Можно не делать обёртку для функции в ОЗУ, а всегда вызывать её по указателю:

в заголовке:
extern void (*const block_erase)(uint8_t *dst);
в сишнике:
void (*const block_erase)(uint8_t *dst) = (void (*)(uint8_t *dst))block_erase_code;
вызов:
block_erase(ADDR);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А в STM есть русскоязычная поддержка, которая отвечает, если не сильно заморачивать им голову.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 23.01.2015 в 09:59, scifi сказал:

Вот так будет кузявее:

А какая выгода от такого подхода? Полагаю,

1. Независимость от синтаксических особенностей среды разработки для расположения функций в ОЗУ.

2. Функции будут жить не постоянно в отдельной секции (тем самым отнимая драгоценную RAM), а локально - на стеке, например. По сути, это массив обычный.

3. ...?

 

Минус, я так понимаю, только в том, что, чтобы получить этот самый массив, нужно отдельно скомпилировать эту функцию, руками перетащить ее бинарный вид в массив. Верно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...