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

STM32VLDISCOVERY + Keil

Здравствуйте, недавно начал изучать МК с этим ядром. Пока что в основном все понятно, попробовал написать простую прогу на ассемблере по примерам с сайта http://stm32asm.ru. Все работает, но т.к. писать весь код на ассемблере для кортексов - не вариант, решил по-тихоньку переходить на СИ. Появились кое-какие вопросы. К примеру, написал код, аналогичный коду на ассемблере, скомпилировал, запустил отладку. И вижу, что выполнение программы начинается с каких-то "левых" функций/процедур(см. вложение). Что это такое, для чего нужно? Можно ли как-то сделать, чтобы компилятор СИ не добавлял их в программу?

post-55094-1333014461_thumb.jpg

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


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

Настройки таргета, закладка Linker, поставить галочку Don't Search Standard Libraries (хотя это верхушка айсберга :) )

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


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

Настройки таргета, закладка Linker, поставить галочку Don't Search Standard Libraries (хотя это верхушка айсберга :) )

Спасибо, думаю, сработало, ибо вылезла ошибка:

discovery_C2.axf: Error: L6218E: Undefined symbol __main (referred from startup_stm32f10x_ld_vl.o).

Как мне теперь передать управление мэйну из стартап-файла? Сейчас там такая бадяга:

IMPORT  __main
LDR R0, =__main
BX R0

Изменено пользователем ohmjke

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


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

Проще всего переименовать свой main() в __main() :)

Большое спасибо, работает! Правда, вылез один warning:

discovery_C2.sct(8): warning: L6314W: No section matches pattern *(InRoot$$Sections).

Но, насколько я понял, на работоспособность моей программы это не влияет. В железе все норм. В отладчике видно, что код во flash размещается с адреса 0x08000000, как и должно быть.

А не подскажете, где можно почитать про все эти взаимодействия между СИ и asm файлами проекта?

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


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

Как-то сейчас и не вспомню, теоретически в хелпе того же кейла можно посмотреть...

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


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

И вижу, что выполнение программы начинается с каких-то "левых" функций/процедур(см. вложение). Что это такое, для чего нужно? Можно ли как-то сделать, чтобы компилятор СИ не добавлял их в программу?

Освоение языка Си точно не следует начинать с этого. К чему этот минимализм? Он будет только мешать. Кстати, если я правильно помню, в Кейле есть опция MicroLib: по сути это обезжиренная версия стандартной библиотеки, оптимизированная по размеру, а не по скорости.

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


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

Освоение языка Си точно не следует начинать с этого. К чему этот минимализм? Он будет только мешать. Кстати, если я правильно помню, в Кейле есть опция MicroLib: по сути это обезжиренная версия стандартной библиотеки, оптимизированная по размеру, а не по скорости.

Осваивать СИ я начал относительно давно. Просто хочется знать за что отвечает каждый кусок программы, дело не том, что мне жалко флеша :rolleyes:

 

А вообще спасибо! Попробовал microlib - доволен. Намного понятнее, чем стандартная библиотека.

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


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

Осваивать СИ я начал относительно давно. Просто хочется знать за что отвечает каждый кусок программы, дело не том, что мне жалко флеша :rolleyes:

 

А вообще спасибо! Попробовал microlib - доволен. Намного понятнее, чем стандартная библиотека.

 

Учтите, что за MicroLIB придется заплатить. К примеру, функции из этой библиотеки нельзя использовать при работе с KEIL RTX.

 

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


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

Учтите, что за MicroLIB придется заплатить. К примеру, функции из этой библиотеки нельзя использовать при работе с KEIL RTX.

Я пока не настольно крут, чтобы использовать KEIL RTX :rolleyes:

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


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

Потихоньку изучаю свой cm3, дошел до RTC.

Проблема с функцией для получения даты и времени зная значение счетчика RTC.

Набыдлокодил такую фиговину:

extern void rtc_decoder (uint32_t counter, date_t *date, time_t *time) {
static const int8_t mth_vls [] = {1, -1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1};
int64_t temp;
uint32_t temp_2, temp_3;
uint8_t i = 0;
temp = (uint32_t)(counter % SEC_PER_4Y);
if (temp > SEC_PER_LY) {
	temp -= SEC_PER_LY;
	i++;
	while (temp > SEC_PER_Y) {
		temp -= SEC_PER_Y;
		i++;
	};
};
date->year = 2012 + ((counter / SEC_PER_4Y) << 2) + i;
i = 0;
do {
	temp_2 = (uint32_t)temp;
	if (mth_vls [i] == 1) {
			temp -= 31 * SEC_PER_D;
	} else if (mth_vls [i] == 0) {
			temp -= 30 * SEC_PER_D;
	} else {
		if (!(date->year % 4)) {
				temp -= 29 * SEC_PER_D;
		} else {
				temp -= 28 * SEC_PER_D;
		};
	};
	i++;	
} while (temp > 0);
date->month = (month_t)i;
date->day = (temp_2 / SEC_PER_D) + 1;
temp_3 = temp_2 % SEC_PER_D;
time->hour = temp_3 / 3600;
temp_2 = temp_3 % 3600;
time->minute = temp_2 / 60;
time->second = temp_2 % 60;
};

В *.h файле следующее:

#define START_YEAR (2012UL)
#define SEC_PER_4Y (126230400UL)
#define SEC_PER_LY (31622400UL)
#define SEC_PER_Y (31536000UL)
#define SEC_PER_D (86400UL)

typedef enum {
	Sunday = 0,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday
} weekday_t; 

typedef enum {
	January = 1,
	February,
	March,
	April,
	May,
	June,
	July,
	August,
	September,
	October,
	November,
	December
} month_t;

typedef struct {
uint8_t second;
uint8_t minute;
uint8_t hour; 
} time_t;

typedef struct {
uint8_t day;
month_t month; 
uint16_t year; 
} date_t;

static time_t system_time;
static date_t system_date;

В мэйне один раз при запуске вызываю эту функцию:

rtc_decoder (0x00F156CB, &system_date, &system_time);

И затем в обработчике внешнего прерывания вывожу такую бадягу:

usart1_putchar (system_date.year / 1000);
usart1_putchar ((system_date.year % 1000) / 100);
usart1_putchar ((system_date.year % 100) / 10);
usart1_putchar (system_date.year % 10);

Проблема в том, что в режиме отладки, когда проц переходит к началу этой функции, начинают вываливаться ошибки. Сначала появляется окно с текстом "Internal command error", затем "Error while attempting to read 64 bytes from 0x20001ffc", затем опять первое окно, после него опять второе...

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

Ну и, дизассемблер:

0x08000490 B5F0	  PUSH	 {r4-r7,lr}
16:  
0x08000492 4B43	  LDR	  r3,[pc,#268] ; @0x080005A0
0x08000494 4E43	  LDR	  r6,[pc,#268] ; @0x080005A4
0x08000496 FBB0F7F3  UDIV	 r7,r0,r3
0x0800049A FB030017  MLS	  r0,r3,r7,r0
15:		 uint8_t i = 0; 
16:  
0x0800049E 2400	  MOVS	 r4,#0x00
0x080004A0 4623	  MOV	  r3,r4
0x080004A2 1A36	  SUBS	 r6,r6,r0
0x080004A4 EB740503  SBCS	 r5,r4,r3
17:		 temp = (uint32_t)(counter % SEC_PER_4Y); 
0x080004A8 DA12	  BGE	  0x080004D0
18:		 if (temp > SEC_PER_LY) { 
0x080004AA 4C3E	  LDR	  r4,[pc,#248] ; @0x080005A4
0x080004AC 4264	  RSBS	 r4,r4,#0
0x080004AE 1900	  ADDS	 r0,r0,r4
0x080004B0 F14333FF  ADC	  r3,r3,#0xFFFFFFFF
19:				 temp -= SEC_PER_LY; 
0x080004B4 2401	  MOVS	 r4,#0x01
20:				 i++; 
0x080004B6 E005	  B		0x080004C4
21:				 while (temp > SEC_PER_Y) { 
0x080004B8 4D3B	  LDR	  r5,[pc,#236] ; @0x080005A8
0x080004BA 1940	  ADDS	 r0,r0,r5
0x080004BC F14333FF  ADC	  r3,r3,#0xFFFFFFFF
22:						 temp -= SEC_PER_Y; 
23:						 i++; 
24:				 }; 
0x080004C0 1C64	  ADDS	 r4,r4,#1
0x080004C2 B2E4	  UXTB	 r4,r4
0x080004C4 4E38	  LDR	  r6,[pc,#224] ; @0x080005A8
0x080004C6 2500	  MOVS	 r5,#0x00
0x080004C8 4276	  RSBS	 r6,r6,#0
0x080004CA 1A36	  SUBS	 r6,r6,r0
0x080004CC 419D	  SBCS	 r5,r5,r3
20:				 i++; 
21:				 while (temp > SEC_PER_Y) { 
22:						 temp -= SEC_PER_Y; 
23:						 i++; 
24:				 }; 
0x080004CE DBF3	  BLT	  0x080004B8
25:		 }; 
26:		 date->year = 2012 + ((counter / SEC_PER_4Y) << 2) + i; 
27:		 i = 0; 
28:		 do { 
0x080004D0 EB040487  ADD	  r4,r4,r7,LSL #2
0x080004D4 F20474DC  ADDW	 r4,r4,#0x7DC
0x080004D8 FA1FFE84  UXTH	 lr,r4
29:				 temp_2 = (uint32_t)temp; 
30:				 if (mth_vls [i] == 1) { 
0x080004DC F8DFC0CC  LDR.W	r12,[pc,#204] ; @0x080005AC
0x080004E0 F8A1E002  STRH	 lr,[r1,#0x02]
26:		 date->year = 2012 + ((counter / SEC_PER_4Y) << 2) + i; 
27:		 i = 0; 
0x080004E4 2400	  MOVS	 r4,#0x00
0x080004E6 F91C6004  LDRSB	r6,[r12,r4]
28:		 do { 
29:				 temp_2 = (uint32_t)temp; 
30:				 if (mth_vls [i] == 1) { 
0x080004EA 4605	  MOV	  r5,r0
0x080004EC 2E01	  CMP	  r6,#0x01
0x080004EE D025	  BEQ	  0x0800053C
31:						 temp -= 31 * SEC_PER_D; 
32:				 } else if (mth_vls [i] == 0) { 
33:						 temp -= 30 * SEC_PER_D; 
0x080004F0 B336	  CBZ	  r6,0x08000540
34:				 } else { 
35:						 if (!(date->year % 4)) { 
36:										 temp -= 29 * SEC_PER_D; 
0x080004F2 EA5F768E  LSLS	 r6,lr,#30
0x080004F6 D025	  BEQ	  0x08000544
37:						 } else { 
38:										 temp -= 28 * SEC_PER_D; 
39:						 }; 
0x080004F8 4E2D	  LDR	  r6,[pc,#180] ; @0x080005B0
40:				 }; 
0x080004FA 2700	  MOVS	 r7,#0x00
0x080004FC 1980	  ADDS	 r0,r0,r6
0x080004FE F14333FF  ADC	  r3,r3,#0xFFFFFFFF
0x08000502 1C64	  ADDS	 r4,r4,#1
0x08000504 463E	  MOV	  r6,r7
0x08000506 1A3F	  SUBS	 r7,r7,r0
0x08000508 B2E4	  UXTB	 r4,r4
0x0800050A 419E	  SBCS	 r6,r6,r3
41:				 i++;	 
42:		 } while (temp > 0); 
0x0800050C DBEB	  BLT	  0x080004E6
43:		 date->month = (month_t)i; 
0x0800050E 4B29	  LDR	  r3,[pc,#164] ; @0x080005B4
42:		 } while (temp > 0); 
43:		 date->month = (month_t)i; 
0x08000510 704C	  STRB	 r4,[r1,#0x01]
0x08000512 FBB5F0F3  UDIV	 r0,r5,r3
0x08000516 1C44	  ADDS	 r4,r0,#1
44:		 date->day = (temp_2 / SEC_PER_D) + 1; 
0x08000518 FB035010  MLS	  r0,r3,r0,r5
43:		 date->month = (month_t)i; 
44:		 date->day = (temp_2 / SEC_PER_D) + 1; 
0x0800051C 700C	  STRB	 r4,[r1,#0x00]
45:		 temp_3 = temp_2 % SEC_PER_D; 
0x0800051E F44F6361  MOV	  r3,#0xE10
0x08000522 FBB0F1F3  UDIV	 r1,r0,r3
46:		 time->hour = temp_3 / 3600; 
0x08000526 FB030011  MLS	  r0,r3,r1,r0
0x0800052A 7091	  STRB	 r1,[r2,#0x02]
47:		 temp_2 = temp_3 % 3600; 
0x0800052C 233C	  MOVS	 r3,#0x3C
0x0800052E FBB0F1F3  UDIV	 r1,r0,r3
48:		 time->minute = temp_2 / 60; 
0x08000532 FB030011  MLS	  r0,r3,r1,r0
0x08000536 7051	  STRB	 r1,[r2,#0x01]
0x08000538 7010	  STRB	 r0,[r2,#0x00]
49:		 time->second = temp_2 % 60; 
50: }; 
0x0800053A BDF0	  POP	  {r4-r7,pc}
30:				 if (mth_vls [i] == 1) {

Использую MICROLIB.

 

 

/***************************************************************************/

 

 

Блин. Как часто со мной бывает - нашел косяк вскоре после того как задал здесь вопрос.

Проблема со стеком. В чем именно она была, я так и не понял, но решить ее удалось.

У меня был вручную подправлен scatter-файл:

LR_IROM1 0x08000000 0x00020000  {; load region size_region
  ER_IROM1 0x08000000 0x00020000  {; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM2 0x20001000 0x00001000  {; stack
   *.o (STACK, +First)
  }
  RW_IRAM1 0x20000000 0x00001000  {; RW data
   .ANY (+RW +ZI)
  }
}

Убрал кусок

RW_IRAM2 0x20001000 0x00001000  {; stack
   *.o (STACK, +First)
  }

и исправил размер RW_IRAM2 с 0x00001000 на 0x00002000, и ошибки перестали выскакивать. Раньше при запуску содержимое SP было таким - 0x20002000, теперь такое - 0x20001114. Надо будет как-нибудь со всем этим рзобраться.

Изменено пользователем ohmjke

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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