Commit 98dfdb34 authored by Bc. Petr Elexa's avatar Bc. Petr Elexa
Browse files

Complete cache

parent 69261e49
......@@ -5,32 +5,110 @@
#include <static_cache.h>
static term_cache_item_t _cache_set_0[STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS];
static term_cache_item_t _cache_set_1[STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS];
static term_cache_item_t _cache_set_2[STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS];
static term_cache_item_t _cache_set_3[STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS];
static term_cache_item_t * _cache_sets[STATIC_CACHE_SETS] = {_cache_set_0, _cache_set_1, _cache_set_2, _cache_set_3};
typedef struct
{
cache_item_t * const ptr_items;
int length;
} cache_set_t;
static cache_item_t _cache_set_0[STATIC_CACHE_SET_CAP];
static cache_item_t _cache_set_1[STATIC_CACHE_SET_CAP];
static cache_item_t _cache_set_2[STATIC_CACHE_SET_CAP];
static cache_item_t _cache_set_3[STATIC_CACHE_SET_CAP];
static cache_set_t _cache_sets[STATIC_CACHE_SETS]
= {
{_cache_set_0, 0},
{_cache_set_1, 0},
{_cache_set_2, 0},
{_cache_set_3, 0}
};
static bool _binary_search(const cache_set_t * ptr_set, const cache_item_t kv, int * ptr_idx)
{
int down = 0;
int top = ptr_set->length - 1;
int mid;
while (down <= top)
{
mid = (down + top) / 2;
if (ptr_set->ptr_items[mid].key > kv.key) top = mid - 1;
else if (ptr_set->ptr_items[mid].key < kv.key) down = mid + 1;
else
{
*ptr_idx = mid;
return true; // found
}
}
*ptr_idx = down;
return false; //not found
}
// O(1)
static inline term_cache_item_t * _get_cache_set(uint32_t key)
static inline cache_set_t * _get_cache_set(const cache_item_t kv)
{
return _cache_sets[(key & 0xC00000) >> 22];
return &_cache_sets[(kv.key & 0xC00000) >> 22];
}
// O(log (STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS))
term_cache_item_t static_cache_get(uint32_t key)
bool static_cache_get(cache_item_t * ptr_kv)
{
const cache_set_t * ptr_set = _get_cache_set(*ptr_kv);
int idx;
if (_binary_search(ptr_set, *ptr_kv, &idx))
{
*ptr_kv = ptr_set->ptr_items[idx];
return true;
}
else
{
return false;
}
}
// O(log (STATIC_CACHE_CAPACITY / 4) + (STATIC_CACHE_CAPACITY / 4))
void static_cache_insert(uint32_t key)
// O(log (STATIC_CACHE_CAPACITY / 4) + 2*(STATIC_CACHE_CAPACITY / 4))
void static_cache_insert(const cache_item_t kv)
{
cache_set_t * ptr_set = _get_cache_set(kv);
int idx;
if (_binary_search(ptr_set, kv, &idx))
{
ptr_set->ptr_items[idx] = kv; // update existing item
}
else
{
if ( 1 + ptr_set->length >= STATIC_CACHE_SET_CAP)
{
//TODO cache set full
ptr_set->ptr_items[idx] = kv;
}
else
{
for (int i = ptr_set->length - 1; i >= idx; --i)
{
ptr_set->ptr_items[i + 1] = ptr_set->ptr_items[i];
}
ptr_set->ptr_items[idx] = kv;
++ptr_set->length;
}
}
}
// O(log (STATIC_CACHE_CAPACITY / 4) + (STATIC_CACHE_CAPACITY / 4))
void static_cache_erase(uint32_t key)
// O(log (STATIC_CACHE_CAPACITY / 4) + 2*(STATIC_CACHE_CAPACITY / 4))
void static_cache_erase(const cache_item_t kv)
{
cache_set_t * ptr_set = _get_cache_set(kv);
int idx;
if (_binary_search(ptr_set, kv, &idx))
{
for (int i = idx; i < ptr_set->length - 1; ++i)
{
ptr_set->ptr_items[i] = ptr_set->ptr_items[i + 1];
}
--ptr_set->length;
}
}
......@@ -2,17 +2,23 @@
#define STATIC_CACHE_H_
#include <stdint.h>
#include <stdbool.h>
#define STATIC_CACHE_SETS 4
#define STATIC_CACHE_CAPACITY (128 * STATIC_CACHE_SETS)
#define STATIC_CACHE_SET_CAP 128
#define STATIC_CACHE_CAPACITY (STATIC_CACHE_SET_CAP * STATIC_CACHE_SETS)
// cache item type
typedef struct
{
uint32_t user_id : 24;
uint32_t is_valid : 1;
uint32_t location : 2;
uint32_t : 5; // reserved for future
} term_cache_item_t; // 4B
uint32_t key : 24;
uint32_t value : 8;
} cache_item_t;
bool static_cache_get(cache_item_t * ptr_kv);
void static_cache_insert(const cache_item_t kv);
void static_cache_erase(const cache_item_t kv);
#endif /* STATIC_CACHE_H_ */
......@@ -14,6 +14,20 @@
#include <stdio.h>
#include <string.h>
typedef union
{
struct
{
uint32_t user_id : 24;
uint32_t panel0 : 1;
uint32_t panel1 : 1;
uint32_t panel2 : 1;
uint32_t is_valid : 1;
uint32_t : 4; // reserved for future
};
cache_item_t item;
}term_cache_item_t; // 4B
static void terminal_user_authorized(uint8_t panel_id)
{
// TODO
......@@ -26,25 +40,29 @@ static void terminal_user_not_authorized(uint8_t panel_id)
(void)panel_id;
}
static bool terminal_is_user_auhorized(uint32_t user_id)
{
#ifdef DEVEL_BOARD
if (user_id == 7632370) return true;
#endif
return false;
}
static void terminal_user_identified(uint32_t user_id, uint8_t panel_id)
{
if (terminal_is_user_auhorized(user_id))
#ifdef DEVEL_BOARD
if (user_id == 7632370)
{
terminal_user_authorized(panel_id);
return;
}
else
#endif
term_cache_item_t user;
user.user_id = user_id;
if (static_cache_get(&user.item))
{
terminal_user_not_authorized(panel_id);
if ((user.panel2 << 2 | user.panel1 << 1 | user.panel0) & (1 << panel_id))
{
terminal_user_authorized(panel_id);
return;
}
}
terminal_user_not_authorized(panel_id);
}
static void terminal_task(void *pvParameters)
......
......@@ -119,163 +119,164 @@ void CAN_IRQHandler (void)
*****************************************************************************/
void CAN_RX(uint8_t msg_obj_num)
{
uint32_t i;
CCAN_MSG_OBJ_T CANopen_Msg_Obj;
/* Determine which CAN message has been received */
CANopen_Msg_Obj.msgobj = msg_obj_num;
/* Now load up the CANopen_Msg_Obj structure with the CAN message */
LPC_CCAN_API->can_receive(&CANopen_Msg_Obj);
if(msg_obj_num == 3)
{
/* message object used for heartbeat / bootup */
for(i=0; i<WatchListLength; i++)
{
if((CANopen_Msg_Obj.mode_id & 0x7F) == WatchList[i].NodeID || (CANopen_Msg_Obj.mode_id & 0x7F) == ((WatchList[i].value>>16) & 0x007F))
{
/* Node ID of received message is listed in watchlist */
WatchList[i].counter = 0;
WatchList[i].status = CANopen_Msg_Obj.data[0];
if(CANopen_Msg_Obj.data[0] == 0x00)
{
/* received message is bootup */
WatchList[i].status = NMT_STATE_PRE_OPERATIONAL; /* Received bootup, thus state is pre-op */
if(WatchList[i].heartbeatFail)
WatchList[i].BootupAfterHBF = 1;
CANopen_NMT_Consumer_Bootup_Received(CANopen_Msg_Obj.mode_id & 0x7F);
}
}
}
}
if (msg_obj_num == 5)
{
/* message object used for NMT */
if(CANopen_Msg_Obj.data[1] == CAN_NODE_ID || CANopen_Msg_Obj.data[1] == 0x00)
CANopen_NMT_Change_MyState(CANopen_Msg_Obj.data[0]); /* change NMT state both on broadcast and on my ID */
}
if (msg_obj_num == 7)
{
/* message object used for SDO client */
if(CANopen_SDOC_State == CANopen_SDOC_Exp_Read_Busy)
{
/* Expedited read was initiated */
if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x40)
{
/* received data from server */
i = 4-((CANopen_Msg_Obj.data[0]>>2) & 0x03); /* i now contains number of valid data bytes */
CANopen_SDOC_InBuff = 0;
while(i--)
CANopen_SDOC_Buff[i] = CANopen_Msg_Obj.data[CANopen_SDOC_InBuff++ + 4]; /* save valid databytes to memory */
CANopen_SDOC_State = CANopen_SDOC_Succes; /* expedited read completed successfully */
if(CANopen_SDOC_Exp_ValidBytes)
*CANopen_SDOC_Exp_ValidBytes = CANopen_SDOC_InBuff; /* save number of valid bytes */
}
}
else if(CANopen_SDOC_State == CANopen_SDOC_Exp_Write_Busy)
{
/* expedited write was initiated */
if(CANopen_Msg_Obj.data[0] == 0x60)
CANopen_SDOC_State = CANopen_SDOC_Succes; /* received confirmation */
}
else if(CANopen_SDOC_State == CANopen_SDOC_Seg_Read_Busy)
{
/* segmented read was initiated */
if(((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x40) && ((CANopen_Msg_Obj.data[0] & (1<<1)) == 0x00))
{
/* Received reply on initiate command, send first segment request */
CANopen_Msg_Obj.msgobj = 8;
CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
CANopen_Msg_Obj.data[0] = 0x60;
CANopen_Msg_Obj.data[1] = 0x00;
CANopen_Msg_Obj.data[2] = 0x00;
CANopen_Msg_Obj.data[3] = 0x00;
CANopen_Msg_Obj.data[4] = 0x00;
CANopen_Msg_Obj.data[5] = 0x00;
CANopen_Msg_Obj.data[6] = 0x00;
CANopen_Msg_Obj.data[7] = 0x00;
LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
CANopen_SDOC_InBuff = 0;
}
else if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x00)
{
/* Received response on request */
for(i=0; i < (7 - ((CANopen_Msg_Obj.data[0]>>1) & 0x07)); i++)
{
/* get all data from frame and save it to memory */
if(CANopen_SDOC_InBuff < CANopen_SDOC_Seg_BuffSize)
CANopen_SDOC_Buff[CANopen_SDOC_InBuff++] = CANopen_Msg_Obj.data[i+1];
else
{
/* SDO segment too big for buffer, abort */
CANopen_SDOC_State = CANopen_SDOC_Fail;
}
}
if(CANopen_Msg_Obj.data[0] & 0x01)
{
/* Last frame, change status to success */
CANopen_SDOC_State = CANopen_SDOC_Succes;
}
else
{
/* not last frame, send acknowledge */
CANopen_Msg_Obj.msgobj = 8;
CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
CANopen_Msg_Obj.data[0] = 0x60 | ((CANopen_Msg_Obj.data[0] & (1<<4)) ^ (1<<4)); /* toggle */
CANopen_Msg_Obj.data[1] = 0x00;
CANopen_Msg_Obj.data[2] = 0x00;
CANopen_Msg_Obj.data[3] = 0x00;
CANopen_Msg_Obj.data[4] = 0x00;
CANopen_Msg_Obj.data[5] = 0x00;
CANopen_Msg_Obj.data[6] = 0x00;
CANopen_Msg_Obj.data[7] = 0x00;
LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
}
}
}
else if(CANopen_SDOC_State == CANopen_SDOC_Seg_Write_Busy)
{
/* segmented write was initiated */
if((((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x60) && ((CANopen_Msg_Obj.data[0] & (1<<1)) == 0x00)) || ((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x20))
{
/* received acknowledge */
CANopen_Msg_Obj.msgobj = 8;
CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x60)
{
/* first frame */
CANopen_SDOC_InBuff = 0; /* Clear buffer */
CANopen_Msg_Obj.data[0] = 1<<4; /* initialize for toggle */
}
CANopen_Msg_Obj.data[0] = ((CANopen_Msg_Obj.data[0] & (1<<4)) ^ (1<<4)); /* toggle */
/* fill frame data */
for(i=0; i<7; i++)
{
if(CANopen_SDOC_InBuff < CANopen_SDOC_Seg_BuffSize)
CANopen_Msg_Obj.data[i+1] = CANopen_SDOC_Buff[CANopen_SDOC_InBuff++];
else
CANopen_Msg_Obj.data[i+1] = 0x00;
}
/* if end of buffer has been reached, then this is the last frame */
if(CANopen_SDOC_InBuff == CANopen_SDOC_Seg_BuffSize)
{
CANopen_Msg_Obj.data[0] |= ((7-(CANopen_SDOC_Seg_BuffSize%7))<<1) | 0x01; /* save length */
CANopen_SDOC_State = CANopen_SDOC_Succes; /* set state to succes */
}
LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
}
}
}
return;
// uint32_t i;
// CCAN_MSG_OBJ_T CANopen_Msg_Obj;
//
// /* Determine which CAN message has been received */
// CANopen_Msg_Obj.msgobj = msg_obj_num;
//
// /* Now load up the CANopen_Msg_Obj structure with the CAN message */
// LPC_CCAN_API->can_receive(&CANopen_Msg_Obj);
//
// if(msg_obj_num == 3)
// {
// /* message object used for heartbeat / bootup */
// for(i=0; i<WatchListLength; i++)
// {
// if((CANopen_Msg_Obj.mode_id & 0x7F) == WatchList[i].NodeID || (CANopen_Msg_Obj.mode_id & 0x7F) == ((WatchList[i].value>>16) & 0x007F))
// {
// /* Node ID of received message is listed in watchlist */
// WatchList[i].counter = 0;
// WatchList[i].status = CANopen_Msg_Obj.data[0];
// if(CANopen_Msg_Obj.data[0] == 0x00)
// {
// /* received message is bootup */
// WatchList[i].status = NMT_STATE_PRE_OPERATIONAL; /* Received bootup, thus state is pre-op */
// if(WatchList[i].heartbeatFail)
// WatchList[i].BootupAfterHBF = 1;
// CANopen_NMT_Consumer_Bootup_Received(CANopen_Msg_Obj.mode_id & 0x7F);
// }
// }
// }
// }
//
// if (msg_obj_num == 5)
// {
// /* message object used for NMT */
// if(CANopen_Msg_Obj.data[1] == CAN_NODE_ID || CANopen_Msg_Obj.data[1] == 0x00)
// CANopen_NMT_Change_MyState(CANopen_Msg_Obj.data[0]); /* change NMT state both on broadcast and on my ID */
// }
//
// if (msg_obj_num == 7)
// {
// /* message object used for SDO client */
// if(CANopen_SDOC_State == CANopen_SDOC_Exp_Read_Busy)
// {
// /* Expedited read was initiated */
// if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x40)
// {
// /* received data from server */
// i = 4-((CANopen_Msg_Obj.data[0]>>2) & 0x03); /* i now contains number of valid data bytes */
// CANopen_SDOC_InBuff = 0;
//
// while(i--)
// CANopen_SDOC_Buff[i] = CANopen_Msg_Obj.data[CANopen_SDOC_InBuff++ + 4]; /* save valid databytes to memory */
// CANopen_SDOC_State = CANopen_SDOC_Succes; /* expedited read completed successfully */
// if(CANopen_SDOC_Exp_ValidBytes)
// *CANopen_SDOC_Exp_ValidBytes = CANopen_SDOC_InBuff; /* save number of valid bytes */
// }
// }
// else if(CANopen_SDOC_State == CANopen_SDOC_Exp_Write_Busy)
// {
// /* expedited write was initiated */
// if(CANopen_Msg_Obj.data[0] == 0x60)
// CANopen_SDOC_State = CANopen_SDOC_Succes; /* received confirmation */
// }
// else if(CANopen_SDOC_State == CANopen_SDOC_Seg_Read_Busy)
// {
// /* segmented read was initiated */
// if(((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x40) && ((CANopen_Msg_Obj.data[0] & (1<<1)) == 0x00))
// {
// /* Received reply on initiate command, send first segment request */
// CANopen_Msg_Obj.msgobj = 8;
// CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
// CANopen_Msg_Obj.data[0] = 0x60;
// CANopen_Msg_Obj.data[1] = 0x00;
// CANopen_Msg_Obj.data[2] = 0x00;
// CANopen_Msg_Obj.data[3] = 0x00;
// CANopen_Msg_Obj.data[4] = 0x00;
// CANopen_Msg_Obj.data[5] = 0x00;
// CANopen_Msg_Obj.data[6] = 0x00;
// CANopen_Msg_Obj.data[7] = 0x00;
// LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
//
// CANopen_SDOC_InBuff = 0;
// }
// else if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x00)
// {
// /* Received response on request */
// for(i=0; i < (7 - ((CANopen_Msg_Obj.data[0]>>1) & 0x07)); i++)
// {
// /* get all data from frame and save it to memory */
// if(CANopen_SDOC_InBuff < CANopen_SDOC_Seg_BuffSize)
// CANopen_SDOC_Buff[CANopen_SDOC_InBuff++] = CANopen_Msg_Obj.data[i+1];
// else
// {
// /* SDO segment too big for buffer, abort */
// CANopen_SDOC_State = CANopen_SDOC_Fail;
// }
// }
//
// if(CANopen_Msg_Obj.data[0] & 0x01)
// {
// /* Last frame, change status to success */
// CANopen_SDOC_State = CANopen_SDOC_Succes;
// }
// else
// {
// /* not last frame, send acknowledge */
// CANopen_Msg_Obj.msgobj = 8;
// CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
// CANopen_Msg_Obj.data[0] = 0x60 | ((CANopen_Msg_Obj.data[0] & (1<<4)) ^ (1<<4)); /* toggle */
// CANopen_Msg_Obj.data[1] = 0x00;
// CANopen_Msg_Obj.data[2] = 0x00;
// CANopen_Msg_Obj.data[3] = 0x00;
// CANopen_Msg_Obj.data[4] = 0x00;
// CANopen_Msg_Obj.data[5] = 0x00;
// CANopen_Msg_Obj.data[6] = 0x00;
// CANopen_Msg_Obj.data[7] = 0x00;
// LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
// }
// }
// }
// else if(CANopen_SDOC_State == CANopen_SDOC_Seg_Write_Busy)
// {
// /* segmented write was initiated */
// if((((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x60) && ((CANopen_Msg_Obj.data[0] & (1<<1)) == 0x00)) || ((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x20))
// {
// /* received acknowledge */
// CANopen_Msg_Obj.msgobj = 8;
// CANopen_Msg_Obj.mode_id = 0x600 + CANopen_SDOC_Seg_ID;
// if((CANopen_Msg_Obj.data[0] & (7<<5)) == 0x60)
// {
// /* first frame */
// CANopen_SDOC_InBuff = 0; /* Clear buffer */
// CANopen_Msg_Obj.data[0] = 1<<4; /* initialize for toggle */
// }
// CANopen_Msg_Obj.data[0] = ((CANopen_Msg_Obj.data[0] & (1<<4)) ^ (1<<4)); /* toggle */
//
// /* fill frame data */
// for(i=0; i<7; i++)
// {
// if(CANopen_SDOC_InBuff < CANopen_SDOC_Seg_BuffSize)
// CANopen_Msg_Obj.data[i+1] = CANopen_SDOC_Buff[CANopen_SDOC_InBuff++];
// else
// CANopen_Msg_Obj.data[i+1] = 0x00;
// }
//
// /* if end of buffer has been reached, then this is the last frame */
// if(CANopen_SDOC_InBuff == CANopen_SDOC_Seg_BuffSize)
// {
// CANopen_Msg_Obj.data[0] |= ((7-(CANopen_SDOC_Seg_BuffSize%7))<<1) | 0x01; /* save length */
// CANopen_SDOC_State = CANopen_SDOC_Succes; /* set state to succes */
// }
//
// LPC_CCAN_API->can_transmit(&CANopen_Msg_Obj);
// }
// }
// }
// return;
}
/*****************************************************************************
......
......@@ -71,7 +71,7 @@ extern unsigned int TERMINAL_UID[5]; // 0 - status code, 1 - least significant w
#define WEIGAND_DEVICE_LIMIT 4
#define SERIAL_DEVICE_LIMIT 0
#define DOOR_ACC_PANEL_MAX_COUNT (WEIGAND_DEVICE_LIMIT + SERIAL_DEVICE_LIMIT)
#define DOOR_ACC_PANEL_MAX_COUNT 3
// IO
#define LOG_HIGH 1
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment