Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » RA » HardFault_Handler/ sprintf/ stm32f103


HardFault_Handler/ sprintf/ stm32f103

Сообщений 1 страница 30 из 38

1

Есть вот такое

Код:
void go_to( char *value ){
	#define enc_tic 20.0 //кол-во положений енкодера
	#define r_l_ob  2.0  //шаг резьбы один оборот 1мм
	#define ntic 4.0     //счет енкодера одно положение 4 тика счетного регистра
	float x = 0;
	float xx = 0;
	char *strtemp1;
	if (_LineState.L)USBLIB_Transmit((uint16_t *)"goto/", 5 );delay_ms(1);
	sscanf( value, "%f", &x );/*из строки в переменную*/
	/*пришли милимметры надо получить тики енкодера
	1 мм это 20 тиков * 4/шаг резьбы 2мм на оборот = 80 тиков счетного регистра.
	значит x*enc_tic*ntic*/
	xx=x*enc_tic*ntic/r_l_ob;
	/* выводим счетный регистр енкодера*/
	sprintf(strtemp1,"%d",(int)(TIM3->CNT));/*из переменной в строку*/
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp1, strlen( strtemp1 ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	/*запускаем движек и ждем равенства между нужным положением и реальным значением счетного регистра*/
	while( TIM3->CNT != (uint16_t)(xx) ){
    while( TIM3->CNT < (uint16_t)(xx)){left_on;delay_ms(50);left_off;delay_ms(200);}
    while( TIM3->CNT > (uint16_t)(xx)){right_on;delay_ms(50);right_off;delay_ms(200);}
	}
	/*вычеляем обратно положение в мм из счетного регистра енкодера*/
	xx=((1/(enc_tic*ntic))*TIM3->CNT)*r_l_ob;
	sprintf(strtemp1, "%f", xx );/*из переменной в строку*/
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp1, strlen( strtemp1 ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	if (_LineState.L)USBLIB_Transmit((uint16_t *)"done\r\n", 4+2 );delay_ms(1);
}

после вот этой строки

Код:
sprintf(strtemp1,"%d",(int)(TIM3->CNT));/*из переменной в строку*/

попадаю HardFault_Handler\B.
Что не так? Не догоняю.
раньше работало, но на каком этапе перестало, нить потерял... все пляски упираются хардфаулт.
http://sg.uploads.ru/t/JLmnK.png
http://s5.uploads.ru/t/ZLt3Y.png
http://sh.uploads.ru/t/HyzKX.png
возвращаемого значения нет. "виснет" на этапе выполнения .
а тут

Код:
///////////////////////////////////////////////////////////////////////////////
void set_pwm( char *value, char *value2, char *value3 ){
	int x;
	int x2;
	int x3;
	char *strtemp;
	if (_LineState.L)USBLIB_Transmit((uint16_t *)"set_pwm/", 8 );delay_ms(1);
	sscanf( value, "%d", &x );/*из строки в переменную*/
	sscanf( value2, "%d", &x2 );/*из строки в переменную*/
	sscanf( value3, "%d", &x3 );/*из строки в переменную*/
	driver_off;
	TIM2->CR1 &= ~TIM_CR1_CEN;
	TIM2->PSC = (uint16_t)x - 1;
  TIM2->ARR = (uint16_t)x2;
	TIM2->CCR1 = (uint16_t)x3;
	driver_off;
	sprintf(strtemp, "%d", (int)(TIM2->PSC +1) );/*из переменной в строку*/
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp, strlen( strtemp ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	sprintf(strtemp, "%d", (int)(TIM2->ARR) );/*из переменной в строку*/
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp, strlen( strtemp ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	sprintf(strtemp, "%d", (int)(TIM2->CCR1) );/*из переменной в строку*/
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp, strlen( strtemp ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	if (_LineState.L)USBLIB_Transmit((uint16_t *)"done\r\n", 4+2 );delay_ms(1);	
	TIM2->CR1 |= TIM_CR1_CEN;
	driver_on;
}

все работает как задумано. ничего не понимаю. Как посмотреть чем именно вызвана ошибка?

2

а если присвоить какой-нибудь переменной (int)(TIM3->CNT) . , а потом уже sprintf делать с ней ?

3

Atomic-dm написал(а):

а если присвоить какой-нибудь переменной (int)(TIM3->CNT) . , а потом уже sprintf делать с ней ?

естественно пробовал. результат тот же. и snprintf пробовал. чего уже только не пробовал... осталось только массив задать и с ним попробовать.

4

RA, всё, что тебе на самом деле нужно - это systick и дебаггер
Ну и вернуться назад, на ту развилку с которой ты пошёл не туда, и эта развилка похоже очень далеко

5

ну я вообще sprintf не использую... из принципа :)

кстати CNT у меня адекватно дебаггером посмотреть не получалось.

6

vt написал(а):

RA, всё, что тебе на самом деле нужно - это systick и дебаггер
Ну и вернуться назад, на ту развилку с которой ты пошёл не туда, и эта развилка похоже очень далеко

Хорошо, пусть так. что мне делать то с systick&дебаггер?
вернуться куда? что вообще за намеки, полуслова, полумысли? Я тебя не понимаю, может туповат, извини. можно прямо? без танцев вокруг да около?

7

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

8

Ну вот зачем использовать функции, приводящие к UB? Что там malloc для этого делает? Или это самописный sprintf?
Зачем вообще такие жирные функции, а также функции, требующие маллоков, использовать в МК bare metal? Кому нужен жир и маллоки, обмазываются ртосями.

9

Код:
void go_to( char *value ){
	int x;
	char *strtemp;
	if(_LineState.L)USBLIB_Transmit((uint16_t *)"goto/", 5 );delay_ms(1);
  sscanf( value, "%u", &x );/*из строки в переменную*/
	sprintf(strtemp, "%u", (int)(TIM3->CNT) );
	if(_LineState.L){USBLIB_Transmit((uint16_t *)strtemp, strlen( strtemp ) );delay_ms(1);USBLIB_Transmit((uint16_t *)"/", 1 );delay_ms(1);}
	if(_LineState.L)USBLIB_Transmit((uint16_t *)"done\r\n", 4+2 );delay_ms(1);
}

работает. http://sh.uploads.ru/t/BlZJc.png
добавляю дальше...

10

RA написал(а):

malloc где?

многие функции из printf-семейства хотят аллокаторы. sprintf не хочет, но лучше посмотреть, что за хрень там внутри.
А вообще, printf для микроконтроллеров - это такой жуткий оверхед, что лучше их только на каких-нибудь жиробасах с мегабайтами флеша и десятками КБ оперативы использовать...
А уж sscanf - вообще лютый оверхед! Если же ты не проверяешь, что она возвращает, то ССЗБ!

Отредактировано Eddy_Em (2018-10-30 21:14:57)

11

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

12

Eddy_Em спасибо. начинаю понимать откуда ноги растут.

13

Код:
void go_to( char *value ){
 int x;
 char *strtemp = (char *)malloc(strlen(value)+1);
 sprintf(strtemp,"%u",(int)(TIM3->CNT));
}
Код:
void go_to( char *value ){
	int x;
	//char *strtemp = (char *)malloc(strlen(value)+1);
	char *strtemp = (char *)calloc(strlen(value)+1,sizeof(char));
	sprintf(strtemp,"%u",(int)(TIM3->CNT));
}

что-то около того?

14

vt написал(а):

RA, всё, что тебе на самом деле нужно - это systick и дебаггер
Ну и вернуться назад, на ту развилку с которой ты пошёл не туда, и эта развилка похоже очень далеко

посмотреть как долго выполняются библиотечные функции?

15

Написать всю программу целиком в виде ф-ций пустышек [вообще всю, а не какую-то часть], представить себе как оно всё будет вертеться по времени и только потом уже писать сами ф-ции
Systick - это дискретизация по времени и синхронизация

16

vt написал(а):

Написать всю программу целиком в виде ф-ций пустышек [вообще всю, а не какую-то часть], представить себе как оно всё будет вертеться по времени и только потом уже писать сами ф-ции
Systick - это дискретизация по времени и синхронизация

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

17

Только всё привязывается не к событиям, а к такту
Общая структура программы - синхронный автомат
http://s7.uploads.ru/Ok4lr.png

18

т.е. создаем прерывание от системного таймера допустим каждые 1мс, в нем уже каждое 1 прерывание проверяем пришло ли что по компорту и что у нас есть на выход в компорт. каждое 2-ое анализируем что пришло... 3-е определяемся какую команду запустить и что ей надо из ресурсов. и так далее... ??? хотя каждое 1-ое надо анализировать что уже запущено и выполнено или нет и как выполнено с ошибкой или без... в ту хоть сторону шагаю???

19

В простейшем случае вся real time часть программы может быть в прерывании systick, а остальное фоном
Компорт - это обычно не real time, если не используется в управлении
А в общем случае - спец scheduler с синхронизацией [time triggered]

Ты хоть какие-нибудь термины, которые я нарочно вскользь кидаю, гуглишь?
Я "намёками" разговариваю не для понта, а потому что не хочу пересказывать книжки целыми главами )

20

vt написал(а):

В простейшем случае вся real time часть программы может быть в прерывании systick, а остальное фоном
Компорт - это обычно не real time, если не используется в управлении
А в общем случае - спец scheduler с синхронизацией [time triggered]

Ты хоть какие-нибудь термины, которые я нарочно вскользь кидаю, гуглишь?
Я "намёками" разговариваю не для понта, а потому что не хочу пересказывать книжки целыми главами )

конечно гуглю. но столько информации сразу не осилить. точнее не отфильтровать, ведь столько всего...
может... ну если время будет, какие нибудь статьи с примерами, не кода а удобовоспринимаемых примеров - теории.  ну к примеру аллокаторы - https://habr.com/post/274827/. ну очень наглядно и понятно. я понимаю что нафиг оно тебе надо, что там искать, просто что-то может на слуху, где-то недавно что-то попадалось или запомнилось где лучше/удачно подано... разжевано. ну как то так.
пока читаю впитываю вникаю...

21

Есть такая новомодная движуха - "Автоматное программирование", не совсем ясно правда чем оно отличается от старой классики, но зато на слуху, популяризируется, со своими пророками, откровениями и фанклубами, в общем всё вполне в стиле эмбеда )
Глянь, может понравится [ну и хуже от этого точно не будет]

22

Без конечных автоматов только свктодиодиврм и выйдет помигать. Скажем, с тем же DS18: у него очень длинная стадия инициализации, поэтому без КА придется очень много времени терять зазря. А так проверяешь, тайм-аут данного состояния вышел - ок, меняем состояние на опрос и запускаем DMA.

23

Все у тебя перемешалось....

24

HHIMERA написал(а):

Все у тебя перемешалось....

у кого? к кому обращение?

25

К Эде ...

26

Нифига не понял: что перемешалось?

// кстати, со скуки, пока сижу в больнице начал для STM32F103 "безбиблиотечный" код пробовать писать. Для начала - стандартный блинк. Правда, два часа убил только на сбор и правку нужных заголовочных файлов. Остается еще клок проверить по даташиту и поменять макросы для настройки режимов ног.
Все же, как все просто у F0...

27

ну так как дело ушло хардфаульт. чем он был вызван я уже понял. теперь вот такая штука.

Код:
#include "stm32f10x.h"
#include "usblib.h"
#include "string.h"
#include <stdio.h>
#include <stdlib.h>
char *str_temp  =0;
int main(void)
{
write_usb("123");
write_usb("456");
write_usb("789");
while (1) {};
}
Код:
void write_usb( char *str)
{
  uint8_t size_str = strlen( str );
  if( str_temp == 0 ){/*если в строке пусто*/
    str_temp = malloc( size_str + 1 );
    memcpy( str_temp, str , size_str );
  }
  else{/*если в строке уже что то есть*/
    str_temp = realloc( str_temp, size_str + 1 );
    strcat( str_temp, str );
  }
}

правильно ли выделяю память под вырастающую строку? чисто теоретически? проверять - проверяю, вроде все гуд.
http://s3.uploads.ru/t/nXPh4.png

Отредактировано RA (2018-11-05 18:26:21)

28

strlen возвращает длинну строки без 0. А memcpy 0 не копирует, и там на том месте остается то, что было до этого в памяти - т.е. мусор, который может быть и не 0.
Надо либо
memcpy( str_temp, str , size_str + 1);
либо дополнительно еще
str_temp[size_str ] = 0;
делать.

Отредактировано MasterAlexei (2018-11-06 08:48:54)

29

Не могу на эти malloc'и без слез смотреть! Это ж микроконтроллер! Там маллок нафиг не сдался вообще!!!

30

MasterAlexei написал(а):

strlen возвращает длинну строки без 0. А memcpy 0 не копирует, и там на том месте остается то, что было до этого в памяти - т.е. мусор, который может быть и не 0.
Надо либо
memcpy( str_temp, str , size_str + 1);
либо дополнительно еще
str_temp[size_str ] = 0;
делать.

Отредактировано MasterAlexei (Сегодня 05:48:54)

значит, лучше вообще через calloc, он занулит выделеную память, а уж копировать не копировать конец строки - не важно, место выделено и занулено.

Код:
void SysTick_Handler(void)
{
	//if(flag_tx);//очистить строку
	uint8_t size_str1 = strlen( str_temp );
	if( size_str1 ){/*если в строке что то есть*/
    if( size_str1 <= 63 ){/*в буфер передачи*/
    	if( _LineState.L ){USBLIB_Transmit((uint16_t *) str_temp, size_str1);}
    //	++flag_tx; 
    }
    else{/*не умещается в буфер передачи*/
    	
    }
	}
	else{/*если в строке ничего нет*/
	}
}
Код:
void write_usb( char *str)
{
	uint8_t size_str = strlen( str );
	if( str_temp == 0 ){/*если в строке пусто*/
    str_temp = calloc( size_str + 1, sizeof(char) );
    memcpy( str_temp, str , size_str );
	}
	else{/*если в строке уже что то есть*/
    str_temp = realloc( str_temp, size_str + 1 );
    strncat( str_temp, str, size_str+1 );
	}
}

Вы здесь » Микроконтроллеры » RA » HardFault_Handler/ sprintf/ stm32f103