Внутри структуры мне нужно место, где я могу что-то вставить. Это пространство должно иметь возможность собирать все типы данных, поэтому я хочу определить объединение. Пространство ограничено n байтами (unsigned char).C Union definition
Как мне определить мой союз, чтобы он мог содержать char, int, float и т. Д.?
Должен ли я так поступать?
#define SIZE (128)
union {
unsigned char uchar[SIZE];
char schar[SIZE];
unsigned int uint[SIZE/sizeof(unsigned int)];
int sint[SIZE/sizeof(int)];
float flt[SIZE/sizeof(float)];
double dbl[SIZE/sizeof(double)];
}memory;
Или есть возможность определить только размер без знака массив символов, а затем автоматически определять размер Int массива? Что произойдет, если SIZE
не делится на 4?
EDIT: (в связи с комментариями)
Я хочу построить что-то вроде приурочено обработчик события. Это означает, что у меня есть структура, содержащая массив событий. Каждое событие имеет время выполнения и связанную функцию (хранится как указатель). Когда счетчик таймера обработчика событий соответствует времени выполнения события, я вызываю связанную функцию. Внутри функции я буду знать, какие аргументы ожидаются, поэтому мне не нужно сохранять значение тега. Проблема в том, что события создаются в funtion, и поскольку я не хочу, чтобы события статичны (чтобы сохранить память), я добавил некоторую память (кольцевой буфер) в обработчик событий, где все функции могут помещать некоторые данные , Каждое событие будет иметь переменную, содержащую указатель на (первые) данные. Тип данных - это только типы данных nativ, не собственные структуры.
Это мой текущий код:
startSystemClock()
будет называться при запуске
executeSystemEvent()
будет вызываться процедура обработки прерываний таймера 1, установив sysEventHandler.execute=TRUE
и А while(1)
-loop проверяет этот флаг, а затем звонки executeSystemEvent()
// typedefs requird for timed events
typedef union __attribute__ ((packed)){
int *i; // pointer, where data is stored
int value; // if there is a pointer assigned, value differs from zero
}systemEventData_u;
typedef union __attribute__ ((packed)){
int value; // if there is a pointer assigned, value differs from zero
void (*voidFct_noData)();
void (*voidFct_data)(systemEventData_u);
}systemEventFct_u;
typedef struct{
int time;
unsigned int id;
systemEventFct_u fct;
systemEventData_u data;
}systemEvent_t;
#define SYSTEM_EVENT_HANDLER_BUFFER_SIZE (10)
#define SYSTEM_EVENT_HANDLER_MEMORY_SIZE (10)
typedef struct{
unsigned int actualCnt;
unsigned int nextEventCnt;
unsigned char execute;
systemEvent_t events[SYSTEM_EVENT_HANDLER_BUFFER_SIZE];
systemEvent_t* write;
// create some persistent memory usable by all functions
int* memWrite;
union __attribute__ ((packed)){
unsigned char uchar[0];
char schar[0];
unsigned int uint[0];
int sint[SYSTEM_EVENT_HANDLER_MEMORY_SIZE];
float flt[0];
double dbl[0];
}memory;
}systemEventHandler_t;
void startSystemClock(){
// initialize event handler
sysEventHandler.actualCnt=0;
sysEventHandler.nextEventCnt=-1;
sysEventHandler.execute=FALSE;
sysEventHandler.write=sysEventHandler.events;
sysEventHandler.memWrite=sysEventHandler.memory.sint;
unsigned int i=SYSTEM_EVENT_HANDLER_BUFFER_SIZE;
systemEvent_t *ptr=sysEventHandler.events;
while(i--){
ptr->fct.value=0;
ptr->data.value=0;
ptr->time=0;
ptr++;
}
// initialize timer 1
TMR1 = 0x00;
T1CON = T3_OFF | T3_IDLE_CON | T3_GATE_OFF | T1_PS_1_8 | T1_SOURCE_INT;
IPC1SET = (INTERRUPT_PRIOR_TIMER1 << _IPC1_T1IP_POSITION) | (INTERRUPT_SUB_PRIOR_TIMER1 << _IPC1_T1IS_POSITION);
IFS0CLR = (1 << _IFS0_T1IF_POSITION);
IEC0SET = (1 << _IEC0_T1IE_POSITION);
PR1 = PR_TIMER1;
T1CONSET = (1 << _T1CON_ON_POSITION);
print_text("timer1 started\n\r");
}
void executeSystemEvent(){
asm("di");
int time=sysEventHandler.actualCnt;
asm("ei");
unsigned int i=SYSTEM_EVENT_HANDLER_BUFFER_SIZE;
unsigned int nextEventCnt=-1;
systemEvent_t *ptr=sysEventHandler.events;
while(i--){
// do not investigate, if there is no function pointer
// no function pointer means no event action
if(ptr->fct.value){
if(time>=ptr->time){
// execute function
if(ptr->data.value){
(*ptr->fct.voidFct_data)(ptr->data);
}else{
(*ptr->fct.voidFct_noData)();
}
ptr->fct.value=0;
}
}
ptr++;
}
// determine next event
// iterate again through whole queue to take added events into account also
i=SYSTEM_EVENT_HANDLER_BUFFER_SIZE;
ptr=sysEventHandler.events;
while(i--){
if(ptr->fct.value){
// get execution time to determine next one
if(ptr->time<nextEventCnt){
nextEventCnt=ptr->time;
}
}
ptr++;
}
asm("di");
sysEventHandler.nextEventCnt=nextEventCnt;
sysEventHandler.execute=FALSE;
asm("ei");
}
void addSystemEvent(systemEvent_t event){
// check, if this event will be the first event to execute
asm("di");
// get event execution time
event.time+=sysEventHandler.actualCnt;
// check, if it will be the next one to execute
if(sysEventHandler.nextEventCnt>event.time){
sysEventHandler.nextEventCnt=event.time;
}
asm("ei");
*sysEventHandler.write=event;
if(++sysEventHandler.write>=sysEventHandler.events+SYSTEM_EVENT_HANDLER_BUFFER_SIZE){
sysEventHandler.write=sysEventHandler.events;
}
}
int * storeSystemEventData(int data){
int *ptr=sysEventHandler.memWrite;
*ptr=data;
if(++sysEventHandler.memWrite>=sysEventHandler.memory.sint+SYSTEM_EVENT_HANDLER_MEMORY_SIZE){
sysEventHandler.memWrite=sysEventHandler.memory.sint;
}
return ptr;
}
Чтобы добавить событие, я пишу в любой функции:
systemEvent_t event;
event.fct.voidFct_data=&enablePinChangeInterrupt_wrapper;
event.data.i=storeSystemEventData((int)PUSHBUTTON_CN_BIT);
event.time=10;
addSystemEvent(event);
Я знаю, что storeSystemEventData
-функция не является полной. Но для моей первой цели мне нужен только int, поэтому он работает.
Когда вы говорите, что все типы данных имеют в виду только обычные типы данных, такие как 'int' и т. Д., Или вам также нужны пользовательские типы данных, такие как' struct'? Вам нужно рассмотреть другие более конкретные типы данных, такие как 32-битные или 64-битные целые числа с подписью/без знака? Вам действительно нужны массивы типов, отличных от 'char' и' unsigned char', поскольку эти массивы обычно используются для текстовых строк или это пространство памяти, которое будет использоваться для размещения текстовой строки или двоичного числа? –
Еще один вопрос: как узнать, какой тип данных хранится в объединении? Обычно объединение используется внутри структуры, которая содержит значение тега или перечисление, которое указывает фактический тип данных, хранящийся в объединении. –
см. Редактировать –