реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> МК после сброса по WatchDog
ListenReality
сообщение Jan 21 2016, 09:47
Сообщение #1


Участник
*

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



Всем привет.

Проблема такая: Необходимо завести такую переменную, которая после сброса МК по WatchDog сохранит свое значение.

Пробовал через static. Но видимо я чего-то глубоко не понимаю. Если переменную не инициализировать, то в ней рандомное значение, которое нельзя никак изменить. (А писать static int i=0 глупо, т.к. оно каждый раз будет обнуляться).

Вообще возможно ли это? или МК после сброса по WatchDog затирает память?
Go to the top of the page
 
+Quote Post
mcheb
сообщение Jan 21 2016, 10:49
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jan 21 2016, 14:39
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 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;
итд




Go to the top of the page
 
+Quote Post
ListenReality
сообщение Jan 22 2016, 03:07
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 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         */
}
Go to the top of the page
 
+Quote Post
Obam
сообщение Jan 22 2016, 07:56
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Так вы бы сразу указали, что не IARом пользуетесь.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ListenReality
сообщение Jan 22 2016, 08:35
Сообщение #6


Участник
*

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



Цитата(Obam @ Jan 22 2016, 14:56) *
Так вы бы сразу указали, что не IARом пользуетесь.


А можете подсказать как в CCS решить эту проблему ?
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jan 22 2016, 10:50
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(ListenReality @ Jan 22 2016, 12:35) *
А можете подсказать как в CCS решить эту проблему ?


ps - это не есть проблема sm.gif

В CCS не работал. Наверняка есть аналогичные ф-ии.
Почитайте раздел помощи, нечто вроде "pragma directive" для CCS
Там могут быть директивы - команды препроцессору компилятора, в каких сегментах
размещать данную переменную или модуль в целом.
Также - работа с абсолютными адресами.
(например, вектора прерываний всегда размещаются по указанным абс. адресам)
"Покурите" h-файлы CCS.

Сообщение отредактировал k155la3 - Jan 22 2016, 10:51
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 30 2016, 18:57
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(ListenReality @ Jan 21 2016, 12:47) *
Но видимо я чего-то глубоко не понимаю. Если переменную не инициализировать, то в ней рандомное значение, которое нельзя никак изменить.

Вообще возможно ли это?

Возможно - что?
Кажется, вы каких-то чудес хотите - чтобы переменная не инициализировалась, но чтобы в ней не было рандомного значения.
"Горячий лед", "сухая вода" ?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 31 2016, 07:46
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(k155la3 @ Jan 21 2016, 20:39) *
обратите внимание на сегмент DATA16_N.
Если переменную разместить там, то она не дожна инициализироваться при пергрузке.

Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения.
А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте???
Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции.
Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен.
Go to the top of the page
 
+Quote Post
E.V.G.
сообщение Jan 31 2016, 09:51
Сообщение #10


Участник
*

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



В компиляторе IAR есть такая функция - int __low_level_init(void). Посмотрите, похоже, это ваш случай.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jan 31 2016, 12:24
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(jcxz @ Jan 31 2016, 10:46) *
Это конечно всё правильно, только прочитайте внимательнее что именно пишет ТС. А пишет он, что неинициализированные переменные у него после указанного сброса принимают рандомные значения.
А теперь вопрос - какие именно секции линкер указывает как заполняемые рандомно при старте???
Я что-то не слышал о таком, чтобы стандартный стартап-код заполнял что-то рандомно. Обычно он обнуляет или не обнуляет (ну или максимум - заполняет неким шаблоном) секции.
Так что сначала копать надо в сторону выяснения - откуда берутся эти рандомные значения? Стартап-код генерить их не должен.


sm.gif нечто вроде RANDOM_INIT_SEGMENT
Случайное значение попадает в SRAM процессора только при холодном старте (и то не факт). И при выходе из какогонибудь LPM5.
Это значение может быть случайно-случайным или случайно-постоянным.
В общем, эта тема для меня еще недостаточно раскурена. Буду прикручивать к проекту работу WD - тогда разберемся.
(в RAM планирую сохранять данные причине сработки WDT и состоянии программы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2016, 05:34
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(k155la3 @ Jan 31 2016, 18:24) *
Случайное значение попадает в SRAM процессора только при холодном старте (и то не факт). И при выходе из какогонибудь LPM5.

Это понятно. Но раз ТС пишет, что у него переменная принимает случайное значение, то советы перенести её в неинициализируемую секцию излишни - она и так уже там.
Ну только если она не находится в какой-то спец.секции рандомно инициализируемой. sm.gif
Go to the top of the page
 
+Quote Post
ListenReality
сообщение Feb 2 2016, 02:43
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 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;" - значение переменной не меняется.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 2 2016, 03:49
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 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, если конечно хотя-бы попытаться его открыть и почитать...
Go to the top of the page
 
+Quote Post
ListenReality
сообщение Mar 10 2016, 03:43
Сообщение #15


Участник
*

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



Спасибо всем за помощь. Впредь буду детальнее читать Help blush.gif

На всякий случай оставлю пример. Программа считает количество 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;
}


Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 22:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01526 секунд с 7
ELECTRONIX ©2004-2016