ListenReality 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Всем привет. Проблема такая: Необходимо завести такую переменную, которая после сброса МК по WatchDog сохранит свое значение. Пробовал через static. Но видимо я чего-то глубоко не понимаю. Если переменную не инициализировать, то в ней рандомное значение, которое нельзя никак изменить. (А писать static int i=0 глупо, т.к. оно каждый раз будет обнуляться). Вообще возможно ли это? или МК после сброса по WatchDog затирает память? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mcheb 0 21 января, 2016 Опубликовано 21 января, 2016 (изменено) · Жалоба Компилятор по умолчанию при сбросе устанавливает указатель стека, обнуляет ОЗУ ( .bss область) и затем инициализирует переменные. Напишите свой ResetHandler. Я так пробовал //#pragma vector=RESET_VECTOR //__interrupt void _reset_vector__(void) //{ // WDTCTL = WDTPW | WDTHOLD; // Stop WDT // asm(" mov #0x23fe,r1");// #0x23fe // asm("br #main");//main(); //} //#pragma vector=UNMI_VECTOR /* 0xFFFA User Non-maskable */ //__interrupt void _unmi_vector__(void) //{ // nop(); //// asm("reti"); //} //#pragma vector=SYSNMI_VECTOR /* 0xFFFC System Non-maskable */ //__interrupt void _sysnmi_vector__(void) //{ // nop(); //// asm("reti"); //} // Изменено 21 января, 2016 пользователем mcheb Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Всем привет. Проблема такая: Необходимо завести такую переменную, которая после сброса МК по WatchDog сохранит свое значение. . . . Вообще возможно ли это? или МК после сброса по WatchDog затирает память? В опциях проекта подключите файл линкера не по умолчанию, а с Вашими настройками. (скопировать стандартный в каталог проекта) В шапке лин-файла ( для MSP430F149 это файл lnk430F149.xcl ) есть такое: // segment Restrictions Usage // ------- ------------ -------------------------- // DATA16_I < 10000 Data16 initialized variables // DATA16_Z < 10000 Data16 zero initialized variables // DATA16_N < 10000 Data16 uninitialized variables // DATA16_HEAP < 10000 Data16 heap used by malloc and free // DATA20_I Data20 initialized variables // DATA20_Z Data20 zero initialized variables // DATA20_N Data20 uninitialized variables // DATA20_HEAP Data20 heap used by malloc and free // CSTACK < 10000 Runtime stack обратите внимание на сегмент DATA16_N. Если переменную разместить там, то она не дожна инициализироваться при пергрузке. int my_data @ "MY_DATA_IN_SEG" = 123; MY_DATA_IN_SEG - указать в списке для DATA16_N в lnk430F149.xcl Я сам это не проверял, но кажется в этом направлении. также префикс __no_init __no_init volatile unsigned __READ char U0RXBUF @ 0x0076; итд Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ListenReality 0 22 января, 2016 Опубликовано 22 января, 2016 · Жалоба mcheb, k155la3 Спасибо за ваши ответы. Не вижу файла "lnk430F149.xcl" или подобного для моего МК. Есть только "lnk_msp430f2012.cmd", но содержимое его не похоже на то, что писали вы. MEMORY { SFR : origin = 0x0000, length = 0x0010 PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0 PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100 RAM : origin = 0x0200, length = 0x0080 INFOA : origin = 0x10C0, length = 0x0040 INFOB : origin = 0x1080, length = 0x0040 INFOC : origin = 0x1040, length = 0x0040 INFOD : origin = 0x1000, length = 0x0040 FLASH : origin = 0xF800, length = 0x07E0 INT00 : origin = 0xFFE0, length = 0x0002 INT01 : origin = 0xFFE2, length = 0x0002 INT02 : origin = 0xFFE4, length = 0x0002 INT03 : origin = 0xFFE6, length = 0x0002 INT04 : origin = 0xFFE8, length = 0x0002 INT05 : origin = 0xFFEA, length = 0x0002 INT06 : origin = 0xFFEC, length = 0x0002 INT07 : origin = 0xFFEE, length = 0x0002 INT08 : origin = 0xFFF0, length = 0x0002 INT09 : origin = 0xFFF2, length = 0x0002 INT10 : origin = 0xFFF4, length = 0x0002 INT11 : origin = 0xFFF6, length = 0x0002 INT12 : origin = 0xFFF8, length = 0x0002 INT13 : origin = 0xFFFA, length = 0x0002 INT14 : origin = 0xFFFC, length = 0x0002 RESET : origin = 0xFFFE, length = 0x0002 } /****************************************************************************/ /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */ /****************************************************************************/ SECTIONS { .bss : {} > RAM /* GLOBAL & STATIC VARS */ .data : {} > RAM /* GLOBAL & STATIC VARS */ .sysmem : {} > RAM /* DYNAMIC MEMORY ALLOCATION AREA */ .stack : {} > RAM (HIGH) /* SOFTWARE SYSTEM STACK */ .text : {} > FLASH /* CODE */ .cinit : {} > FLASH /* INITIALIZATION TABLES */ .const : {} > FLASH /* CONSTANT DATA */ .cio : {} > RAM /* C I/O BUFFER */ .pinit : {} > FLASH /* C++ CONSTRUCTOR TABLES */ .init_array : {} > FLASH /* C++ CONSTRUCTOR TABLES */ .mspabi.exidx : {} > FLASH /* C++ CONSTRUCTOR TABLES */ .mspabi.extab : {} > FLASH /* C++ CONSTRUCTOR TABLES */ .infoA : {} > INFOA /* MSP430 INFO FLASH MEMORY SEGMENTS */ .infoB : {} > INFOB .infoC : {} > INFOC .infoD : {} > INFOD /* MSP430 INTERRUPT VECTORS */ .int00 : {} > INT00 .int01 : {} > INT01 PORT1 : { * ( .int02 ) } > INT02 type = VECT_INIT PORT2 : { * ( .int03 ) } > INT03 type = VECT_INIT USI : { * ( .int04 ) } > INT04 type = VECT_INIT ADC10 : { * ( .int05 ) } > INT05 type = VECT_INIT .int06 : {} > INT06 .int07 : {} > INT07 TIMERA1 : { * ( .int08 ) } > INT08 type = VECT_INIT TIMERA0 : { * ( .int09 ) } > INT09 type = VECT_INIT WDT : { * ( .int10 ) } > INT10 type = VECT_INIT .int11 : {} > INT11 .int12 : {} > INT12 .int13 : {} > INT13 NMI : { * ( .int14 ) } > INT14 type = VECT_INIT .reset : {} > RESET /* MSP430 RESET VECTOR */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 33 22 января, 2016 Опубликовано 22 января, 2016 · Жалоба Так вы бы сразу указали, что не IARом пользуетесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ListenReality 0 22 января, 2016 Опубликовано 22 января, 2016 · Жалоба Так вы бы сразу указали, что не IARом пользуетесь. А можете подсказать как в CCS решить эту проблему ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 22 января, 2016 Опубликовано 22 января, 2016 (изменено) · Жалоба А можете подсказать как в CCS решить эту проблему ? ps - это не есть проблема :) В CCS не работал. Наверняка есть аналогичные ф-ии. Почитайте раздел помощи, нечто вроде "pragma directive" для CCS Там могут быть директивы - команды препроцессору компилятора, в каких сегментах размещать данную переменную или модуль в целом. Также - работа с абсолютными адресами. (например, вектора прерываний всегда размещаются по указанным абс. адресам) "Покурите" h-файлы CCS. Изменено 22 января, 2016 пользователем k155la3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 30 января, 2016 Опубликовано 30 января, 2016 · Жалоба Но видимо я чего-то глубоко не понимаю. Если переменную не инициализировать, то в ней рандомное значение, которое нельзя никак изменить. Вообще возможно ли это? Возможно - что? Кажется, вы каких-то чудес хотите - чтобы переменная не инициализировалась, но чтобы в ней не было рандомного значения. "Горячий лед", "сухая вода" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 31 января, 2016 Опубликовано 31 января, 2016 · Жалоба обратите внимание на сегмент DATA16_N. Если переменную разместить там, то она не дожна инициализироваться при пергрузке. Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения. А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте??? Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции. Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
E.V.G. 0 31 января, 2016 Опубликовано 31 января, 2016 · Жалоба В компиляторе IAR есть такая функция - int __low_level_init(void). Посмотрите, похоже, это ваш случай. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 31 января, 2016 Опубликовано 31 января, 2016 · Жалоба Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения. А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте??? Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции. Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен. :) нечто вроде RANDOM_INIT_SEGMENT Случайное значение попадает в SRAM процессора только при холодном старте (и то не факт). И при выходе из какогонибудь LPM5. Это значение может быть случайно-случайным или случайно-постоянным. В общем, эта тема для меня еще недостаточно раскурена. Буду прикручивать к проекту работу WD - тогда разберемся. (в RAM планирую сохранять данные причине сработки WDT и состоянии программы) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 1 февраля, 2016 Опубликовано 1 февраля, 2016 · Жалоба Случайное значение попадает в SRAM процессора только при холодном старте (и то не факт). И при выходе из какогонибудь LPM5. Это понятно. Но раз ТС пишет, что у него переменная принимает случайное значение, то советы перенести её в неинициализируемую секцию излишни - она и так уже там. Ну только если она не находится в какой-то спец.секции рандомно инициализируемой. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ListenReality 0 2 февраля, 2016 Опубликовано 2 февраля, 2016 · Жалоба Возможно - что? Кажется, вы каких-то чудес хотите - чтобы переменная не инициализировалась, но чтобы в ней не было рандомного значения. "Горячий лед", "сухая вода" ? Вы видимо не правильно поняли. 1) Включение МК по питанию(сигнал POR и PUC) 2) Сброс МК по WatchDog(только сигнал PUC). Программа начинает выполняться с начала, но есть бит, который указывает, что мы сбросились именно по WatchDog. if((IFG1&WDTIFG)==WDTIFG)//сбросились по собаке { IFG1&=~WDTIFG;//обнуляем флаг countWatchDog++; } Поставлю вопрос тогда так. Где и как мне объявить переменную countWatchDog, чтобы: 1) Если включились по питанию, countWatchDog=0; 2) Если сброс по WatchDog, то countWatchDog++; По сути нужно посчитать кол-во сбросов по WatchDog. Пробовал: Объявлял переменную за функцией main по-разному: int countWatchDog; static int countWatchDog; При этом main выглядит примерно так: int main(void) { /*настройка сторожевого таймера*/ WDTCTL = WDTPW // ключ защиты + WDTCNTCL // Обнуляем таймер + WDTSSEL; // 0 - тактовый сигнал от SMCLK, 1 - ACLK IE1 = WDTIE;// разрешаем прерывания от сторожевого таймера BCSCTL3 = LFXT1S_2;//задаем для ACLK источник тактирования VLO if((IFG1&WDTIFG)!=WDTIFG)//по питанию { countWatchDog=0; } if((IFG1&WDTIFG)==WDTIFG)//сбросились по собаке { IFG1&=~WDTIFG;//обнуляем флаг countWatchDog++; } } При этом в случае, когда "int countWatchDog;" переменная всегда = 0 В случае, когда "static int countWatchDog;" переменная всегда равна 0х261. И в отладчике, после прохождения строчки "countWatchDog=0;" - значение переменной не меняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 2 февраля, 2016 Опубликовано 2 февраля, 2016 · Жалоба При этом в случае, когда "int countWatchDog;" переменная всегда = 0Так и должно быть. В случае, когда "static int countWatchDog;" переменная всегда равна 0х261. И в отладчике, после прохождения строчки "countWatchDog=0;" - значение переменной не меняется.Вот это странно. Должна быть ==0. А как Вы отладчиком подключаетесь? Он сброс на МК выставляет при подключении? Возможно, что он подключается на лету, без сброса, тогда переменная содержит значение, присвоенное её в ходе выполнения ПО. И вообще контролировать надо не отладчиком, а без него. Например - вывести значение переменной в UART при старте. Как правильно объявить переменную - Вам уже сказали. Как сделать это в Вашем компиляторе - не знаю, а в IAR например: static __root __no_init int var @ ".myNoInitSection"; Потом в командном файле компоновщика говорите компоновать секцию .myNoInitSection в отдельный регион памяти, который не надо инитить нулями. А можете подсказать как в CCS решить эту проблему ? В CCS я делал так (это для ARM926 ядра), в файле .cmd: #define RAM_SDRAM_ARM_NC_RW_BEGIN 0xC0010000 #define RAM_SDRAM_ARM_NC_RW_LEN 0x000E0000 MEMORY { PAGE 0: //!<RAM ... RAM_SDRAM_ARM_NC_RW (RWX): o = RAM_SDRAM_ARM_NC_RW_BEGIN l = RAM_SDRAM_ARM_NC_RW_LEN //!<read-write noncached SDRAM is accessible only ARM } SECTIONS { ... .mmuTTable > RAM_SDRAM_ARM_NC_RW, type = NOINIT } Это легко узнаётся из описания компоновщика CCS, если конечно хотя-бы попытаться его открыть и почитать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ListenReality 0 10 марта, 2016 Опубликовано 10 марта, 2016 · Жалоба Спасибо всем за помощь. Впредь буду детальнее читать Help На всякий случай оставлю пример. Программа считает количество WatchDog'ов #pragma NOINIT (x ); int x; int main(void) { /*настройка сторожевого таймера*/ WDTCTL = WDTPW // ключ защиты //+ WDTNMI // 0 - Вход аппаратного сброса, 1 - вход прервания //+ WDTTMSEL // 0 - режим сторожевого таймера, 1 - интервальный таймер + WDTCNTCL // Обнуляем таймер + WDTSSEL; // 0 - тактовый сигнал от SMCLK, 1 - ACLK //+ WDTIS0; //+ WDTIS1; IE1 = WDTIE;// разрешаем прерывания от сторожевого таймера BCSCTL3 = LFXT1S_2;//задаем для ACLK источник тактирования VLO DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ; if((IFG1&WDTIFG)==WDTIFG)//сбросились по собаке { IFG1&=~WDTIFG;//обнуляем флаг x++; } else x=0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться