253 lines
7.9 KiB
C
253 lines
7.9 KiB
C
/*!
|
|
Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
\file V_event_log.c
|
|
\brief Ñîõðàíåíèå ñîáûòèé è âðåìåíè âîçíèêíîâåíèß â ÝíÎÇÓ
|
|
Èñïîëüçóåòñß äðàéâåð ðàáîòû ñ ýíåðãîíåçàâèñèìîé ïàìßòüþ
|
|
Ïîýòîìó âûçîâ init(); äîëæåí áûòü ïîñëå èíèöèàëèçàöèè ÝíÎÇÓ
|
|
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
|
|
\version v 1.0 2009_01_20
|
|
|
|
*/
|
|
|
|
/** \addtogroup W_event_log */
|
|
/*@{*/
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <main.h>
|
|
|
|
|
|
//!<Ïðîòîêîëèðîâàíèå àâàðèé
|
|
|
|
//Ïðîöåäóðû çàïèñè ñîáûòèé â ýíåðãîíåçàâèñèìóþ ôëåøêó î÷åíü äîëãèå (ñâÿçàíî ñ òàéìèíãàìè I2C-èíòåðôåéñà
|
|
//è áîëüøèì îáúåìîì äàííûõ, ïåðåäàâàåìûì ïî I2C â ïðîöåññå çàïèñè).
|
|
//Ïîýòîìó àëãîðèòì ðàáîòû òàêîé:
|
|
//Åñëè íóæíî ïðî÷èòàòü àâàðèþ [Logger_Event_Read] (ñðî÷íî ñ÷èòûâàòü àâàðèþ èç áàíêà íå òðåáóåòñÿ) -
|
|
//îíà ÷èòàåòñÿ â ôîíîâîì öèêëå ïðÿìèêîì èç ÝíÎÇÓ.
|
|
//Åñëè íóæíî çàïèñàòü àâàðèþ â áàíê [Logger_Event_Write] - â ïðåðûâàíèè (íàïðèìåð, 1ìñ) äàííûå àâàðèè ïèøóòñÿ â FIFO;
|
|
//çàòåì â ôîíîâîì öèêëå [Logger_Background_Calc] àâàðèè ÷èòàþòñÿ èç FIFO [Event_FIFO_Read]
|
|
//(ïî îäíî çà 1 ôîíîâûé öèêë) è ïèøóòñÿ â ÝíÎÇÓ.
|
|
|
|
|
|
//ïðî÷èòàòü ñîáûòèå èç FIFO (äëÿ äàëüíåéøåé çàïèñè â ÝíÎÇÓ).
|
|
Uint16 Event_FIFO_Read(TEventFIFO* p,TEvent* ev)
|
|
{
|
|
if (p->busy_flag > 0) return EVENT_FIFO_BUSY;
|
|
//âûñòàâëßåì ôëàæîê ðàáîòû ñ FIFO
|
|
p->busy_flag = 1;
|
|
if (p->number_of_msgs == 0)
|
|
{
|
|
//îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO
|
|
p->busy_flag = 0;
|
|
return EVENT_FIFO_EMPTY;
|
|
}
|
|
//÷èòàåì äàííûå èç FIFO
|
|
ev->ev_code = p->msg_array[(p->read_ptr)].ev_code;
|
|
ev->ev_time = p->msg_array[(p->read_ptr)].ev_time;
|
|
ev->ev_num = p->msg_array[(p->read_ptr)].ev_num;
|
|
//ïîäãîòîâêà FIFO ê ñëåäóþùåìó âûçîâó
|
|
p->read_ptr++;
|
|
if (p->read_ptr >= p->size) p->read_ptr = 0;
|
|
p->number_of_msgs--;
|
|
//îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO
|
|
p->busy_flag = 0;
|
|
return EVENT_FIFO_SUCCESSFUL;
|
|
}
|
|
|
|
|
|
|
|
//Çàïèñàòü ñîáûòèå â FIFO (âûçûâàåòñÿ â Logger_Event_Write, â ïðåðûâàíèè)
|
|
Uint16 Event_FIFO_Write(TEventFIFO* p,TEvent* ev)
|
|
{
|
|
if (p->busy_flag > 0) return EVENT_FIFO_BUSY;
|
|
//âûñòàâëßåì ôëàæîê ðàáîòû ñ FIFO
|
|
p->busy_flag = 1;
|
|
if (p->number_of_msgs == p->size)
|
|
{
|
|
//îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO
|
|
p->busy_flag = 0;
|
|
return EVENT_FIFO_FULL;
|
|
}
|
|
//çàïèñûâàåì äàííûå â FIFO
|
|
p->msg_array[(p->write_ptr)].ev_code = ev->ev_code;
|
|
p->msg_array[(p->write_ptr)].ev_time = ev->ev_time;
|
|
p->msg_array[(p->write_ptr)].ev_num = ev->ev_num;
|
|
//ïîäãîòîâêà FIFO ê ñëåäóþùåìó âûçîâó
|
|
p->write_ptr++;
|
|
if (p->write_ptr >= p->size)p->write_ptr = 0;
|
|
p->number_of_msgs++;
|
|
//îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO
|
|
p->busy_flag = 0;
|
|
return EVENT_FIFO_SUCCESSFUL;
|
|
}
|
|
|
|
//èíèöèàëèçàöèÿ (åñëè áàíê çàáèò ìóñîðîì - âñå äàííûå FFFF, î÷èùàåì åãî)
|
|
void Logger_Init(TLogger* p,Uint16 BS,Uint16 SA,Uint32* tptr)
|
|
{
|
|
TEvent tmp;
|
|
Uint16 i;
|
|
Uint16 last_log_num = 0;
|
|
Uint16 last_log_index = 0;
|
|
//èíèöèàëèçèðóåì âíóòðåííèå ïåðåìåííûå
|
|
p->SPI_buf_size = BS;
|
|
p->SPI_start_addr = SA;
|
|
p->time_ptr = tptr;
|
|
|
|
//äàëåå íóæíî ïðîñêàíèðîâàòü áóôåð â ÝíÎÇÓ - íàéòè ïîñëåäíþþ
|
|
UserMem.MemStartAddr = p->SPI_start_addr;
|
|
UserMem.data_length = 0;
|
|
for (i=0;i<p->SPI_buf_size;i++)
|
|
{
|
|
//÷èòàåì íîìåð
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_num);
|
|
UserMem.data_length = LOG_NUM_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
//÷èòàåì âðåìß
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_time);
|
|
UserMem.data_length = LOG_TIME_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
//÷èòàåì êîä
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_code);
|
|
UserMem.data_length = LOG_CODE_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
|
|
//äåëàåì íåîáõîäèìûå ïðîâåðêè
|
|
//åñëè âñå ïîëß 0xFFFF, òî ÷èñòèì âñþ ïàìßòü
|
|
if ((tmp.ev_num == 0xFFFF) && (tmp.ev_time == 0xFFFFFFFF) && (tmp.ev_code == 0xFFFF))
|
|
{
|
|
//÷èñòèì
|
|
p->clear(p);
|
|
//èíèöèàëèçèðóåì ïåðåìåííûå
|
|
p->INTERNAL_last_log_num = 0;
|
|
p->INTERNAL_last_log_index = 0;
|
|
return;
|
|
}
|
|
//èùåì ïîñëåäíþþ çàïèñü
|
|
if (last_log_num < tmp.ev_num)
|
|
{
|
|
last_log_num = tmp.ev_num;
|
|
last_log_index = i;
|
|
}
|
|
}
|
|
p->INTERNAL_last_log_num = last_log_num;
|
|
p->INTERNAL_last_log_index = last_log_index;
|
|
}
|
|
|
|
//ôóíêöèß î÷èñòêè áóôåðà â ÝíÎÇÓ
|
|
void Logger_Clear(TLogger* p)
|
|
{
|
|
Uint16 zero = 0;
|
|
UserMem.MemStartAddr = p->SPI_start_addr;
|
|
UserMem.MCUStartAddr = (Uint16*)(&zero);
|
|
UserMem.data_length = 1;
|
|
for (int i=0;i<(p->SPI_buf_size * (LOG_LENGTH));i++)
|
|
{
|
|
UserMem.write(&UserMem);
|
|
UserMem.MemStartAddr++;
|
|
}
|
|
p->INTERNAL_last_log_index = 0;
|
|
p->INTERNAL_last_log_num = 0;
|
|
}
|
|
|
|
|
|
//áûñòðàß ôóíêöèß çàïèñè ñîáûòèß â FIFO
|
|
Uint16 Logger_Event_Write(TLogger* p,Uint16 code)
|
|
{
|
|
TEvent event;
|
|
//ôîðìèðóåì äàííûå
|
|
__disable_irq();
|
|
event.ev_time = *(p->time_ptr);
|
|
event.ev_code = code;
|
|
event.ev_num = ++p->INTERNAL_last_log_num;
|
|
p->INTERNAL_last_log_code = code;
|
|
__enable_irq();
|
|
//ïèøåì â FIFO
|
|
return p->FIFO.write((struct SEventFIFO*)&(p->FIFO),(TEvent*)&event);
|
|
}
|
|
|
|
//ïðî÷èòàòü àâàðèþ èç áàíêà, ñëîæèòü äàííûå â TEvent* event
|
|
void Logger_Event_Read(TLogger* p,Uint16 shift_index,TEvent* event)
|
|
{
|
|
Uint16 correction = 0;
|
|
//ïðîâåðßåì ïðàâèëüíîñòü çàïðîñà
|
|
if (shift_index > (p->SPI_buf_size - 1)) return;
|
|
|
|
//ââîä êîððåêöèè äëß îðãàíèçàöèè êîëüöà
|
|
if (((int16)p->INTERNAL_last_log_index - (int16)shift_index) < 0) correction = p->SPI_buf_size;
|
|
//÷òåíèå íîìåðà
|
|
UserMem.MemStartAddr = p->SPI_start_addr + ((p->INTERNAL_last_log_index - shift_index + correction)*(LOG_LENGTH));
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event->ev_num));
|
|
UserMem.data_length = LOG_NUM_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
//÷òåíèå âðåìåíè
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event->ev_time));
|
|
UserMem.data_length = LOG_TIME_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
//÷òåíèå êîäà
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event->ev_code));
|
|
UserMem.data_length = LOG_CODE_LENGTH;
|
|
UserMem.read(&UserMem);
|
|
}
|
|
|
|
//ôóíêöèß îáðàáîòêè FIFO è çàïèñè àâàðèé â ÝíÎÇÓ. Åñëè â FIFO ÷òî-òî êëàëè - çàïèøåì âî ôëåøêó.
|
|
//Åñëè FIFO çàíÿòà èëè ïóñòàÿ - îòäûõàåì.
|
|
void Logger_Background_Calc(TLogger* p)
|
|
{
|
|
Uint16 ret;
|
|
TEvent event;
|
|
//÷òîáû íå ñèëüíî çàòîðìàæèâàòü ôîíîâûé öèêë áóäåì çàïèñûâàòü ïî 1 çàïèñè çà ðàç
|
|
ret = p->FIFO.read((struct SEventFIFO*)&(p->FIFO),(TEvent*)&event);
|
|
if (ret == EVENT_FIFO_SUCCESSFUL)
|
|
{
|
|
//ïèøåì â ÝíÎÇÓ
|
|
if (p->INTERNAL_last_log_index >= (p->SPI_buf_size - 1)) p->INTERNAL_last_log_index = 0;
|
|
else p->INTERNAL_last_log_index++;
|
|
|
|
//çàïèñü íîìåðà
|
|
UserMem.MemStartAddr = p->SPI_start_addr + (p->INTERNAL_last_log_index)*(LOG_LENGTH);
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event.ev_num));
|
|
UserMem.data_length = LOG_NUM_LENGTH;
|
|
UserMem.write(&UserMem);
|
|
//çàïèñü âðåìåíè
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event.ev_time));
|
|
UserMem.data_length = LOG_TIME_LENGTH;
|
|
UserMem.write(&UserMem);
|
|
//çàïèñü êîäà
|
|
UserMem.MemStartAddr += UserMem.data_length;
|
|
UserMem.MCUStartAddr = (Uint16*)(&(event.ev_code));
|
|
UserMem.data_length = LOG_CODE_LENGTH;
|
|
UserMem.write(&UserMem);
|
|
}
|
|
}
|
|
|
|
//ôóíêöèÿ ïðîâåðêè è çàïèñè âèñÿùèõ â äàííûé ìîìåíò ôëàãîâ àâàðèé
|
|
//Ïîñëåäîâàòåëüíî ñìîòðèòñÿ êàæäûé áèò ñëîâ àâàðèé è, åñëè îí âçâåäåí, íî åùå íå çàïèñàí, ïðîèçâîäèòñÿ çàïèñü.
|
|
void Logger_ms_Calc(TLogger* p){
|
|
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
} // Extern "C"
|
|
#endif
|
|
/*@}*/
|