Проблемы при программировании AVR на Си

Обсуждение статей, технологий домашней автоматизации, программных и аппаратных решений
alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 10 апр 2014, 11:16

Добрый день попробывал на своем девайсе , все работает , держите код
if (page==7) {// reset
RstCount=eeprom_read_byte(&EEMEM_RSTCOUNT);
plen=fill_tcp_data_p(buf,plen,PSTR("<h2>Reset</h2>"));
intToStr(Prm,RstCount ,3);
plen=fill_tcp_data(buf,plen,Prm);
www_server_reply(buf,plen); // send data

HardReset();
void HardReset()
{
RstCount++;
eeprom_write_byte(&EEMEM_RSTCOUNT, RstCount);
wdt_enable(WDTO_15MS); // enable watchdog
while(1); // wait for watchdog to reset processor
}
жирным шрифтом выделено то что Вы должны добавить
во вложении скрин , при нажатии ссылки reset увеличивается счетчик нажатий
ежели что пишите
Вложения
reset_coint.rar
(16.59 КБ) 302 скачивания

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 10 апр 2014, 13:25

Alex_Jet Отличная работа :!: очень понравилось , завтра разберусь с компилятором (кстати у меня еще древнее 2009) только смущают огромный пинг 155-160ms , временами интерфейс не отвечает совсем , traceroute показывает большие задежки на маршруте(более 10 узлов)

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 10 апр 2014, 13:51

alexsis_76 писал(а):Alex_Jet Отличная работа :!: очень понравилось , завтра разберусь с компилятором (кстати у меня еще древнее 2009) только смущают огромный пинг 155-160ms , временами интерфейс не отвечает совсем , traceroute показывает большие задежки на маршруте(более 10 узлов)
Спасибо за похвалу и спасибо что поняли в чем проблема - я бы еще недельку копался, пока дошел бы до этого... Огромный пинг и tracerout из-за того, что девайс подцеплен к маршрутизатору, который через 3G по VPN выходит на мой домашний VPN-server (на базе маршрутизатора)... а, кстати, вы бы до девайса-то Ping-ом или Tracert-ом и не достучались! Они же не работают с портами.

Все равно не понимаю!!! Не логично это все. Конвертируем цифру в строку и она отображается???
alexsis_76 писал(а):

Код: Выделить всё

intToStr(Prm,RstCount ,3);
plen=fill_tcp_data(buf,plen,Prm);
Почему тогда все остальные переменные отображаются нормально на страницах, например:

Код: Выделить всё

		plen=fill_tcp_data_int(buf,plen,TIMER_DAY);
		plen=fill_tcp_data_p(buf,plen,PSTR(" day "));
		plen=fill_tcp_data_int(buf,plen,TIMER_HOUR);
		plen=fill_tcp_data_p(buf,plen,PSTR(":"));
		if(TIMER_MIN<10) plen=fill_tcp_data_p(buf,plen,PSTR("0"));
		plen=fill_tcp_data_int(buf,plen,TIMER_MIN);
ЗАБИРАЮ СВОИ СЛОВА НАЗАД!
В моей же версии программы есть функция, которая выводит на страничку уже строку!

Код: Выделить всё

uint16_t fill_tcp_data_int(uint8_t *buf,uint16_t plen,int16_t i)
{	intToStr(Strbuf,i,5);			// convert integer to string
    return(fill_tcp_data(buf,plen,Strbuf));
}
Я вывожу ведь так:

Код: Выделить всё

		plen=fill_tcp_data_int(buf,plen,RstCount);
Вы, получается то же делаете, но "вручную". Поэтому тут что-то другое - вероятно все же оптимизация кода компилятором.
Последний раз редактировалось Alex_Jet 10 апр 2014, 14:15, всего редактировалось 2 раза.


Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 10 апр 2014, 14:08

alexsis_76 писал(а):Заработало :?:
Проверить смогу только через часиков 4-5. В любом случае, завтра отпишусь. Однако у меня разрыв мозга все же - смотри корректировку предыдущего поста.

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 10 апр 2014, 15:05

fill_tcp_data_int
я только сейчас обратил на это внимание , в моем исходнике нет fill_tcp_data_int, а есть только fill_tcp_data и перед ней всегда делается intToStr , иначе выводятся каракули

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 10 апр 2014, 21:17

Ну что сказать - перелопатил все. Выяснил лишь одно - счетчик начинает нормально работать только тогда, когда комментирую следующие строчки в функции HardReset():

Код: Выделить всё

	wdt_enable(WDTO_15MS);		// enable watchdog
	while(1);					// wait for watchdog to reset processor
Получается, что либо инфа не успевает записаться в EEPROM, либо что-то где-то еще.

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 11 апр 2014, 02:35

Интересное кино
Получается, что либо инфа не успевает записаться в EEPROM
попробуйте поставить задежку перед wdt_enable(WDTO_15MS);, хотя по идее функция не возвращает управление пока запись в eeprom не завершится, у меня ведь работает,может компилятор мудрит, ведь не просто так у меня ваша прошивка не работает,хотя ведь все остальное у Вас нормально функционирует, сегодня попробую запустит Вашу прошивку у себя

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 11 апр 2014, 06:29

alexsis_76 писал(а):Интересное кино
попробуйте поставить задежку перед wdt_enable(WDTO_15MS);, хотя по идее функция не возвращает управление пока запись в eeprom не завершится, у меня ведь работает,может компилятор мудрит, ведь не просто так у меня ваша прошивка не работает,хотя ведь все остальное у Вас нормально функционирует, сегодня попробую запустит Вашу прошивку у себя
Перепробовал все!
1. Ставил задержку до wdt_enable(WDTO_15MS)
2. Убирал совсем wdt_enable(WDTO_15MS) и оставлял в HardReset() задержку 1000мС, поскольку в основной программе уже есть wdt_enable(WDTO_1S)
3. Убирал совсем wdt_enable(WDTO_15MS) и оставлял в HardReset() бесконечный цикл, поскольку в основной программе уже есть wdt_enable(WDTO_1S)
4. Ставил wdt_enable(WDTO_15MS) до инкремента счетчика и записи в EEPROM
4. Пробовал дополнительно сбрасывать watchdog перед wdt_enable(WDTO_15MS).
И все тоже! Будто для нормальной записи в EEPROM зачем-то нужна передача управления основной программе!???

Единственное что выходит - это счет 5,10,15,20,25 когда EEPROM считываю не при входе на страницу, а при начальной инициализации программы - read_settings(void). поэтому если извратиться, то можно выводить на страничку:
plen=fill_tcp_data_int(buf,plen,rstcount/5);
Думаю, у Вас тоже прекратит работу, если будете использовать обработчик событий (нажатие кнопки "Reset manager"). И надо с этим разобраться!
Убирал оптимизацию - код получается 41кБайт, пробовал ставить 1 и 2 - код впритык, но результатов нет.
Кстати, обещанный пинг устройства, при включенном Host watchdog и Log-server:
Вложения
Ping_Manager_of_CCTV.png
Пинг действующего устройства при непосредственном подключении
Ping_Manager_of_CCTV.png (34.98 КБ) 8560 просмотров

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 11 апр 2014, 07:40

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

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 11 апр 2014, 09:40

Пробывал исправить отображение страницы , получил следущее , после получения девайсом
GET /Manager/
устройство как положено отдает главную страницу и шлет
http [FIN, ACK]

,затем браузер сам зачем то 2 раза посылает
GET /Manager/?pg=1
, не могу понять зачем , из за этого получаются еще 2 картинки, на прошивке которую использую я этого нет, скрин во вложении, что делать ума не приложу :(
Вложения
scrin_manage.rar
(57.49 КБ) 298 скачиваний

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 11 апр 2014, 10:02

alexsis_76 писал(а):
Думаю, у Вас тоже прекратит работу, если будете использовать обработчик событий
это как
что то пинги большие
интересно что он там делает
В вашей версии все команды отрабатываются при нажатии на ссылку страницы №7:

Код: Выделить всё

if (page==7) {// reset
RstCount=eeprom_read_byte(&EEMEM_RSTCOUNT);
plen=fill_tcp_data_p(buf,plen,PSTR("<h2>Reset</h2>"));
intToStr(Prm,RstCount ,3);
plen=fill_tcp_data(buf,plen,Prm);
www_server_reply(buf,plen); // send data

HardReset();
При этом страница после рестарта устройства не перезагружается и мы видим предыдущее состояние счетчика сбросов. Если захотим увидеть текущее, то надо обновить страницу, но устройство снова перезагрузиться...
В моем варианте - заходим на страницу и видим текущее состояние счетчика сбросов, нажимаем кнопку и...и либо +5, либо +0...

Пинги - попробую запустить версию 2.1. На сколько помню - там пинг был идеален, правда watchdog не работал как мне надо. А вот в версии 1.0 - каждый 5-й пинг растягивался (чтение T по старому со старыми библиотеками).

По остальному - попробую сниффером вечерком глянуть. Кстати, у вас служба NetAlarm под виндой работает? Вижу сниффером Alarm-сообщения, а вот служба их не читает/распознает - пока не знаю где копать. Склоняюсь уже freebsd поднять на чем-нибудь. В планах к Manager прикрутить smtp клиента на дополнительной странице и слать лог на почту в зависимости от Events.
alexsis_76 писал(а):Пробывал исправить отображение страницы
Давайте мне исходники под вашу распиновку, попробую у себя скомпилировать и выслать hex и eep. Думаю, это все компилятор - в makefile у Вас оптимизация по размеру?
Я сталкивался со страницей в странице когда в обработчике у какого-то if скобки забыл поставить.

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 11 апр 2014, 11:36

Alex_Jet ухожу на двухдневные каникулы :)

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Проблемы при программировании AVR на Си

Сообщение Urbas81 » 11 апр 2014, 11:42

Alex_Jet писал(а): Кстати, у вас служба NetAlarm под виндой работает? Вижу сниффером Alarm-сообщения, а вот служба их не читает/распознает - пока не знаю где копать. Склоняюсь уже freebsd поднять на чем-нибудь. В планах к Manager прикрутить smtp клиента на дополнительной странице и слать лог на почту в зависимости от Events.
Добрый день, буквально несколько дней назад, тоже вспомнил про этот исходник, хочу переделать под свои задачи, когда-то когда только скачал его, запускал посмотреть, у меня работала служба NetAlarm, но тогда один раз проверил и забросил, сейчас решил опять попробовать не работает, но точно помню что работала. Но мне хотелось бы применить в этом устройстве отправку сообщений на сервер на определенный скрипт php, как это сделано в Megad. Посмотрел файлы ip_arp_udp_tcp.c правтически одинаковые, но когда пишу строчку для отправки как в Megad, то при компиляции вылазит ошибка про неизвестную функцию.
Возможно кто-то подскажет как сформировать для данного исходника строчку кода, который бы отсылал на сервер запрос как это делает Megad.

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 11 апр 2014, 12:20

Urbas81 писал(а):Добрый день, буквально несколько дней назад, тоже вспомнил про этот исходник, хочу переделать под свои задачи, когда-то когда только скачал его, запускал посмотреть, у меня работала служба NetAlarm, но тогда один раз проверил и забросил, сейчас решил опять попробовать не работает, но точно помню что работала. Но мне хотелось бы применить в этом устройстве отправку сообщений на сервер на определенный скрипт php, как это сделано в Megad. Посмотрел файлы ip_arp_udp_tcp.c практически одинаковые, но когда пишу строчку для отправки как в Megad, то при компиляции вылазит ошибка про неизвестную функцию.
Возможно кто-то подскажет как сформировать для данного исходника строчку кода, который бы отсылал на сервер запрос как это делает Megad.
Значит где-то какой-то функции не хватает в какой-то библиотеке - не обязательно в ip_arp_udp_tcp.c, это же просто библиотека для отправки сообщения по соответствующему протоколу. Вставьте скрин на что ругается компилятор? Я с MegaD дела не имел, но исходник когда-то смотрел.

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Проблемы при программировании AVR на Си

Сообщение Urbas81 » 11 апр 2014, 13:15

Вот добавил строчку

client_browse_url(PSTR("/test-http.php"),"","",0);

в ветку где идет опрос DS18B20, правда не знаю достаточно ли этих данных для отправки, но если вставляю другие строки, где прописаны &browserresult_callback mac ip, тогда начинает выскакивать про неизвестную ф-ю &browserresult_callback, и так тянется все по цепочке


../main.c:2078: undefined reference to `client_browse_url'

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: Проблемы при программировании AVR на Си

Сообщение THK » 12 апр 2014, 11:13

Осилил не всю тему, поэтому могу написать немного невпопад...
Попробуйте копнуть в сторону регистра MCUSR, если на старте программы анализировать его состояние, сможете не только количество перезагрузок считать, но и узнаете их причину...

Файл "reset.h"

Код: Выделить всё

#ifndef _RST_h_
#define _RST_h_

#include <avr/io.h>

#define	 RST_POWER_ON				0
#define	 RST_HARD_RESET				1
#define	 RST_POWER_MONITOR_RESET	2
#define	 RST_WATCHDOG_RESET			3
#define	 RST_JTAG_RESET				4
#define	 RST_SOFT_RESET				8
#define	 RST_FIRMWARE_UPDATE_RESET	9

uint8_t reset_status( void );

#endif
Файл "reset.c"

Код: Выделить всё

#include "reset.h"

uint8_t reset_status( void )
{
	if ((MCUSR & (1<<PORF))&&(MCUSR & (1<<EXTRF))&&(MCUSR & (1<<BORF))&&(MCUSR & (1<<WDRF))&&(MCUSR & (1<<JTRF)))//выход из загрузчика
	{
		MCUSR &=  ~((1<<PORF)|(1<<EXTRF)|(1<<BORF)|(1<<WDRF)|(1<<JTRF));
		return RST_FIRMWARE_UPDATE_RESET;
	}
	else if (MCUSR & (1<<PORF))			//cброс по питанию
	{
		MCUSR &=  ~(1<<PORF);
		return RST_POWER_ON;
	}
	else if (MCUSR & (1<<EXTRF))		//внешний сброс
	{
		MCUSR &=  ~(1<<EXTRF);
		return RST_HARD_RESET;
	}
	else if (MCUSR & (1<<BORF))			//Brown-out Reset
	{
		MCUSR &=  ~(1<<BORF);
		return RST_POWER_MONITOR_RESET;
	}
	else if (MCUSR & (1<<WDRF))			//сработал watchdog
	{
		MCUSR &=  ~(1<<WDRF);
		return RST_WATCHDOG_RESET;
	}
	else if (MCUSR & (1<<JTRF))			//JTAG Reset
	{
		MCUSR &=  ~(1<<JTRF);
		return RST_JTAG_RESET;
	}
	else								//программный сброс: asm( "jmp 0" )
	{
		return RST_SOFT_RESET;
	}
}
PS "RST_FIRMWARE_UPDATE_RESET" - это мои каракули :), идея не работает, но плотно с ней не занимался.

Alex_Jet
Сообщения: 1251
Зарегистрирован: 12 янв 2014, 18:00
Откуда: Россия, г.Томск

Re: Проблемы при программировании AVR на Си

Сообщение Alex_Jet » 12 апр 2014, 18:27

THK писал(а):Осилил не всю тему, поэтому могу написать немного невпопад...
Попробуйте копнуть в сторону регистра MCUSR, если на старте программы анализировать его состояние, сможете не только количество перезагрузок считать, но и узнаете их причину...
Спасибо за информацию. Почитал в даташите про регистр MCUCSR у ATmega32 - интересная штучка, исходники сохраню обязательно. Однако тут все же необходимо будет счетчиком считать перезагрузки, а он как раз не работает в случае не выхода в основную программу. И где проблема я понять пока не могу. Интересно стало другое - как залезть во фьюзы из программы и перезагрузить контроллер с помощью BOD (вместо 2,7В установить 4,0В)?

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: Проблемы при программировании AVR на Си

Сообщение THK » 13 апр 2014, 00:08

Alex_Jet писал(а):Однако тут все же необходимо будет счетчиком считать перезагрузки, а он как раз не работает в случае не выхода в основную программу. И где проблема я понять пока не могу.
Счетчик естественно нужен, но одно дело, когда вы пытаетесь перед сработкой WD в него что то записать и совсем другое, делать это на старте программы, перед инициализацией периферии.
Alex_Jet писал(а):Интересно стало другое - как залезть во фьюзы из программы и перезагрузить контроллер с помощью BOD (вместо 2,7В установить 4,0В)?
У Вас питание 3.3в и таким образом Вы хотите перезагрузить контроллер? В этом случае контроллер не выйдет из ресета до тех пор, пока напряжение питания не превысит 4 вольта...

Вот как я делаю софт-ресет:

Код: Выделить всё

#define RESET() (((void(*)(void))(char *)0x0000)())	// function for software reset of AVR
И в нужном месте

Код: Выделить всё

RESET();
Правда вот так работает надежнее

Код: Выделить всё

_delay_ms(20);
RESET();
Один раз, при слишком короткой и быстрой программе, после оптимизации и удаления отладочного кода, просто RESET не хотел срабатывать, почему - для меня осталось загадкой. Возможно это были козни компилятора, т.к. даже _delay_ms(1); исправлял ситуацию.

alexsis_76

Re: Проблемы при программировании AVR на Си

Сообщение alexsis_76 » 13 апр 2014, 11:20

Добрый день подискутирую чисто теоретически, программирование завтра ;)
undefined reference to `client_browse_url
'
это из за того что не включен клиент в ip_config.h
что бы подключить добавьте туда
#define WWW_clien
#undef WWW_client
заккоментируйте или уберите
объявите в main
browserresult_callback
функцию возьмите из исходников Андрея
вот она
// --- void browserresult_callback(uint8_t statuscode,uint16_t datapos, uint16_t len)
void browserresult_callback(uint16_t statuscode,uint16_t datapos __attribute__((unused)), uint16_t len __attribute__((unused)))
{
uint16_t i=0;
uint8_t j=0;
uint8_t k=0;

char * srv_rep;
srv_rep = (char *)&(buf[datapos]);
char srv_cmd[30];
for ( i = 0; i < 30; i++ )
srv_cmd = *"";

// Предполагается, что в нормальной ситуации ответ сервера не может содержать более 200 байт
if ( len > 300 )
len = 300;

if (statuscode==200)
{
// Поскольку в этой функции у нас нет информации о том, какой именно вход сработал,
// сбрасываем таймаут по всем входам, предполагая, что если сервер ответил по одному,
// он ответит и по остальным.
for ( i = 0; i < IO_SIZE; i++ )
srv_timeout = 0;

for ( i = 0; i < len; i++ )
{
// Пропускаем все HTTP-заголовки
if ( (*srv_rep == '\r' || *srv_rep == '\n') && k != 2 )
{
srv_rep++;
if ( *srv_rep == '\n' )
k++;
continue;
}

if ( k == 2 )
{
srv_cmd[j] = *srv_rep;
j++;
}

if ( k != 2 )
k = 0;

srv_rep++;
}

if (strlen(srv_cmd) > 0)
port_execute(srv_cmd);
}
// Если ответ сервера не 200, то выполняем команды по умолчанию
else
{
memset(temp, 0, sizeof(temp));
eeprom_read_block (temp, &ee_cmd[cur_input], 11);
if ( temp[0] != (char)255 && strlen(temp) > 0 )
port_execute(temp);

}

send_eth_flag2 = 1;
}

поменяйте в файле
ip_arp_udp_tcp
проекта NetAlarm функцию
client_browse_url
на такую же из
ip_arp_udp_tcp
проекта Андрея
объявите недостающие переменные
о результатах пишите

Ответить