|
Работа с EEPROM STM8 в IAR, Дописываем библиотеки для работы модификатора __eeprom |
|
|
|
Jul 21 2017, 20:54
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Привет, любители STM! В последних версиях IAR уже почти нормально с модификатором __eeprom работает. Надо лишь реализовать три функции, которые в библиотеке не реализованы и на которые линкер ругается. CODE int __eeprom_wait_for_last_operation(void) { if(FLASH_IAPSR_bit.WR_PG_DIS) return 0; while(!FLASH_IAPSR_bit.HVOFF); return 1; }
void __eeprom_program_byte(uint8_t __near * dst, uint8_t v) { *dst = v; }
void __eeprom_program_long(uint8_t __near * dst, uint32_t v) { FLASH_CR2_bit.WPRG = 1; *(dst++) = *((uint8_t*)(&v)); *(dst++) = *((uint8_t*)(&v) + 1); *(dst++) = *((uint8_t*)(&v) + 2); *dst = *((uint8_t*)(&v) + 3); } Ну и не забывать разблокировать запись. CODE void EEPROM_Unlock(void) { FLASH_DUKR = FLASH_RASS_KEY2; FLASH_DUKR = FLASH_RASS_KEY1; }
void EEPROM_Lock(void) { FLASH_IAPSR_bit.DUL=0; }
А дальше как обычно определяем неинициализированные и инициализированные переменные с модификатором __eeprom и компилятор сам всё сделает. CODE __no_init __eeprom uint8_t x; #pragma data_alignment=4 __no_init __eeprom uint32_t y; __no_init __eeprom uint8_t z; __eeprom uint8_t test[10]={ 1,2,3,4,5,6,7,8,9,10 };
int main() { EEPROM_Unlock(); x=test[5]; z=x+1; y=0x12345678; EEPROM_Lock(); for(;;); } И даже при отладке IAR сам прошивает инициализированные __eeprom переменные вместе с кодом. Удобно. Следует обратить внимание на следующие вещи: - почему-то компилятор смело при оптимизации выкидывает переменные с модификатором __eeprom. Мне кажется они должны быть по умолчанию volatile как и SFR, но нет. Ну нет, так нет. В приложенном проекте пришлось обтыкать их volatile. - STM8 32-битные переменные шьёт за один присест, но для этого они должны быть выровнены по 4. Приходится компилятору напоминать о выравнивании. - что-то мне с ходу не удалось получить два раздельных HEX с кодом и eeprom, но у меня опыт с STM8 аж один день  Только сегодня STM8L-Discovery получил. Может кто научит? Прикладываю проект для дискавери (STM8L152C6), может кому пригодится.
STM8_IAR_EEPROM.rar ( 27.42 килобайт )
Кол-во скачиваний: 68
|
|
|
|
|
 |
Ответов
|
Nov 16 2017, 18:11
|
Группа: Участник
Сообщений: 9
Регистрация: 14-11-17
Пользователь №: 100 189

|
Господа, огромное спасибо за помощь. Почему сам не пробовал кастинг - думал что вроде как должно само преобразоваться, а потом доступа к компу не было и писал с телефона (поэтому прошу прощения за кучу очепяток). По сути, был вопрос про где чёрным по белому написано. Вот цитата из хелпа к IAR for stm8: Цитата Casting Casts between pointers have these characteristics: * Casting a value of an integer type to a pointer of a smaller type is performed by truncation
* Casting a value of an integer type to a pointer of a larger type is performed by zero extension
* Casting a pointer type to a smaller integer type is performed by truncation
* Casting a pointer type to a larger integer type is performed by zero extension
* Casting a data pointer to a function pointer and vice versa is illegal
* Casting a function pointer to an integer type gives an undefined result
* Casting from a smaller pointer to a larger pointer is performed by zero extension
* Casting from a larger pointer to a smaller pointer is performed by truncation.
* Casting _ _eeprom to another data pointer and vice versa is illegal Почему сам не писал сравнение и ковыряние в ЕЕПРОМ: да всё просто - раньше я так и делал, так у меня было сделано в предыдущих проектах, а теперь хотел воспользоватся стандартными инструментами С и IAR, но пока не получилось. Вообще, мне кажется на STM проще всего писать на АСМ, т.к. сравниваю код, что генерит компилятор и код, что напишу я в этом случае на ассемблере - раза в 1,5 более эффективно получается (иногда 10%, иногда в 2 раза и больше). Просто хотелось освоить именно чистый С... В) С# - писал, ASM - писал, С - не писал. В) Сейчас попробую с приведением типа, будет ли работать. Всё заработало в таком виде: Код if (memcmp((void*)ee_key_list[0], mf_key_list[i], sizeof(mf_key_list[0]) == 0)) Тогда не понял, а что в доках написано: * Casting _ _eeprom to another data pointer and vice versa is illegal И ещё раз не понял: если на входе процедуры указатель на безтиповый массив (фактически - на первый байт массива), плюс длина этого массива, используется побайтовое сравнение (а не поэлементное, т.к. в любом случае кастится к void, как я понял?? - прав ли я?), тогда почему бы автоматически любой массив не кастить к войду? Чего компилятор не понимает? Какое может быть другое поведение, кроме сравнения побайтно двух областей памяти начиная с двух указателей?
|
|
|
|
|
Nov 16 2017, 19:58
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(pittyalex @ Nov 16 2017, 21:11)  Вообще, мне кажется на STM проще всего писать на АСМ, т.к. сравниваю код, что генерит компилятор и код, что напишу я в этом случае на ассемблере - раза в 1,5 более эффективно получается (иногда 10%, иногда в 2 раза и больше). Глупости. Проще на Си, а не на ассемблере. На то он и Си. А то, что все существующие компиляторы для стм8 - отстой, давно известно. Тем не менее, ставить рекорды по размеру кода или времени выполнения нужно далеко не каждый день, поэтому польза от этих компиляторов безусловно есть. Цитата(pittyalex @ Nov 16 2017, 21:11)  И ещё раз не понял: если на входе процедуры указатель на безтиповый массив (фактически - на первый байт массива), плюс длина этого массива, используется побайтовое сравнение (а не поэлементное, т.к. в любом случае кастится к void, как я понял?? - прав ли я?), тогда почему бы автоматически любой массив не кастить к войду? Чего компилятор не понимает? Какое может быть другое поведение, кроме сравнения побайтно двух областей памяти начиная с двух указателей? Кстати, указатель на войд имеет такое полезное свойство: указатель на любой другой тип данных приводится к нему и обратно автоматически и без предупреждений. Яр придумал __eeprom для удобства пользователя, наверное, но по недомыслию написал, что указатель приводить нельзя. Просто кто-то у них там не подумал как следует.
|
|
|
|
|
Nov 16 2017, 20:17
|
Группа: Участник
Сообщений: 9
Регистрация: 14-11-17
Пользователь №: 100 189

|
Цитата(scifi @ Nov 16 2017, 19:58)  Глупости. Проще на Си, а не на ассемблере. На то он и Си. А то, что все существующие компиляторы для стм8 - отстой, давно известно. Тем не менее, ставить рекорды по размеру кода или времени выполнения нужно далеко не каждый день, поэтому польза от этих компиляторов безусловно есть.
Кстати, указатель на войд имеет такое полезное свойство: указатель на любой другой тип данных приводится к нему и обратно автоматически и без предупреждений. Яр придумал __eeprom для удобства пользователя, наверное, но по недомыслию написал, что указатель приводить нельзя. Просто кто-то у них там не подумал как следует. Но ведь тем не менее работает. В)) И ещё, если оно так автоматически приводится, почему у меня без явного каста автоматически не привелось? Или может быть речь в мануале шла именно об автоматическом кастинге? А в ручную можно? Хз. Но по сути эта догадка совпадает с реальным положением дел: пока не было явного кастинга - приведения не было, с явным кастингом - всё заработало. Кстати, вопрос: а есть ли какая-то подсказка компилятору, что у меня массивы всегда размером меньше 256 байт, а то он не мудруствуя лукаво, чтобы посчитать индекс в двумерном массиве (размер которого априори не может превыстить 40 байт), ажно вызывает умножение 16х16, что явно избыточно в моём случае (надо посчитать 2 индекса, на это уходит куча времени и кода). Правда я ещё не включал оптимизацию, может оптимизация это всё уберёт. В любом случае, товарищи, большое спасибо за подсказку. Простейшая вещь, но когда мало знаком и не хватает знаний матчасти (программирование - лишь хобби), иногда на такие детские грабли наступаешь (детские, потому что короткие, и бьют не в лоб, а в ... на знаете сами что примерно на высоте 80 см находится у мужчины), что диву потом даёшься, как всё просто и элементарно.
|
|
|
|
|
Nov 16 2017, 20:40
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(pittyalex @ Nov 16 2017, 23:17)  Кстати, вопрос: а есть ли какая-то подсказка компилятору, что у меня массивы всегда размером меньше 256 байт, а то он не мудруствуя лукаво, чтобы посчитать индекс в двумерном массиве (размер которого априори не может превыстить 40 байт), ажно вызывает умножение 16х16, что явно избыточно в моём случае (надо посчитать 2 индекса, на это уходит куча времени и кода). Правда я ещё не включал оптимизацию, может оптимизация это всё уберёт. Лучше бы код выложили. "Правильный" выбор типов выражений при вычислении индекса может уговорить компилятор считать более оптимально, а может и не уговорить. Умный компилятор, конечно, сам догадается. Но яр для стм8 точно не умный, как я уже упомянул выше. Хотя говорят, что яр для арма, к примеру, творит чудеса. Сам не так давно пытался заставить его использовать инструкцию MUL для умножения 8x8=16 без знака. Это почти невозможно. Не придумал ничего лучше, чем сделать функцию mul( a, b ) с ассемблерной вставкой. И да, это было необходимо, поскольку в моём случае код просто не успевал бы делать то, что нужно.
|
|
|
|
|
Nov 18 2017, 09:27
|
Группа: Участник
Сообщений: 9
Регистрация: 14-11-17
Пользователь №: 100 189

|
Цитата(scifi @ Nov 16 2017, 20:40)  Лучше бы код выложили. "Правильный" выбор типов выражений при вычислении индекса может уговорить компилятор считать более оптимально, а может и не уговорить. Умный компилятор, конечно, сам догадается. Но яр для стм8 точно не умный, как я уже упомянул выше. Хотя говорят, что яр для арма, к примеру, творит чудеса. Сам не так давно пытался заставить его использовать инструкцию MUL для умножения 8x8=16 без знака. Это почти невозможно. Не придумал ничего лучше, чем сделать функцию mul( a, b ) с ассемблерной вставкой. И да, это было необходимо, поскольку в моём случае код просто не успевал бы делать то, что нужно. Вот кусок кода: Код if (memcmp((void*)ee_key_list[i+1], mf_key_list[i], sizeof(mf_key_list[0])) == 0) 008B3E AE000A LDW X, #?b10 008B41 BF00 LDW 0x00, X 008B43 CD8AC1 CALL ?mov_w1_w0 008B46 3F08 CLR ?b8 008B48 AE000A LDW X, #?b10 008B4B BF00 LDW 0x00, X 008B4D BE08 LDW X, ?b8 008B4F CD90B4 CALL ?mul16_x_x_w0 008B52 9093 LDW Y, X 008B54 72A90016 ADDW Y, #mf_key_list 008B58 CD8AAC CALL ?mov_w0_w1 008B5B CD8AC1 CALL ?mov_w1_w0 008B5E 3F08 CLR ?b8 008B60 AE000A LDW X, #?b10 008B63 BF00 LDW 0x00, X 008B65 BE08 LDW X, ?b8 008B67 CD90B4 CALL ?mul16_x_x_w0 008B6A 1C400A ADDW X, #0x400A 008B6D CD8AAC CALL ?mov_w0_w1[/b][/i] 008B70 CD9128 CALL memcmp 008B73 5D TNZW X 008B74 26B1 JRNE 0xB1 Всё что выделено - это всего лишь вычисление индекса в двух массивах, размер которых принципиально меньше 255. Учитывая, что индекс хранится в регичистре ?b9, а адрес ee_key_list[1] = 0x400A, Можно было бы записать: Код LDW X, #?b10 //3 LD A, ?b9 //2 MUL X, A //1 LDW Y, X //2 ADDW Y, #mf_key_list //4 ADDW X,#0x400A //3 CLR ?b8 //2 CALL memcmp //3 TNZW X //1 JRNE 0xB1 //2 И всё, и всего 1 вызов функции вместо 7, да и в целом короче 56 байт против 23 байт. Не считая вызова сторонних функций. Индекс массива объявлен как unsigned char i; Я понимаю, что компилятор не может догадаться, что размер массива меньше байта, поэтому индекс не может (не должен) быть больше размера массива, т.е. байта и нет необходимости выполнять 16 битное умножение, но как ему это подсказать, я не знаю.
Сообщение отредактировал pittyalex - Nov 18 2017, 09:28
|
|
|
|
|
Nov 20 2017, 10:20
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(pittyalex @ Nov 18 2017, 11:27)  Я понимаю, что компилятор не может догадаться, что размер массива меньше байта, поэтому индекс не может (не должен) быть больше размера массива, т.е. байта и нет необходимости выполнять 16 битное умножение, но как ему это подсказать, я не знаю. А какой версией IAR это скомпилено? Предполагаю что старой (v2.xx) и без оптимизации. У меня подобный код (с кучей 16-битных операций) генерит старый v2.20 и с выключенной оптимизацией. Со включенной оптимизацией уже гораздо лучше. А новый IAR (3.с чем-то) генерит гораздо лучше.
|
|
|
|
|
Nov 22 2017, 21:36
|
Группа: Участник
Сообщений: 9
Регистрация: 14-11-17
Пользователь №: 100 189

|
Цитата(jcxz @ Nov 20 2017, 10:20)  А какой версией IAR это скомпилено? Предполагаю что старой (v2.xx) и без оптимизации. У меня подобный код (с кучей 16-битных операций) генерит старый v2.20 и с выключенной оптимизацией. Со включенной оптимизацией уже гораздо лучше. А новый IAR (3.с чем-то) генерит гораздо лучше. С выключенной оптимизацией и самая последняя версия.
|
|
|
|
|
Nov 23 2017, 19:28
|
Группа: Участник
Сообщений: 9
Регистрация: 14-11-17
Пользователь №: 100 189

|
Цитата(jcxz @ Nov 23 2017, 08:48)  Хм... Включать не пробовали?  Нет, после включения оптимизации иногда код понять совершенно не возможно, да и не всегда потом, говорят, работает. Пока места хватает и производительности, не вижу смысла включать. В) ХОтя если будет время, надо будет на том же самом месте эксперимент поставить. Спасибо за "наводку".
|
|
|
|
Сообщений в этой теме
VladislavS Работа с EEPROM STM8 в IAR Jul 21 2017, 20:54 jcxz Цитата(VladislavS @ Jul 21 2017, 23:54) С... Jul 31 2017, 09:22 VladislavS Цитата(jcxz @ Jul 31 2017, 12:22) Выкидыв... Jul 31 2017, 11:01  jcxz Цитата(VladislavS @ Jul 31 2017, 14:01) К... Jul 31 2017, 11:25   VladislavS Цитата(jcxz @ Jul 31 2017, 14:25) Вот это... Jul 31 2017, 12:31    jcxz Цитата(VladislavS @ Jul 31 2017, 15:31) К... Jul 31 2017, 15:10     VladislavS Цитата(jcxz @ Jul 31 2017, 18:10) А если ... Jul 31 2017, 16:34   VladislavS Цитата(jcxz @ Jul 31 2017, 14:25) Тут как... Jul 31 2017, 14:26 juvf 2VladislavS
Цитата(jcxz @ Jul 31 2017, 14... Aug 1 2017, 11:38  jcxz Цитата(juvf @ Aug 1 2017, 14:38) вопрос о... Aug 1 2017, 13:08  VladislavS Цитата(juvf @ Aug 1 2017, 14:38) вопрос о... Aug 1 2017, 14:09   jcxz Цитата(VladislavS @ Aug 1 2017, 17:09) См... Aug 1 2017, 15:23   juvf Цитата(VladislavS @ Aug 1 2017, 19:09) Би... Aug 1 2017, 17:29 DS Прекратите хамить собеседнику. При повторении буде... Aug 1 2017, 16:02 VladislavS Инициализированные переменные с модификатором __ee... Aug 1 2017, 16:11 Эдди Подтверждаю, никаких const писать не надо. Вот так... Aug 1 2017, 16:19 VladislavS Цитата(Эдди @ Aug 1 2017, 19:19) Подтверж... Aug 1 2017, 16:34 Эдди Цитата(VladislavS @ Aug 1 2017, 19:34) а ... Aug 1 2017, 19:00 juvf Цитата(Эдди @ Aug 2 2017, 00:00) Зачем вы... Aug 1 2017, 19:48  VladislavS Цитата(Эдди @ Aug 1 2017, 22:00) А смысл?... Aug 1 2017, 20:38  jcxz Цитата(juvf @ Aug 1 2017, 22:48) Мне не н... Aug 2 2017, 09:53 Эдди Да, под стартапом я имел в виду ассемблерный файл,... Aug 2 2017, 05:30 juvf ЦитатаНу и просто уродливо выглядят все эти инициа... Aug 2 2017, 07:15 Эдди Цитата(juvf @ Aug 2 2017, 10:15) вот напр... Aug 2 2017, 08:19 Obam Кто-нибудь, покажите устройство, реально отслуживш... Aug 2 2017, 07:50 juvf Цитата(Obam @ Aug 2 2017, 12:50) Кто-нибу... Aug 2 2017, 09:10  Obam Цитата(juvf @ Aug 2 2017, 12:28) радиоста... Aug 2 2017, 09:17   juvf Цитата(Obam @ Aug 2 2017, 14:17) В '1... Aug 2 2017, 10:03    Obam Цитата(juvf @ Aug 2 2017, 14:03) При чем ... Aug 2 2017, 10:47  Эдди Цитата(juvf @ Aug 2 2017, 12:10) вам всё ... Aug 2 2017, 09:20   juvf Цитата(Эдди @ Aug 2 2017, 14:20) Кому это... Aug 2 2017, 11:12    jcxz Цитата(juvf @ Aug 2 2017, 14:12) Потому ч... Aug 2 2017, 13:08    Эдди Цитата(juvf @ Aug 2 2017, 14:12) При этом... Aug 2 2017, 16:08     juvf Цитата(Эдди @ Aug 2 2017, 21:08) Код UART... Aug 2 2017, 17:08      Эдди Цитата(juvf @ Aug 2 2017, 20:08) И в трет... Aug 2 2017, 22:40 Эдди Вот можно подумать, обычные USB-флешки гарантируют... Aug 2 2017, 09:11 Obam Там нет FRAM, счётчик обычный, рабоче-крестьянский... Aug 2 2017, 09:58 jcxz Цитата(Obam @ Aug 2 2017, 12:58) Там нет ... Aug 2 2017, 10:01 VladislavS А я бы как-то так написал:
Код#define F_CPU 160000... Aug 2 2017, 18:04 juvf Цитата(VladislavS @ Aug 2 2017, 23:04) А ... Aug 2 2017, 18:53  jcxz Цитата(juvf @ Aug 2 2017, 21:53) кошерный... Aug 2 2017, 21:04 VladislavS Для того чтобы изменить скорость USART надо записа... Aug 3 2017, 09:56 juvf Цитата(VladislavS @ Jul 22 2017, 01:54) А... Aug 3 2017, 15:35 VladislavS Цитата(juvf @ Aug 3 2017, 18:35) а как ui... Aug 3 2017, 16:48 pittyalex Господа, товарищи, здравствуйте.
Помогите разобрат... Nov 14 2017, 21:22 juvf Цитата(pittyalex @ Nov 15 2017, 02:22) По... Nov 15 2017, 03:48  pittyalex Цитата(juvf @ Nov 15 2017, 04:48) так ком... Nov 16 2017, 12:30   scifi Цитата(pittyalex @ Nov 16 2017, 15:30) Ес... Nov 16 2017, 12:46   juvf Цитата(pittyalex @ Nov 16 2017, 17:30) В ... Nov 16 2017, 13:30 VladislavS На чтение EEPROM в STM8 ничем не отличается от обы... Nov 16 2017, 17:14     scifi Цитата(pittyalex @ Nov 18 2017, 12:27) но... Nov 19 2017, 13:27         jcxz Цитата(pittyalex @ Nov 23 2017, 21:28) Не... Nov 23 2017, 23:13          juvf Цитата(scifi @ Nov 24 2017, 13:03) А заче... Nov 24 2017, 08:26          pittyalex Цитата(scifi @ Nov 24 2017, 08:03) А заче... Nov 24 2017, 20:45           scifi Цитата(pittyalex @ Nov 24 2017, 23:45) А ... Nov 24 2017, 21:03 juvf Цитата(pittyalex @ Nov 16 2017, 23:11) То... Nov 17 2017, 03:00 VladislavS Все эти кастинги работают пока вы указатель для чт... Nov 17 2017, 04:19 juvf был код
Код__eeprom __no_init uint16_t countStart... Nov 18 2017, 13:55 VladislavS Цитата(juvf @ Nov 18 2017, 16:55) получил... Nov 18 2017, 17:10  juvf Цитата(VladislavS @ Nov 18 2017, 22:10) В... Nov 19 2017, 07:47   pittyalex Цитата(juvf @ Nov 19 2017, 07:47) В еепро... Nov 19 2017, 17:56    razrab83 У меня @0x4030 - такой "стандартный" спо... Nov 20 2017, 04:37    scifi Цитата(pittyalex @ Nov 19 2017, 20:56) По... Nov 20 2017, 06:38     juvf Цитатаstruct eeprom_layout volatile* const eeprom ... Nov 20 2017, 11:20      scifi Цитата(juvf @ Nov 20 2017, 14:20) -это да... Nov 20 2017, 12:02       VladislavS Цитата(scifi @ Nov 20 2017, 15:02) Зачем ... Nov 21 2017, 04:16       juvf Цитата(scifi @ Nov 20 2017, 17:02) Прежде... Nov 21 2017, 09:16        scifi Цитата(juvf @ Nov 21 2017, 12:16) ах да, ... Nov 21 2017, 11:19         juvf Цитата(scifi @ Nov 21 2017, 16:19) Вы мно... Nov 21 2017, 11:21 AHTOXA Цитата(juvf @ Nov 18 2017, 18:55) получил... Nov 18 2017, 20:20
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|