ARM. Учебный курс. IAR EWARM. Создание проекта часть 2. CMSIS и Standard Peripherals Library

Каждый выбирает для себя
женщину, религию, дорогу.

Итак, создавать проекты и настраивать их параметры, в минимально необходимом объеме, мы научились, и руки так и чешутся попробовать свои силы в программировании микроконтроллера. Не буду оригинальничать, и предложу вам попробовать свои силы на классическом примере – поморгать светодиодом, да и название проекта из прошлой статьи недвусмысленно на это указывало :-)

Сей, кажущийся тривиально простым пример (который на самом деле таким и является), на самом деле все-таки несет в себе некий глубинный смысл, т.к. на нем мы научимся подключать в свой проект CMSIS (что это такое, уже рассказал уважаемый Di Halt в своей статье про создание проекта в Keil ) и узнаем о существовании Standard Peripherals Library (стандартной библиотекой работы с периферией), вещью весьма полезной и часто упрощающей жизнь программиста.

Ну что же, приступим. Для начала, хочу сделать небольшое отступление и навести порядок в своем проекте. Дело в том, что я стараюсь всегда делать так, чтобы в проекте был виден некий логический порядок, т.е. исходники и подключаемые файлы (в простонародье инклуды) лежали в папочках с говорящими названиями, а не в корне проекта и чтобы они еще и были структурированы по функциональной нагрузке.
Не сочтите меня педантом, но соблюдение этих простых правил может сильно облегчить вам жизнь в серьезных проектах, поэтому, перефразируя персонажа одного известного мультфильма, лучше 3 минуты потерять на начальном этапе зато потом… Те, кто со мной не согласен могут смело пропускать следующие несколько абзацев (и пить йад! прим. DI HALT).

EWARM в дереве с проектом позволяет создавать логические группы. Что мне особенно в нем понравилось после Keil uVision v3 (может в 4 версии это улучшили) так это то, что группы могут быть вложенными. В uVision v3 вложенные группы у меня создать не получилось.
Первым делом, идем в папку с проектом, создаем там папочку src (вы можете ввести любое, привычное вам, обозначение для папки с исходниками) и перемещаем в нее наш main.c из корня проекта. Затем в EWARM’е тыкаем мышкой на файле main.c и жмем Del на клавиатуре, либо правый клик и в меню Remove. Подтверждаем удаление файла из проекта.
Теперь в дереве проекта, тыкаем правой кнопкой мышки и в меню выбираем

Add->Add Group.

В появившемся окошке нас попросят ввести название группы, вводим src, или как вы там это называете, и нажимаем Ок. В дереве появится «папочка» src.
Тыкаем на ней правой кнопкой мыши и в мею выбираем

Add->Add Files.

В диалоговом окне выбора файлов идем в папочку src и выбираем файл main.c. После этого выбранный файл появится в дереве проекта в «папочке» src.

Теперь настало время подключить CMSIS. Для этого, в принципе, можно воспользоваться файлами любезно предоставленными Di Halt’ом в своей статье. Но я предлагаю вам пройтись на официальный сайт ST Microelectronics и скачать архив содержащий CMSIS и не только.

Дело в том, что данный архив во первых содержит ASM startup файлы, в том числе и для EWARM, а во вторых, он содержите еще и упомянутую в начале статьи Standard Peripherals Library, о ней речь пойдет ниже.

Качаем и распаковываем архив. В нем находим в папочке

STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\CoreSupport файл core_cm3.c

В своем проекте, в папке с исходниками, создаем папку CMSIS и копируем сюда файл core_cm3.c. Копируем туда же файл

STM32F10x_StdPeriph_Lib_V3.4.0\Project\STM32F10x_StdPeriph_Template\system_stm32f10x.c

Аналогично описанному выше, создаем группу CMSIS в группе src в дереве проекта и добавляем эти файлы в проект в «папочку» src\CMSIS.

В папке с проектом, создаем папку inc и копируем в нее файлы stm32f10x.h и system_stm32f10x.h из папки

STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x

и файл core_cm3.h из папки

 STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\CoreSupport.

Аналогично добавляем группу и эти файлы в дерево проекта.

И, наконец, создаем в папке с проектом папочку startup, копируем в нее файл startup_stm32f10x_xxx.s из папки

STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\iar

и добавляем группу и этот файл в проект.
Последний файл является программой на языке ассемблера которая содержит в себе самую низкоуровневую инициализацию контроллера. (Keil, кстати, делает это автоматически, беря эти файлы из своих закромов. прим. DI HALT)

В нем содержится таблица векторов прерываний, инициализация стека, вызов функции SystemInit() из библиотеки CMSIS и последующий вызов функции main() нашей программы.
В указанной папке будет находиться несколько файлов вида startup_stm32f10x_xxx.s Это обусловлено различием микроконтроллеров разных серий по функционалу. Различия в этих файлах минимальны и касаются только таблицы векторов прерываний, т.к. если в вашем микроконтроллере, например, отсутствует ЦАП, то соответственно не будет и прерываний им генерируемых…

ST Microelectronics использует следующую классификацию и обозначения (в моем вольном переводе):

  • STM32F10X_LD: STM32 Low density devices (устройства низкой плотности интеграции). Это микроконтроллеры серий STM32F101xx, STM32F102xx и STM32F103xx имеющие на борту от 16 до 32Кбайта флеш памяти.
  • STM32F10X_LD_VL: STM32 Low density Value Line devices (устройства низкой плотности интеграции массового уровня). Это микроконтроллеры серии STM32F100xx имеющие на борту от 16 до 32Кбайта флеш памяти.
  • STM32F10X_MD: STM32 Medium density devices (устройства средней плотности интеграции). Это микроконтроллеры серий STM32F101xx, STM32F102xx и STM32F103xx имеющие на борту от 64 до 128Кбайта флеш памяти.
  • STM32F10X_MD_VL: STM32 Medium density Value Line devices (устройства средней плотности интеграции массового уровня). Это микроконтроллеры серии STM32F100xx имеющие на борту от 64 до 128Кбайта флеш памяти.
  • STM32F10X_HD: STM32 High density devices (устройства высокой плотности интеграции). Это микроконтроллеры серий STM32F101xx и STM32F103xx имеющие на борту от 256 до 512Кбайта флеш памяти.
  • STM32F10X_HD: STM32 High density value line devices (устройства высокой плотности интеграции массового уровня). Это микроконтроллеры серии STM32F100xx имеющие на борту от 256 до 512Кбайта флеш памяти.
  • STM32F10X_XL: STM32 XL-density devices (устройства очень высокой плотности интеграции). Это микроконтроллеры серий STM32F101xx и STM32F103xx имеющие на борту от 512 до 1024Кбайта флеш памяти.
  • STM32F10X_CL: STM32 Connectivity line devices (устройства ориентированные на коммуникации и сфокусированные на реализацию высокопроизводительных вариантов интерфейсов, удовлетворяющих промышленным стандартам). Это микроконтроллеры серий STM32F105xx и STM32F107xx.

Итак, пользуясь данной классификацией, выбираете подходящий вам вариант файла. Для меня это будет startup_stm32f10x_hd.s
В итоге, должна получиться примерно следующая картина:

Если попытаться откомпилировать проект, то компилятор начнет ругаться на то, что он не может найти файл stm32f10x.h Это потому, что мы поместили его в отдельную папочку inc. Укажем эту папку в настройках проекта во вкладке Preprocessor в категории C/C++ Compiler. Здесь есть 2 варианта:

  • Указать абсолютный путь до своей папки inc.
  • Указать относительный путь.

Я пользуюсь относительными путями но в таком случае нужно добавить 2 пути.

Пробуем откомпилировать, и появляется другая ошибка:

«Fatal Error[Pe035]: #error directive: "Please select first the target STM32F10x device used in your application бла бла бла».

Эта ошибка генерируется в файле stm32f10x.h и говорит она нам о том, что неплохо бы указать тип микроконтроллера. Это уже просит библиотека CMSIS… Если пройти по ошибке в файл stm32f10x.h и отмотать чуть чуть выше, то мы увидим блок, где можно задефайнить нужный нам тип микроконтроллера, но тут же есть и намек, что, может быть, не стоит это делать жестко. В общем, как обычно у нас 2 пути:

  • Задефайнить жестко тип микроконтроллера здесь, подойдет, если файл stm32f10x.h, в каждом проекте будет свой или работать планируете только с одним типом контроллеров.
  • Определить дефайн с типом микроконтроллера в опциях компилятора (там же, где указывали путь к подключаемым файлам, только чуть ниже, едит бокс под названием Defined symbols).

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

1
/* #define STM32F10X_HD */     /*!< STM32F10X_HD: STM32 High density devices */

(предварительно сняв в проводнике с файла stm32f10x.h атрибут read only).
Компилируем еще раз, и убеждаемся что на этот раз все компилируется без ошибок. Теперь добавляем код инициализации ножки порта к которой подключен светодиод и в цикле с некоторой задержкой устанавливаем на этой ножке уровень напряжений Vcc или 0, что заставляет мигать наш светодиод. У меня используется 5-я нога порта B. В остальном код практически полностью взят из статьи Di Halt’а.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "stm32f10x.h"
 
//------------------------------------------------------------------------------
 
void InitAll( void);
void Delay( unsigned int Val);
 
//------------------------------------------------------------------------------
 
int main( void) {
 
  InitAll();
 
  while( 1) {
    // Set PB.5 bit
    GPIOB->BSRR = GPIO_BSRR_BS5;
    Delay( 600000);
 
    // Reset PB.5 bit
    GPIOB->BSRR = GPIO_BSRR_BR5;
    Delay( 600000);
  }
 
}
 
//------------------------------------------------------------------------------
 
void InitAll( void) {
 
  // Enable PORTB Periph clock  
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
 
 
  // Clear PB.5 control register bits
  GPIOB->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);
 
  // Configure PB.5 as Push Pull output at max 10Mhz
  GPIOB->CRL |= GPIO_CRL_MODE5_0;
 
 
   return;
}
 
//------------------------------------------------------------------------------
 
void Delay( unsigned int Val) {
  for( ; Val != 0; Val--) {
    __NOP();
  }
}
 
//------------------------------------------------------------------------------

Лирическое отступление
В своих статьях и проектах я форматирую тексты программ так, как я привык… Хорошо это или плохо я не знаю, но в комментах несколько раз видел дискуссии на тему оформления кода. Если кому-то мой стиль не нравиться, то прошу молча переформатировать так, как вашей душе угодно, но не стоит убеждать меня что я делаю что-то не так :-)

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

Standard Peripherals Library
На этом, можно было бы закончить данную статью, но хочется еще рассказать о библиотеке Standard Peripherals Library, упомянутой пару раз ранее. Эта библиотека любезно представляется компанией ST Microelectronics для использования со своими микроконтроллерами. Данная библиотека, как следует из ее описания самим производителем, предназначена лишь в качестве руководства к действию, но может облегчить жизнь программисту и сократить время разработки проекта.
Также производитель не несет никакой ответственности если в результате использования этой библиотеки вы чего-то там сломаете себе или кому другому… Но это как обычно :-) Истинные последователи дзен буддизма с негодованием могут закончить чтение данной статьи. Библиотека поставляется в исходных кодах, и на данный момент доступна версия 3.4.0 от 15 октября 2010г.

Итак, что же представляет из себя данная библиотека? По сути это просто набор функций, позволяющих намного легче и проще делать какие-то основные моменты. В основном, упор сделан на функции инициализации периферии, ее включения/выключения, опроса состояния и т.д. В комплекте идет небольшой справочник в формате chm (честно говоря весьма убогий т.к. IMHO генерируется автоматически чем-то типа Doxygen т.е. на основе комментариев к коду). Также присутствует папочка с различными примерами, число которых довольно велико и которые тоже могут быть интересны начинающим осваивать данные микроконтроллеры. Примеры разбиты тематически по папочкам с говорящими названиями и неплохо описаны.

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

1
 #if !defined  USE_STDPERIPH_DRIVER.

Далее идет описание, что такое USE_STDPERIPH_DRIVER и закомментированный дефайн. Раскомментируем его, тем самым давая понять, что мы желаем использовать не просто CMSIS а также использовать функционал данной библиотеки. Также, крайне желательно, еще чуть ниже найти строку

1
#define HSE_VALUE    ((uint32_t)8000000)

и указать свое значение кварца, если оно отлично от 8МГц. Если этого не сделать, то потом можно наступить на грабли в виде «неработающего» USART и т.п.

Теперь в наш проект нужно добавить файл stm32f10x_conf.h, который вызывается теперь из файла stm32f10x.h Взять его можно в папочке

STM32F10x_StdPeriph_Lib_V3.4.0\Project\STM32F10x_StdPeriph_Template

Данный файл содержит в себе инклуды на части библиотеки и макрос assert_param предназначенный для проверки правильности передаваемых в функции библиотеки параметров. По умолчанию он пустой. Кому интересно как им пользоваться в полной мере – спрашивайте в комментах. В данном файле можно убрать или закомментировать все не нужные нам инклуды. Мы будем пользоваться только функциями определенными в заголовочных файлах stm32f10x_rcc.h (функции работы с тактовыми генераторами) и stm32f10x_gpio.h (функции работы с портами ввода/вывода).
Также в папочке с проектом создаем папку типа StdPeriphLib, копируем туда файлы stm32f10x_rcc.c и stm32f10x_gpio.c из

 STM32F10x_StdPeriph_Lib_V3.4.0\Libraries\STM32F10x_StdPeriph_Driver\src

и добавляем все это добро в наш проект. Теперь переписываем код и заменяем прямую работу с регистрами на вызовы функций билиотеки. В результате получаем следующее:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "stm32f10x.h"
 
//------------------------------------------------------------------------------
 
void InitAll( void);
void Delay( unsigned int Val);
 
//------------------------------------------------------------------------------
 
int main( void) {
 
  InitAll();
 
  while( 1) {
    GPIO_SetBits( GPIOB, GPIO_Pin_5);
    Delay( 600000);
 
    GPIO_ResetBits( GPIOB, GPIO_Pin_5);
    Delay( 600000);
  }
 
}
 
//------------------------------------------------------------------------------
 
void InitAll( void) {
  GPIO_InitTypeDef GPIO_InitStructure;
 
  // Enable PORTB Periph clock  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
 
  // Configure PB.5 as Push Pull output at max 10Mhz
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init( GPIOB, &GPIO_InitStructure);
 
  return;
}
 
//------------------------------------------------------------------------------
 
void Delay( unsigned int Val) {
  for( ; Val != 0; Val--) {
    __no_operation();
  }
}
 
//------------------------------------------------------------------------------

Компилируем, прошиваем, убеждаемся, что работает.
Что же мы получили от использования Standard Peripherals Library?

Плюсы:

  • код стал проще (хотя на данном простейшем примере это вопрос спорный), но как минимум не нужно уже знать что и в какие регистры надо прописать.
  • код стал понятнее, т.к. мы использовали функции с вполне говорящими названиями вместо того чтобы делать какие-то битовые операции и помещать результат непонятно куда.
  • написать такой код начинающему (да и не только) программисту гораздо проще и быстрее чем читать даташит, чтобы узнать какие регистры и как нужно проинициализировать. (Не не не не, Дэвид Блейн! Не надо нам такой магии!!! Изучать надо без готовых решений, а то так и будешь взывать )

Особенно эти пункты становятся видны на более сложном коде.
Есть еще? пишите в комменты.

Минусы:

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

Есть еще? пишите в комменты.

В общем, как сказано в эпиграфе, каждый выбирает по себе… Я, например, пользуюсь данными библиотеками там, где это имеет смысл. Но где нужно максимальное быстродействие и минимум кода работаю напрямую с регистрами, иногда переходя на чистый Ассемблер. Бывают моменты, когда это очень выручает!

И еще, чтобы все время не добавлять нужные C файлы из библиотеки в проект, я просто один раз откомпилировал их в библиотеку, и подключаю ее в свои проекты. Если кому интересно как это сделать – спрашивайте.

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

PS:
Мистика какая-то! Пару раз специально пытался найти на сайте ST Microelectronics Flash loader demonstrator и не получалось… Сейчас, когда начал писать статью и полез за исходниками библиотеки, сразу же наткнулся и на нее! Причем версия 2.2, еще свежее чем приложенная к прошлой статье. Я так и не понял, толи я раньше тупил, толи подправили сайт. В общем, кому надо, качайте. :-)

106 thoughts on “ARM. Учебный курс. IAR EWARM. Создание проекта часть 2. CMSIS и Standard Peripherals Library”

    1. Они будут параллельно. Просто я начал чуть раньше чем RtxOnAir и поэтому он, догоняя меня, вбросил вариант для IAR (по хорошему это должна быть одна монстр статья). Потом вначале будут примеры для Keil, ниже для IAR.

          1. Ну понятия о езернет и протоколах оно не зависит от железа. А вообще я реализую пока все на AVR… Соответственно об использовании на них и могу написать.

            На 32 битники все никак не переберусь… мешают текущие проекты на AVR которые никак нельзя сбросить пока или совмещать с изучением ARM (( Но при случае- обязательно )

                1. ENC28J60 интересная микросхема!!! даже проект есть описанный у конкурентов
                  http://www.rlocman.ru/shem/schematics.html?di=55059

                  Можно попробовать собрать, как только те UDP пакеты ей отправлять? Я с дельфями только работаю, буду искать как там сокеты программировать… радует что схема простая )))

                  1. Ну отправлять можно многими способами… В том числе на дельфи можно написать софтину. Я с делфи не работаю. На Perl не сложно работать с сетью, на C++ тоже не плохо особенно если с QT. С тех пор как я познакомился с QT вообще перестал понимать как жил раньше ))

                    1. К ENC28J60 есть готовая демоплата
                      http://www.megachip.ru/item.php?item_id=662662
                      цена неизвестна, но было бы удобно
                      программирование с QT непонятное что-то, тут описанно,
                      http://ru.wikipedia.org/wiki/Qt
                      впринципе интересно, кросплатформенность может пригодится наверное ))

                      Вот еще вопрос, можно ли сделать в Windows виртуальный COM порт и кидая туда байты получать их в контроллере? Помоему самый удобный механизм для общения с устройством был бы. Видел готовые решения такие (Конвертеры RS-232/422/485 в Ethernet)
                      http://www.moxa.ru/group/listAll/14890/
                      можно попробовать самому что-то подобное собрать, наверняка кто-то уже занимался в мире )))
                      Работать с COM портом не сложно, а вот как его создать в системе…

                    2. Лучше я схемотехнику сделаю и платку разведу под это дело.

                      А зачем виртуальный ком порт? МОжет telnet’ом туда ломиться? У визнета был софт который делал виртуальный ком в системе. Но работал с W5100, Хотя можно под него подстроиться.

                    3. Еще нашел для работы по сети, аналог Moxa подешевле немного
                      http://www.tibbo.ru/item/1/4/
                      виртуальным COM порт под любую ОС и передача данных по сети, самое простое решение помоему чтобы начать работать с сетью

                    4. QT это грубо говоря такой фреймворк. Который предоставляет кучу разных полезностей. Например он умеет рисовать пользовательские интерфейсы. В частности такие программы как Google Earth, Opera, Skype сделаны именно на нем. Интерфейсы рисует QT на много лучше чем майкрософтовский MFC. Не считаю нужным мне об этом рассказывать, так как об этом очень хорошо написано в начале любой книги по QT.

                      Но он не только рисовать интерфейсы умеет. Он имеет куру разных модулей. В том числе для работы с сетью. Об этом написано на википедии под заголовком «Компоненты».

                      Еще он объявляет множество разных типов данных. QByteArray например и другие, которые на много удобнее обычных сишных типов. Об этом можно глянуть в документации по QT. http://doc.crossplatform.ru/qt/4.7.x/

                      Ну и плюс это все плаформонезависимое. В том числе есть порты под ARM.

                      —————————

                      >>Вот еще вопрос, можно ли сделать в Windows виртуальный COM порт и кидая туда байты получать их в контроллере?

                      Ну конечно можно все. Надо тока взвесить все за и против, сравнить с другими способами передачи данных (например тот же телнет). Посмотреть какой объем работы получится, какой объем кода получится в результате. Telnet например сам требует некоторой реализации. И он использует TCP. Все это требует ресурсов.

                    5. > Ну и плюс это все плаформонезависимое. В том числе есть порты под ARM.
                      Только вы забываете о том, что АРМ’ы бывают разные… В том числе и двухядерные с частотами за ГГц… Порта QT для МИКРОконтроллеров я что-то не углядел на их сайте, да и даже не сомневался, что его не существует.

                      > Но он не только рисовать интерфейсы умеет. Он имеет куру разных модулей. В том числе для работы с сетью. Об этом написано на википедии под заголовком “Компоненты”.
                      > Еще он объявляет множество разных типов данных. QByteArray например и другие, которые на много удобнее обычных сишных типов.
                      Вы еще посмотрите исходники, какой ценой все это достигается… Если речь идет о микроконтроллерах, то IMHO про QT нужно забыть как про страшный сон…

                    6. Ну тут я спорить не буду конечно ) я его использую только на компе.

                    7. Не, я сначала прикручивал его к Visual Studio, потом убедившить в ее убогости стал пользоваться QT Creator’ом… Правда тоже не фонтан ))

                    8. Думаю имеет смысл попробовать с эклипсом. Если у вас какие-то успехи есть в этом направлении- поделитесь )

    1. Ну не сказать, чтобы прямо гораздо (хотя 4 строчки вместо 2-х, это в 2 раза длинее :-)), но я об этом упоминал в минусах, что код стал больше…

      А вообще, в ней лично для меня, есть спорные моменты. Те-же элементарные функции вроде установки сброса бита порта или, например, флага прерывания, лично я бы определил через дефайны, чтобы не было вызова функции ради одной операции. Хотя тут, наверное, могли бы помочь и inline функции…

  1. rtxonair, а расскажи пожалуйста поподробнее про предварительную компиляцию библиотек, чтобы потом в проект добавлять? Я немного не понял, о чем речь. Я просто копирую все ST-шные исходники к себе в проект, а потом добавляю нужные модули через файл stm32f10x_conf.h

    1. Речь идет о том, чтобы создать библиотеку (обычно это файл с расширением .lib, но у IAR’а используется Unix’овый вариант и расширение .a) содержащую откомпилированные исходники. А потом только в разделе Linker->Library указывается эта библиотека, и на стадии линковки, используемые функции берутся из нее. Т.е. отпадает необходимость все время копировать в каждый проект исходники библиотеки.

      1. Ага, это я понял. А можешь тогда рассказать, как откомпилировать исходники в такую библиотеку? На сколько я понимаю, использование такого метода может немного ускорить время полной сборки проекта.

        1. Откомпилировать очень просто. Нужно создать прект точно так-же как обычно, только в настройках проекта General Options->Output выбрать радиобуттон Library. Это говорит о том, что нужно сгенерировать библиотеку. Затем в проект добавляются все исходники и компилируются. Получается файл с расширением «.a», это и есть библиотека.
          Далее во всех проектах, подключаются только инклуды (я их не копирую в каждый проект, а подключаю из одной, единой для всех проектов папки) и эта библиотека.

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

  2. RtxOnAir — спасибо за статью, многое выглядит знакомо (после трех лет ковыряния в EWAVR :)) Не подскажешь, где можно нарыть аналогично толковую статью по началам разработки под ARM/Linux? Конкретно говоря, собираюсь начать копать под ARM9… совершенно не верится, что каждая перекомпиляция проекта должна вести к перепрошиванию всего образа (как в тех же АВРках), включая сам Линь — как там вообще работа идет? Есть ли какие-то туториалы для получайников? Под сам Линь писал, разве что только на PC.

    1. > Не подскажешь, где можно нарыть аналогично толковую статью по началам разработки под ARM/Linux?
      Если имеется ввиду именно под EWARM, то я не смог нигде ничего найти.
      И вообще, почемуто по EWARM практически нет инфы (в смысле туториалов, примеров и т.д.) в инете…

      > Конкретно говоря, собираюсь начать копать под ARM9…
      У меня есть опыт работы с платформой FriendlyArm на базе ARM9 процессора Samsung S3C2440.
      На какую платформу ты ориентируешься? ARM9 в домашних условиях особо не распаяешь т.к. это уже полноценные CPU а не микроконтроллеры и идут они в BGA корпусах с кол-вом выводов от 250 и выше… ;-) т.е. нужно иметь готовую плату.

      > совершенно не верится, что каждая перекомпиляция проекта должна вести к перепрошиванию всего образа (как в тех же АВРках), включая сам Линь — как там вообще работа идет?
      Конечно нет! Именно под линукс я не пробовал писать т.к. нужды не было, но принцип там такой:
      1. На стадии разработки программы скидываются либо напрямую в память и выполняются, либо скидываются на файловую систему Linux/WinCE и запускаются оттуда уже как обычные исполняемые файлы.
      2. Когда разработка/отладка завершится, то программа либо включается в прошивку вместе с ОС, либо просто копируется на файловую систему уже прошитой ОС.

      Ну и повторяю, ARM9 это уже не микроконтроллеры, у них нет ни флеша ни ОЗУ на борту. Это полноценные CPU. Грузяться они, как правило, с внешней NOR или NAND флеш памяти и для работы им нужно внешнее ОЗУ.

    2. На самом деле это зависит от проекта. Даже на AVR необязательно перешивать все (так, например, при использовании бутлоадера не прошивается секция бутлоадера). Можно, например, выделить на том же AVR первый кб памяти под ядро, второй под одну работающую на нем программу, третий под другую, четвертый под бут. Тогда перекомпилировав вторую программу можно перезалить только ее — т.е. третий килобайт памяти. Правда, при таких объемах памяти подобный подход неоправдан, а вот на чем-то покрупнее — запросто. Скажем, в типичных роутерах с прошивкой на основе линукса имеющийся флеш (2-8МБ обычно) разбит на секцию ядра, секцию файловой системы и т.п. Соответсвенно, перекомпилировав какую-то входящую в состав прошивки программу не требуется перезаливать весь флеш — достаточно перезалить секцию ФС (либо ее часть, если ФС допускает). А на этапе прошивки можно и прямо в ОЗУ заливать.

  3. > Если имеется ввиду именно под EWARM, то я не смог нигде ничего найти.
    И вообще, почемуто по EWARM практически нет инфы (в смысле туториалов, примеров и т.д.) в инете…

    Та же ерунда. Может что-то есть про отладку с Линуксом на других компиляторах? Какая уж там разница, чем оно собрано. Хотелось бы увидеть процесс работы — вроде 1) собрали проект, 2) засунули его туда-то, 3) запустили так-то.

    Вот еще вопрос. Есть ли смысл/возможность отлаживать такие программы под Линуксом на РС? Если мы имеем стандартный набор библиотек, то какая разница, на каком железе это все бегает? За минусом конечно случаев, когда есть какая-то сверх-особенная периферия, но пару-тройку светодиодов можно и DEFINE’ами забить.

    Я ориентируюсь на AT91SAM9G45 (Atmel). Уж очень оно нравится с точки зрения периферии — LCD controller и USB HS Host в одном флаконе. Плата не проблема — есть родные отладочные платы, так что дома паять БГАшки не придется.

    Про память и пр. понял, не проблема — на отладочной плате есть, дальше пусть аппаратчики разбираются, когда дело дойдет до разработки реальной платы.

    Еще вопрос. Если мы прошиваем конечный девайс прошивкой, содержащей саму ОС, то кто со стороны чипа занимается прописыванием прошивки во флэш — есть такие же бутлоадеры как на АВР?

    1. >Может что-то есть про отладку с Линуксом на других компиляторах? Какая уж там разница, чем оно собрано. Хотелось бы увидеть процесс работы — вроде 1) собрали проект, 2) засунули его туда-то, 3) запустили так-то.
      Не совсем понял, что тебе всетаки требуется.
      1. Просто написать программу и запустить. Это делается элементарно.
      2. Запустить в отладчике и отлаживать. Это уже сложнее, в том плане, что нужно с gdb уже уметь работать. Но тоже проблем особых нет.

      Сама программа пишется/компилируется обычно на PC с использованием нужного тулчайна. Все зависит от того, какая ОС будет в целевом устройстве. Даже если это линукс, то какой именно (в смысле, насколько кастрирован).
      Опять же, что за программа, консольная она или с GUI, если GUI то смотреть что за GUI используется в ОС прошитом на целевом девайсе и т.д. и т.п.

      Если бы речь шла об WinCE, то там вообще все просто. Прямо в визуал студии нажимешь кнопочку, программа сама кидается в девайс и дальше отлаживаешь программу запущенную на девайсе. Т.е. ты в отладчике на PC видишь все регистры, память и т.д. своего девайса. Можешь ставить брекпоинты, ходить по шагам и т.д. Очень удобно. Есть ли подобное для линукса — я не знаю.

      > Вот еще вопрос. Есть ли смысл/возможность отлаживать такие программы под Линуксом на РС? Если мы имеем стандартный набор библиотек, то какая разница, на каком железе это все бегает? За минусом конечно случаев, когда есть какая-то сверх-особенная периферия, но пару-тройку светодиодов можно и DEFINE’ами забить.
      Конечно! Программе абсолютно все равно где выполняться! Но только работу с переферией (ЦАП, АЦП, прерывания, таймеры, порты ввода/вывода, контроллер ЖК и.т.д.), если это нужно, ты как эмулировать собираешься? Если же программа всего этого не использует — то без проблем!

      >Я ориентируюсь на AT91SAM9G45 (Atmel). Уж очень оно нравится с точки зрения периферии — LCD controller и USB HS Host в одном флаконе.
      Ну положим, у S3C2440 тоже все это есть, правда этот атмел посовременнее, поддержка DDR2 памяти и т.д. Есть еще платы FriendlyArm на базе самсунговского процессора S3C6410, он наверное еще мощнее будет. Но в принципе те-же яйца, только сбоку. Смотря что в проекте нужно.

      > Еще вопрос. Если мы прошиваем конечный девайс прошивкой, содержащей саму ОС, то кто со стороны чипа занимается прописыванием прошивки во флэш — есть такие же бутлоадеры как на АВР?
      Не знаю, как в этом атмеле, надо читать даташит, но очень сомневаюсь что там есть бутлоадер. Обычно, процессор в зависимости от состояния определнных ножек в момент включения/сброса начинает читать и выполнять программу с внешней РАМ. Обычно это NOR или NAND флеш. Сейчас глянул, этот атмел поддерживает загрузку с: NAND Flash, SDCard, DataFlash® or serial DataFlash. Вот в одной из этих флешей и должна лежать программа. Либо это твоя программа, которая сама будет инициализировать процессор и работать дальше, либо это один из бутлоадеров, который выполняет роль БИОСа, т.е. инициализирует процессор, переферию, а дальше либо ждет команд на USART/USB/ETHERNET портах либо грузит ОС. А уж как ты положишь свою программу или бутлоадер во флеш — это уже твоя проблема. Хотя на 99.9% уверен, что можно прошить все на самом девайсе через JTAG. Во FriendlyArm так и делается, если надо.

      1. Смотрел на S3C2440 — там хост только 1.1, а мне надо 2.0. S3C6410 — вот это уже ляля, разве что OpenGL мне там не нужен :)

        > Но только работу с переферией (ЦАП, АЦП, прерывания, таймеры, порты ввода/вывода, контроллер ЖК и.т.д.), если это нужно, ты как эмулировать собираешься?

        Имелась в виду отладка бизнес-логики.. насчет контроллера ЖК — это же должно быть как видеодрайвер на РС, так? Т.е. программа на Linux/ARM использует какие-то функции, экспортируемые библиотеками ОС, а те уже обеспечивают аппаратную часть вывода, правильно? Таймеры — то же самое, функции ОС. Порты — то же самое, тот же USB изолируется ОСью, нет?

        1. > Т.е. программа на Linux/ARM использует какие-то функции, экспортируемые библиотеками ОС, а те уже обеспечивают аппаратную часть вывода, правильно? Таймеры — то же самое, функции ОС. Порты — то же самое, тот же USB изолируется ОСью, нет?
          Да, все так. Звук, USB, экран и т.д., унифицировано на уровне драйверов и/или библиотек, если они портированы на целевой девайс. Но это если хватает их (драйверов/библиотек) функционала. Я имел ввиду про сложности эмуляции чего-то очень сильно от железа зависящего. Если такое не планируется, то без проблем, можно писать и отлаживать па PC а потом скомпилировать релиз для девайса.

    2. Обычно, 1 раз прописывается бутлоадер через JTAG в набортную флеш память, а дальше уже этот бутлоадер, помогает прошить нужную ОС либо что еще требуется. Если покупается готовая демо-плата, то там на 99.9% уже будет нужный бутлоадер.

  4. Добрый вечер!
    Спасибо за статью, очень содержательная. Мучаю STM32VL Discovery, контроллер STM32RB. Пытаюсь помигать светодиодом.
    Столкнулся с вот такой проблемой:

    Tue Dec 07 03:58:49 2010: 920 bytes downloaded and verified (9.56 Kbytes/sec)
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x08000000, target byte: 0x60, byte in file: 0x00
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x08000004, target byte: 0x71, byte in file: 0x95
    Tue Dec 07 03:58:49 2010: Warning:
    ………
    //еще куча аналогичных сообщений;
    ………
    ………
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x08000148, target byte: 0x96, byte in file: 0xFE
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x08000149, target byte: 0xF8, byte in file: 0x01
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x0800014A, target byte: 0x1F, byte in file: 0x41
    Tue Dec 07 03:58:49 2010: Warning:
    Verify error at address 0x0800014B, target byte: 0xBD, byte in file: 0x60
    Tue Dec 07 03:58:49 2010: Warning: Too many verify errors, only the first 200 are displayed
    Tue Dec 07 03:58:50 2010: Warning: There were warnings during download, see Log Window
    Tue Dec 07 03:58:50 2010: Loaded debugee: C:\Documents and Settings\Administrator\Рабочий стол\Dev_Progs\Release\Exe\LEDTest.out
    Tue Dec 07 03:58:50 2010: Target reset

    Не подскажете, где может быть проблема?

    1. Думаю проблема в прошивальщике. Судя по ошибкам, ругается на то, что считанные после прошивки из флеша данные не совпадают с теми, что должны были записаться. Т.е. записи не произошло.
      Ты чем прошиваешь?
      Проблема возникает только с этим проектом? Пробовал ли удачно прошивать и запускать другие проекты?
      Стирается ли флеш перед прошивкой? Может галочку какую в программепрошивальщике для этого надо ткнуть, или в ручную флеш сначала стирать. Если флеш не стереть, то записать данные в нее нельзя.

    2. Вчера столкнулся с полность аналогичной ситуацией. Попробовал ST Visual Programmer, установив кристалл ST32F100xB — ругается на неправильный кристалл ПРИ ЗАШИВКЕ. Читает, вроде, нормально. Них$я себе пельмешки, подумал я. Но там же нашелся кристалл ST32F100xBххВ. С ним прошивальшик заработал без единого писка. Посмотрел внимательно на камушек а там и вправду маркировка ST32F100RBT6В. Ну, думаю, приплыли — как же я без любимого отладчика? Версия IAR была 5.50 с чем-то. Сначала ругался на то, что не может загрузить FlashSTM32F100x8.board. Потом тыканьем в кнопочки вокруг Debugger — Download получил результат как у тебя.
      Переставил на 6.10 — все волшебным образом заработало.
      «У_Р_А!!!» — прошептал я, поскольку уже было час ночи и, довольный заработавшим загрузчиком и недовольный буквой «В» в маркировке, пошел спать. :)

      Что означает буковка «В» в конце маркировки — великая тайна ST.

      1. Стал разбираться. Выяснил вот что.
        В ИАР 5.50 файл FlashSTM32F100xB.board (то, что стоИт по умолчанию в проекте к плате Дисковери) ссылается на FlashSTM32F100xB.flash, а тот в свою очередь на FlashSTM32F100xB.out которого — то и нет. Вообще нет. И всЁ и все встают раком.
        В ИАР 6.10 FlashSTM32F100xB.flash ссылается на FlashSTM32F10xxxRAM6K.out который на месте и все шьется.
        Т.о. в ИАР 5.50 (возможно, что и в других 5.хх) надо найти файл FlashSTM32F100xB.flash, в нем найти и заменить в нем «FlashSTM32F100xB.out» на «FlashSTM32F10xxxRAM6K.out»

  5. Проблема возникает не только с этим проектом, пробовал пример для моей платы-то же самое. Другие проекты не пробовал, с АРМ только знакомлюсь) Может и вправду стереть забыл, надо будет проверить. Попробую через UART еще прошить.
    Прошиваю прямо из IAR, отладчик\прошивальщик ST-Link (на демоплате находится).

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

      А так все части по арм собраны в отдельную рубрику «ARM. учебный курс» Где обе части будут по порядку.

  6. Добрый вечер, спасибо за статью! Столкнулся вот с такой проблеммой при попытке откомпилить проект, на этапе линковки без использования библиотек, проц STM32F100RBT6B, в IAR ставлю Device — ST STM32F100xB:

    Error[Li005]: no definition for «__iar_program_start» [program entry]
    Error[Li005]: no definition for «__iar_program_start» [referenced from C:\MCU Project\ST\LEDTest\Debug\Obj\startup_stm32f10x_md_vl.o]

    Подскажите в чем может быть проблема? Почему линковщик не находит директиву __iar_program_start?

    Никак победить не могу что только не делал :( Заранее спасибо.

  7. Неужели никто не сталкивался с такой проблемой? Да наверное мне путь на Keil светит, а так не хотелось… Я когда перешел с Keil на IAR для С8051 столько позитива ощутил :), думал и под АРМ на IAR начать, а тут такая засада, googlе тоже ответа не знает или я неправильно спрашиваю…

    1. На кейле свои тоже не все гладко — там пока нет поддержки в симуляторе STM32F100х.
      Попробуй поставь иар версии 5.5 — там у меня все работало с этим чипом после того, когда я поставил патч.

      1. Примеры для discovery работают без проблем! А свой проект без использования библиотек нет :(. Кстати в Keil откомпилировалось и запустилось, а симуляция да, не работает… Но хотелось бы именно IAR побороть :)

          1. По моему разобрался! Все компилиться без проблем и дело было не в баяне :). Я по рекомендации в статье скачал свежие библ. CMSIS v3.4 вот в них и была проблема видимо IAR с ними глючит, скачал 3.3 все нормально…

  8. Респектище за статью)) Начал разбираться с STM32VL Discovery. В принципе все нормально, светодиодом помигал, прикрутил дисплей на HD44780. Счас стоит HelloWorld’ом мерцает. Ежели интересно, могу накалякать как и что.
    Кстати, тут проскакивал комент, что инициализация через библиотеку длинная, так я поковырял исходники, там регистры можно оптом настраивать, на одном порту.. как то так:
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init( GPIOB, &GPIO_InitStructure);

          1. Лучше бы выложить, хостингов вроде рапидшары дочерта же. На slil.ru например.
            Сам я тоже на этой же платке ЖК на 44780 запускал, но поскольку цель была только посмотреть как он работает — код страшен и крив).
            Еще портировал пример из статьи на VLDiscovery+IAR. Любопытно, что под дебагом СИД мигает медленнее, чем после ресета МК.

            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
            GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
            GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
            GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
            GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
            GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
            Оптимизатор это вероятно поправит, но ИМХО все же читабельней так:
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
            Ну и покороче.

    1. > Кстати, тут проскакивал комент, что инициализация через библиотеку длинная,
      > так я поковырял исходники, там регистры можно оптом настраивать, на одном порту..
      > как то так:
      > GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
      > GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
      Во первых, чтобы это «открыть» не обязательно было копаться в исходниках… ;-)
      С SPL от ST идет справочник в формате chm, в котором это прямо указано (про него я упоминал в статье).
      А во вторых, если все конфигурационные биты посчитать сразу самому и записать в регистр конфигурации, то всеже намного короче код получится и быстрее. Хотя, для большинства, он будет и менее наглядным…

      1. >С SPL от ST идет справочник в формате chm, в котором это прямо указано (про >него я упоминал в статье).
        ЭТО не справочник ;) Это нечто, во что нужно вдумчиво вкуривать)) У меня снахрапу взять не вышло, полез в исходники…
        >А во вторых, если все конфигурационные биты посчитать сразу самому и записать >в регистр конфигурации, то всеже намного короче код получится и быстрее. Хотя, >для большинства, он будет и менее наглядным…
        И здесь я пошел по пути наименьшего сопротивления.. Сходу расставлять биты в 32 битном регистре как-то не вышло(после 8 бит avr’ок). Точнее не расставлять, а в HEX конвертить.. я просто завис))

  9. Подскажите, а как с stdperiph дальше работать с прерываниями? Очевидно, что там должны быть какие-то механизмы, но я что-то не понял — какие.
    Может в продолжение цикла статей еще и про это написать? Ведь вполне естественная цепочка разработки проекта с нуля: создание проекта -> создание структуры проекта -> настройка проекта под устройство -> подключение заводских библиотек -> написание инициализации железа -> подключение своих процедур обработки прерываний -> написание собственно рабочего кода
    Вот как-то предпоследний пункт не совсем понятен :)

  10. Тэкс Ребятки…. у кого там не компилировалось с ошибкой
    Error[Li005]: no definition for «__iar_program_start» [referenced from E:\DropBox\Dropbox\IAR\hello\Debug\Obj\

    решение нашел
    оказывается проблема в двух местах
    1) Нужно поставить хотяб «Normal» в свойствах проекта-Генерал-вкладка Library config — выпадающий список Library….там сичас ноне … надоть поставить хотяб

    Впринципе уже и заработает и соберется НО…в примере от СТМ рекомендуется точку входа переназначить на Reset_Handler
    потому пункт-
    2) свойства проекта — Linker — Library — Галка Override default prog entry — точка Entry symbol — впечатать без кавычек «Reset_Handler»

    Вот и всё — будет Вам счастье

  11. Люди добрые! подскажите, пожалуйста!
    Знаю, что туплю по мелочи, но мозги уже вспотели
    ткните носом
    ситуация: использую Keil MDK 4.21, STM32F10x_MD, Standard Peripherials Library 3.5.0
    в stm32f10x.h раскомментировал что нужно
    при запуске проекта Keil в дереве проекта хидеры видит, но на вызов любой функции (к примеру: RCC_DeInit из stm32f10x_rcc) ругается, что неопределённая переменная.

  12. Привет rtxonair. Под АРМ первый раз проект создавал. Всё по твоей методике, пункт за пунктом. Но каждый раз делать так больно муторно. Почему не слова о том что в иаре можно создавать шаблоны проектов?
    Я сделал так: создал проект в папке My_temp стащил туда все нужные библиотеки, выставил все опции проекта. В main.c можно что нибудь написать. Проверил что компилится. В общем полностью готовый шаблон. Папку My_temp перетащил по пути IAR Systems\Embedded Workbench 5.4_0\arm\config\template\project\C вычистил из нее файлы созданные компилятором. Должны остаться только папки scr, startup (по твоей версии) и файл проекта My_temp.ewp – его надо переименовать в templproj.ewp Далее: в папке с шаблонами есть два файла main.JPN.projtempl и main.ENU.projtempl. Создаём с них копии и названия меняем с main на My_temp. осталось их подредактировать

    мой шаблон C , готов к работе.”
    My_temp

    $PROJ_DIR$\scr\main.cpp

    Всё, при создании нового проекта шаблон появится в списке :-)

    Первоисточник (для меня) здесь http://chipenable.ru/index.php/iar-embedded-workbench/12-iar-ide-using-templates.html

  13. дошёл до момента где надо раскоментировать STM32F10X_MD_VL шло всё так как написано . Раскоментировал :
    #define STM32F10X_MD_VL /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
    и у меня стало выдавать кучу ошибок см картину , в чём может быть ошибка и как её исправить?
    [URL=http://fastpic.ru/view/28/2012/0202/addc251e28dc8b4d924116333cd260cc.jpg.html][IMG]http://i28.fastpic.ru/thumb/2012/0202/cc/addc251e28dc8b4d924116333cd260cc.jpeg[/IMG][/URL]

  14. Спасибо автору и прочим спецам за отличную тему. Но у меня проблемка.
    Все вроде делаю как автор предложил, но линковаться не хочет:(
    В файле stm32f10x.icf сообщает об ошибках в строках определения адреса вектора прерываний и начальном адресе ROM.
    Error[Lc047]:Illegal integer

    В чем может быть причина, как Вы думаете?

    1. Нашел! Мистика какая-то!
      Взял работающий пример и скопировал из него эти же самые цифры, и заработало. Видимо когда я нажимал цифры я вдохнул в них чуждую энергетику :)

      1. Да, именно в этом всё дело. Попробуйте те значения, которые вписывали вы, вставить в адресную строку браузера — вы увидете, что там совсем не то, что вы хотели написать.

  15. Жаль, что rxtonair давно не появлялся. Я так и не понял, зачем нужен startup_stm32f10x_xxx.s и в какой момент он вызывается компилятором. Если сделать «Exclude from build», то программа всё равно компилируется и работает.

  16. После раскоммента #define STM32F10X_CL выдает следующие ошибки

    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __get_PSP(void)» (declared at line 52 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1084
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp void __set_PSP(unsigned long)» (declared at line 53 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1094
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __get_MSP(void)» (declared at line 50 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1104
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp void __set_MSP(unsigned long)» (declared at line 51 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1114
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __REV16(unsigned long)» (declared at line 177 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1124
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __RBIT(unsigned long)» (declared at line 178 of «C:\Program Files\IAR Systems\ D:\work\MCs\src\inc\core_cm3.h 1134
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __STREXB(unsigned char, unsigned char *)» (declared at line 185 of «C:\Program D:\work\MCs\src\inc\core_cm3.h 1175
    Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__interwork __softfp unsigned long __STREXH(unsigned short, unsigned short *)» (declared at line 186 of «C:\Program D:\work\MCs\src\inc\core_cm3.h 1186
    Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error while running C/C++ Compiler
    Что посоветуете?

      1. Убил на эту ошибку дня три. Уже на скачанный пакет IAR стал грешить — скачал и попробовал все, что были выложены на торрент. Чуть на Keil не перескочил или и того хуже на Кокос. Оказалось все проще:
        1) в свойствах проекта — генерал оптионс — вкладка Library configuaration — CMSIS поставить галочку юз КМСИС
        2) в свойствах проекта — С/С++ компайлер — вкладка Препроцессор — убираем все дополнительные довавочные директории подзагрузки
        3) в корне проекта создаем папку CMSIS и кладем в нее файлы core_cm3.c, core_cm3.h, startup_stm32f10x_xxx.s, stm32f10x.h, system_stm32f10x.c и system_stm32f10x.h, причем файл core_cm3.h берем не из дополнительно скачанной с инета CMSIS, а находим его в установленном IARе

        1. Стоит заметить, что «в установленном IARе» файл stm32f10x.h (к примеру) лежит в десятке разных мест, везде разного размера (содержимое не стал сравнивать).

          Взял из папки «arm\examples\ST\STM32F10x\STM32-Eval\Libraries\CMSIS» (я ковыряю VLDiscovery, а startup_stm32f10x_ld_vl.s только тут нашёлся)

          После этого возникла другая ошибка:
          Error[Li005]: no definition for «__iar_program_start» [program entry]

          Погуглил: в настройках проекта general options—> вкладка Library Configurations —> Library должно стоять Normal , а не None.

          Поправил — все компилируется.

  17. Building configuration: LEDTest — Release
    Updating build tree…
    main.c
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1084
    __get_PSP(void)» (declared at line 52 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_PSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1094
    long)» (declared at line 53 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1104
    __get_MSP(void)» (declared at line 50 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_MSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1114
    long)» (declared at line 51 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1124
    __REV16(unsigned long)» (declared at line 177 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1134
    __RBIT(unsigned long)» (declared at line 178 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1175
    __STREXB(unsigned char, unsigned char *)» (declared at line 185 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1186
    __STREXH(unsigned short, unsigned short *)» (declared at line 186 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error while running C/C++ Compiler
    stm32f10x_gpio.c
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1084
    __get_PSP(void)» (declared at line 52 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_PSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1094
    long)» (declared at line 53 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1104
    __get_MSP(void)» (declared at line 50 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_MSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1114
    long)» (declared at line 51 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1124
    __REV16(unsigned long)» (declared at line 177 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1134
    __RBIT(unsigned long)» (declared at line 178 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1175
    __STREXB(unsigned char, unsigned char *)» (declared at line 185 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1186
    __STREXH(unsigned short, unsigned short *)» (declared at line 186 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error while running C/C++ Compiler
    stm32f10x_rcc.c
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1084
    __get_PSP(void)» (declared at line 52 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_PSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1094
    long)» (declared at line 53 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1104
    __get_MSP(void)» (declared at line 50 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_MSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1114
    long)» (declared at line 51 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1124
    __REV16(unsigned long)» (declared at line 177 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1134
    __RBIT(unsigned long)» (declared at line 178 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1175
    __STREXB(unsigned char, unsigned char *)» (declared at line 185 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1186
    __STREXH(unsigned short, unsigned short *)» (declared at line 186 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error while running C/C++ Compiler
    system_stm32f10x.c
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1084
    __get_PSP(void)» (declared at line 52 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_PSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1094
    long)» (declared at line 53 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1104
    __get_MSP(void)» (declared at line 50 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\
    intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp void __set_MSP(unsigned F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1114
    long)» (declared at line 51 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1124
    __REV16(unsigned long)» (declared at line 177 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1134
    __RBIT(unsigned long)» (declared at line 178 of «C:\Program Files\IAR Systems\Embedded Workbench 6.0\
    arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1175
    __STREXB(unsigned char, unsigned char *)» (declared at line 185 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error[Pe147]: declaration is incompatible with «__nounwind __interwork __softfp unsigned long F:\1WORK\1AVR\ARM\stm32f_cmsis_stdperiphlib\LEDTest_StdPeriphLib\src\inc\core_cm3.h 1186
    __STREXH(unsigned short, unsigned short *)» (declared at line 186 of «C:\Program Files\IAR Systems\
    Embedded Workbench 6.0\arm\inc\c\intrinsics.h»)
    Error while running C/C++ Compiler

    Total number of errors: 32
    Total number of warnings: 0
    на 6.30 такие же грабли, как вылечить?

    1. Убил на эту ошибку дня три. Уже на скачанный пакет IAR стал грешить — скачал и попробовал все, что были выложены на торрент. Чуть на Keil не перескочил или и того хуже на Кокос. Оказалось все проще:
      1) в свойствах проекта — генерал оптионс — вкладка Library configuaration — CMSIS поставить галочку юз КМСИС
      2) в свойствах проекта — С/С++ компайлер — вкладка Препроцессор — убираем все дополнительные довавочные директории подзагрузки
      3) в корне проекта создаем папку CMSIS и кладем в нее файлы core_cm3.c, core_cm3.h, startup_stm32f10x_xxx.s, stm32f10x.h, system_stm32f10x.c и system_stm32f10x.h, причем файл core_cm3.h берем не из дополнительно скачанной с инета CMSIS, а находим его в установленном IARе

  18. «Убил на эту ошибку дня три. Уже на скачанный пакет IAR стал грешить — скачал и попробовал все, что были выложены на торрент. Чуть на Keil не перескочил или и того хуже на Кокос. Оказалось все проще:
    1) в свойствах проекта — генерал оптионс — вкладка Library configuaration — CMSIS поставить галочку юз КМСИС
    2) в свойствах проекта — С/С++ компайлер — вкладка Препроцессор — убираем все дополнительные довавочные директории подзагрузки
    3) в корне проекта создаем папку CMSIS и кладем в нее файлы core_cm3.c, core_cm3.h, startup_stm32f10x_xxx.s, stm32f10x.h, system_stm32f10x.c и system_stm32f10x.h, причем файл core_cm3.h берем не из дополнительно скачанной с инета CMSIS, а находим его в установленном IARе»
    Все проще!
    Делаете пункт 1, а далее берете файл \arm\CMSIS\Include\core_cm3.h и меняете им свой в проекте
    Вот источник по этому: http://www.emcu.it/ARM_Compiler/IAR/IAR_tips_and_tricks.html

  19. Добрый день!
    У меня такая проблема, может поможет кто. Работаю в IAR версии 6.5, пишу программу потихоньку. Все нормально компилировалось, работало в режиме отладки. Тут мне понадобилось во флеш записать, чтобы устройство отдельно работало. И тупик. В окне пишет что заливается во флеш, а программа не стартует после перещелкивания питания. Что может быть? Перепробовал уже уйму всего — и создавал проект заново, и кидал исходники в созданный примерчик моргалки светодиода, и даже в keil создал. Та же ерунда.

  20. Всем привет, вопрос будет по EWAVR:
    Есть проект, созданный для Atmega32, нужно переделать под другой проц 2560 (глубокая адаптация исхододника выходит за рамки вопроса).
    Проект содержит подключаемые файлы iom32.h и iom32.inc. В строчках #include меняю на iom2560.h,
    и в проекте появляются файлы iom2560.h iom2560.inc. Но нужно удалить хидеры от 32 меги, а они нифига не удаляются. Правой кнопкой — Удалить. Но ничего не происходит. Компилятор-то на них ругается…
    Конечно, я файлы проекта .ewp вручную подправил. Но это «незаконно», наверняка ведь можно и из среды сделать?

Добавить комментарий