|
2 страниц
1 2 >
|
 |
Ответов
(1 - 17)
|
Jan 21 2016, 10:49
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602

|
Компилятор по умолчанию при сбросе устанавливает указатель стека, обнуляет ОЗУ ( .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"); //} //
Сообщение отредактировал mcheb - Jan 21 2016, 10:52
|
|
|
|
|
Jan 21 2016, 14:39
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(ListenReality @ Jan 21 2016, 12:47)  Всем привет.
Проблема такая: Необходимо завести такую переменную, которая после сброса МК по 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; итд
|
|
|
|
|
Jan 22 2016, 03:07
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 2-04-15
Из: Железногорск
Пользователь №: 86 023

|
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 */ }
|
|
|
|
|
Jan 22 2016, 08:35
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 2-04-15
Из: Железногорск
Пользователь №: 86 023

|
Цитата(Obam @ Jan 22 2016, 14:56)  Так вы бы сразу указали, что не IARом пользуетесь. А можете подсказать как в CCS решить эту проблему ?
|
|
|
|
|
Jan 22 2016, 10:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(ListenReality @ Jan 22 2016, 12:35)  А можете подсказать как в CCS решить эту проблему ? ps - это не есть проблема  В CCS не работал. Наверняка есть аналогичные ф-ии. Почитайте раздел помощи, нечто вроде "pragma directive" для CCS Там могут быть директивы - команды препроцессору компилятора, в каких сегментах размещать данную переменную или модуль в целом. Также - работа с абсолютными адресами. (например, вектора прерываний всегда размещаются по указанным абс. адресам) "Покурите" h-файлы CCS.
Сообщение отредактировал k155la3 - Jan 22 2016, 10:51
|
|
|
|
|
Jan 30 2016, 18:57
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(ListenReality @ Jan 21 2016, 12:47)  Но видимо я чего-то глубоко не понимаю. Если переменную не инициализировать, то в ней рандомное значение, которое нельзя никак изменить.
Вообще возможно ли это? Возможно - что? Кажется, вы каких-то чудес хотите - чтобы переменная не инициализировалась, но чтобы в ней не было рандомного значения. "Горячий лед", "сухая вода" ?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jan 31 2016, 07:46
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(k155la3 @ Jan 21 2016, 20:39)  обратите внимание на сегмент DATA16_N. Если переменную разместить там, то она не дожна инициализироваться при пергрузке. Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения. А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте??? Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции. Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен.
|
|
|
|
|
Jan 31 2016, 09:51
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175

|
В компиляторе IAR есть такая функция - int __low_level_init(void). Посмотрите, похоже, это ваш случай.
|
|
|
|
|
Jan 31 2016, 12:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(jcxz @ Jan 31 2016, 10:46)  Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения. А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте??? Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции. Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен.  нечто вроде RANDOM_INIT_SEGMENT Случайное значение попадает в SRAM процессора только при холодном старте (и то не факт). И при выходе из какогонибудь LPM5. Это значение может быть случайно-случайным или случайно-постоянным. В общем, эта тема для меня еще недостаточно раскурена. Буду прикручивать к проекту работу WD - тогда разберемся. (в RAM планирую сохранять данные причине сработки WDT и состоянии программы)
|
|
|
|
|
Feb 2 2016, 02:43
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 2-04-15
Из: Железногорск
Пользователь №: 86 023

|
Цитата(Dog Pawlowa @ Jan 31 2016, 01:57)  Возможно - что? Кажется, вы каких-то чудес хотите - чтобы переменная не инициализировалась, но чтобы в ней не было рандомного значения. "Горячий лед", "сухая вода" ? Вы видимо не правильно поняли. 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;" - значение переменной не меняется.
|
|
|
|
|
Feb 2 2016, 03:49
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ListenReality @ Feb 2 2016, 08:43)  При этом в случае, когда "int countWatchDog;" переменная всегда = 0 Так и должно быть. Цитата(ListenReality @ Feb 2 2016, 08:43)  В случае, когда "static int countWatchDog;" переменная всегда равна 0х261. И в отладчике, после прохождения строчки "countWatchDog=0;" - значение переменной не меняется. Вот это странно. Должна быть ==0. А как Вы отладчиком подключаетесь? Он сброс на МК выставляет при подключении? Возможно, что он подключается на лету, без сброса, тогда переменная содержит значение, присвоенное её в ходе выполнения ПО. И вообще контролировать надо не отладчиком, а без него. Например - вывести значение переменной в UART при старте. Как правильно объявить переменную - Вам уже сказали. Как сделать это в Вашем компиляторе - не знаю, а в IAR например: static __root __no_init int var @ ".myNoInitSection"; Потом в командном файле компоновщика говорите компоновать секцию .myNoInitSection в отдельный регион памяти, который не надо инитить нулями. Цитата(ListenReality @ Jan 22 2016, 14:35)  А можете подсказать как в 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, если конечно хотя-бы попытаться его открыть и почитать...
|
|
|
|
|
Mar 10 2016, 03:43
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 2-04-15
Из: Железногорск
Пользователь №: 86 023

|
Спасибо всем за помощь. Впредь буду детальнее читать 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; }
|
|
|
|
|
Apr 24 2016, 07:08
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(ListenReality @ Jan 21 2016, 12:47)  Проблема такая: Необходимо завести такую переменную, которая после сброса МК по WatchDog сохранит свое значение. Вообще возможно ли это? или МК после сброса по WatchDog затирает память? Меня тоже интересует сохраняются ли значения в RAM памяти после сброса сторожевым таймером именно в тот момент, когда уже произошел сброс и МК начал выполнять первую инструкцию, расположенную по адресу вектора сброса.
Сообщение отредактировал d7d1cd - Apr 24 2016, 07:13
|
|
|
|
|
Apr 24 2016, 11:41
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(d7d1cd @ Apr 24 2016, 10:08)  Меня тоже интересует сохраняются ли значения в RAM памяти после сброса сторожевым таймером именно в тот момент, когда уже произошел сброс и МК начал выполнять первую инструкцию, расположенную по адресу вектора сброса. Никакого вида сбросы не влияют на содержимое оперативной памяти. На ее содержимое влияет только напряжение питания. Есть минимальное напряжение, когда ОЗУ еще сохраняется. Из мануала на MSP430F2xx : Цитата V(RAMh) RAM retention supply voltage (CPU halted) 1.6 V This parameter defines the minimum supply voltage VCC when the data in RAM remains unchanged. No program execution should happen during this supply voltage condition. Если ОЗУ слетело, значит или питание пропадало, или процессор что-то туда записал согласно программе
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|