Цитата(Shread @ Dec 10 2010, 16:47)

Разберитесь с тем что у вас включено из прерываний, а что нет, после чего добавьте обработчики тех прерываний, которые включены. Просто так "шляться" программа в 2хх не может - в этом семействе есть аппаратный модуль сброса на этот случай.
да вроде всё что нужно включено, всё что не нужно выключено. Может какой нибудь прерывание не нужное раз в 3 дня включается и процесс постоянно ныряет в него около минуты. потом опять всё нормально. Но я ме могу понять где процесс находится? в каком прерывании или где застревает в мэйне?
И всё же, есть у кого-нибудь опыт трассировки процесса? Может кто-нибудь подсказать в какую сторону глянуть?
Цитата
Исходник обработчика прерывания приведите. Мнится мне, что именно там собака порылась.
Ну тут адский код. Черт ногу сломит. Но мож на вскидку кто увидет потенциальную багу.
Код
#pragma vector=TIMERB1_VECTOR
__interrupt void TimerB_Int1(void) {
switch(__even_in_range(TBIV, 14)) {
case 2: break; //Прерывание по модулю сравнения 1 (Высший приоритет)
case 4: TBCCTL2=0; InvalidIntCNT++; return;
case 6: TBCCTL3=0; InvalidIntCNT++; return;
case 8: TBCCTL4=0; InvalidIntCNT++; return;
case 10: TBCCTL5=0; InvalidIntCNT++; return;
case 12: TBCCTL6=0; InvalidIntCNT++; return;
case 14: Tic2sCounter++; return; //Прерывание по переполнению таймера B. Период 32768/65536=0.5 Гц (2 с)
default: return;
}
TBCCR1+=Value32kHz1sCCR;
//Цифровая коррекция хода часов
//Изменение на 3 такта каждые 79 сек дает 0,1 сек/сут
if(++DTC79Cnt>=79) {
DTC79Cnt=0;
TBCCR1-=(EEPROM.RTC_Correct*3)-60; //60 - отставание на 2 сек/сут
}
//Если нужно, считаем длительность заряда АКБ
if(ChargeCnt) if(gFlags.ExtPower) {
if(++ChargeSticks>4) ChargeSticks=0;
if(!--ChargeCnt) EndCharge();
}
if(P3State != P3_Off) {
//Если нужно, считаем секундный тайм-аут
if(Sec_TimeOut) --Sec_TimeOut;
//Если нужно, проверим время автовыключения
if(gFlags.ExtPower) {AutoOffCnt=EEPROM.AutoOff; BLAutoOffCnt=EEPROM.BLAutoOff;}
else{
if(AutoOffCnt) if(!--AutoOffCnt) gFlags.AutoOff=1;
if(BLAutoOffCnt) if(!--BLAutoOffCnt) InitBackLight();
}
//Синхронизируем индикацию с часами
if((Cnt20ms>1) && (Cnt20ms<18)) Cnt20ms++;
if((Cnt1S>1) && (Cnt1S<48)) Cnt1S++;
}
//Если идет ожидание окончания измерения, считать секунды
if(MeasWait) MeasWait--;
//Если часы остановлены, выход
if(gFlags.ClockStop) return;
_EINT();
//Прибавление секунды к текущему времени
//NewSec++;
if( GsmCheckTimeOut != 0)
--GsmCheckTimeOut;
++CurDT.Sec;
if((CurDT.Sec >= 1) && gFlags.TimeBeginConnect)
{
gFlags.TimeBeginConnect = 0;
//PORT_UART_PC &= ~Bit_UART_PC_FOF;//порт сбросим для наблюдения в осцилографе
}
#ifdef RADIO
if(CurDT.Sec == 58)
{//включим питание RFD21733
UARTAdOn();
Power4On();
}
#endif
//if(CurDT.Sec == 3)///!!!
// CurDT.Sec = 56;
if(CurDT.Sec>59) {
CurDT.Sec=0;
//Если есть нормальное питание (EP2), проснуться
if(!PowerIsLi())
{
_BIC_SR_IRQ(LPM3_bits);
InitUART1();
IdleDelay=1;
}
BCSCTL1 &= ~XT2OFF;
BCSCTL2 |= SELS;
gFlags.TimeBeginConnect = 1;
gFlags.isTest = 1;
BeginSysTimer(); //сброс дебажного счетчика
gFlags.Synchronization = 1;
if(--timeCheckBattary == 0)
{
gFlags.CheckBattary = 1; // флаг проверки батареи
timeCheckBattary = 10;
}
//PORT_UART_PC |= Bit_UART_PC_FOF;
if(++CurDT.Min>59) {
CurDT.Min=0;
if(++CurDT.Hour>23) {
CurDT.Hour=0; CurDT.Day++;
if(CurDT.Day>CalcDayInMonth(&CurDT)) { //Месяц закончился
CurDT.Day=1;
if(++CurDT.Month>12) {
CurDT.Month=1;
CurDT.Year++;
}
}
}
}
}
//Проверка будильника
if((AlarmAct != AA_Off) && //Будильник включен,
(AlarmAct != AA_ProcStop) && //Не требуется окончание процесса
(*(WORD*)&AlarmDT.Sec==*(WORD*)&CurDT.Sec) && //..секунды, минуты совпадают,..
(*(WORD*)&AlarmDT.Hour==*(WORD*)&CurDT.Hour) && //..час, день,..
(*(WORD*)&AlarmDT.Month==*(WORD*)&CurDT.Month)) //..месяц, год
{
//Будильник сработал, установить флаг
regFlags.Alarm=1; MeasStep=MS_Wait;
//Если есть нормальное питание (EP2), проснуться
if(!PowerIsLi()) {_BIC_SR_IRQ(LPM3_bits); IdleDelay=1;}
//При отсутствии нормального питания установить флаг потенциальной ошибки
else {InitPower(); regFlags.PotencError=1;}
}
//Если при отсутствии нормального питания (EP2) разрешено включение, разобраться
if((IE_PowerIn & Bit_PowerIn) && PowerIsLi()) {InitPower(); _BIC_SR_IRQ(LPM3_bits); regFlags.PotencError=1;}
//Программный WDT
if((P3State != P3_Off) && !--SoftWDT) {regFlags.PotencError=1; regFlags.ResultWrite=0; WarmReset();}
asm("nop");
msTime[0] = EndSysTimer(); фиксация дебажного счетчика
}
А вот еще возник вопрос, может здесь грабля лежит. Как работает "многопоточность" в мсп430 + иар?
например есть код и есть обработчик прерывания
Код
///main.cpp
bool happy;
int main()
{
happy = false;
while(1)
{
if(happy)
{
divHappySmb();
happy = false;
}
}
}
//обработчик прерывания
#pragma vector=TIMERB1_VECTOR
__interrupt void TimerB_Int1()
{
happy = checkMyMoney();
}
так вот, крутимся постоянно в main. по прерываниям порадаем в TimerB_Int1(). Можно сказать что тут 2 потока - главный и обработчик прерывания. Но ни какой системы синхранизации. Допустим мэйне мы читаем или пишим happy, в это время происходит прерывание. прцессор передает управление обработчику, сохраняется "портрет" состояния мэин и выполняется обработчик TimerB_Int1(). Потом востанавливается картина и передается управление мэйну. Так вот получается как-бы одновременное обращение из двух "потоков" к переменной happy. Не косяк ли это? может ли оператор "=" быть прерван по среди выполнения?
Понятно, что оператор "=" для bool скорее всего одна инструкция и её прервать на середине невозможно, но если happy это int, или какойнибудь тяжелый class MyHappyClass? Нужно ли защищять переменные в мэйне, которые используются в прерывании, типа
Код
int main()
{
happy = false;
while(1)
{
dInt();//запрет прерывания
if(happy)
{
eInt();//разрешение прерывания
divHappySmb();
dInt();//запрет прерывания
happy = false;
}
eInt();//разрешение прерывания
}
}