a for loop not executed in an operating system C - c

I have problems while executing a for loop, I created a static table which contains defined values, then I pass my table as an argument in a function to process.
basicly my code looks like the following one:
#define ID_01 0x0000
#define ID_02 0x0001
#define ID_03 0x0002
#define ID_04 0x0003
#define ID_05 0x0004
#define ID_06 0x0005
#define ID_07 0x0006
#define ID_08 0x0007
#define ID_09 0x0008
/*...
*/
#define ID_LAST 0xFFFF
static char table[]={
ID_01, ID_02 ,ID_03, ID_04, .... , ID_LAST}
void process( char *table){
int LastId=0;
char *Command;
for ( Command=table; LastId==0 ; Command++){
switch(Command)
{
case ID_01:
do_stuff01();
break;
case ID_02:
do_stuff02();
break;
...
case ID_LAST:
LastId=1;
break;
default:
break;
}
}
}
I've tried to print some messages to debug but the program does not execute any of the printed even those before the for and after the loop.
But when I've changed my for loop into :
for(i=0;i<10;i++)
all the messages were printed. but I have to process the same way I did in the first place.
PS: this part of code is executed in an operating system task running into a microcontroller and I'm just a beginner.

Now you are using switch (Command) where Command holds address od table variable.
Change switch to
switch (*Command) { //Use value at pointed Command.
}
And note, when doing *Command you dereference char which is 1byte. Your ID's have 2 bytes, therefore you have loss of data.
Change:
static char table[] = {ID_01, ID_02 ,ID_03, ID_04, .... , ID_LAST}
to short to have 16-bits values
static unsigned short table[]={ID_01, ID_02 ,ID_03, ID_04, .... , ID_LAST}
Later, modify your process function to accept unsigned short
void process( const unsigned short *table) { //Unsigned short
int LastId = 0;
unsigned short *Command; //Unsigned short
for ( Command=table; LastId==0 ; Command++){
switch(*Command) { //Added star
//...
}
}
//...
I would rewrite your process code to:
void process(const unsigned short *table, size_t tableLen) {
while (tableLen--) {
switch (*table) {
case ID_1: /* Do stuff */ break;
}
table++; //Increase pointer to next ID element
}
}
//Usage then like this:
static unsigned short table[] = {ID_1, ID_2, ID_3, ..., ID_n};
//Put pointer and length of table
process(table, sizeof(table)/sizeof(table[0]));

In generally, it makes struct and map the ID/FUNC like below.
#include <stdio.h>
#define ID_01 0x0000
#define ID_02 0x0001
/* ... */
#define ID_LAST 0xFFFF
typedef void (*func)();
typedef struct {
char n;
func f;
} fmap;
void do_something01() { }
void do_something02() { }
/* ... */
static fmap fmaps[] = {
{ID_01, do_something01},
{ID_02, do_something02},
/* ... */
{ID_LAST, NULL},
};

Related

function pointers and enum in C

I am looking for a fancy way to link function pointers and enums.
In my case I have a message queue that holds a event id and some data associated with the event.
some simple pseudo code:
event=(eid, data)
switch(eid) {
case eid1:
handler1(data);
break;
case edi2:
handler2(data);
break;
}
Now I like to do some optimization. If the event id has the value of the function called inside of the switch case statement I can save the switch case decode by preserving a nice readability of the code.
event=(eid, data)
eid(data)
Now if I am putting it into an example like:
static void abc(void * p) {
}
static void abc2(void * p) {
}
enum eventId {
eid1 = abc,
eid2 = abc2
} xyz;
My compiler tells:
error: enumerator value for 'eid1' is not an integer constant eid1 = abc
What is absolutely right.
Any ideas how to solve that problem?
Use an array of function pointers, and use the enum as the index.
typedef void (*handler_func)(void *);
handler_func event_handlers[] = { abc, abc2 };
enum eventId {
eid1 = 0,
eid2 = 1,
eid_max
}
if (eid < eid_max) event_handlers[eid](data);
enums cannot be linked with other data in C, but the preprocessor can generate code for you in the form of X-Macros.
#include <stdio.h>
typedef void (*handler_func)(void *);
static void handler1(void *const param) {
printf("Event 1: %p.\n", param);
}
static void handler2(void *const param) {
printf("Event 2: %p.\n", param);
}
#define EVENT(X) \
X(EID1, &handler1), \
X(EID2, &handler2)
#define PARAMA(A, B) A
#define PARAMB(A, B) B
#define STRINGISEA(A, B) #A
enum Event { EVENT(PARAMA) };
static const handler_func event_handlers[] = { EVENT(PARAMB) };
static const char *const event_strings[] = { EVENT(STRINGISEA) };
/* Everything will be the same size, pick one. */
static const size_t event_size = sizeof event_strings / sizeof *event_strings;
int main(void) {
size_t i;
void *const param = (void *)0x100;
for(i = 0; i < event_size; i++) {
printf("Calling %s.\n", event_strings[i]);
event_handlers[i](param);
}
return 0;
}
Gives,
Calling EID1.
Event 1: 0x100.
Calling EID2.
Event 2: 0x100.
The advantage of this implementation is it's a single source of truth; if one decided to add more events, they will only need to be added in one spot. The disadvantage is it's hard to read.
As an extension to the answer of #Barmar, you can use a technique called X macro, to keep corresponding (eid, handler) pairs in order. Note that you need only to change the definition of LIST_OF_EVENTS macro, adding or deleting pairs as needed.
void handler1(void*);
void handler2(void*);
void handler3(void*);
#define LIST_OF_EVENTS X(eid1, handler1), X(eid2, handler2), X(eid3, handler3)
#define X(id, x) id
enum evID { LIST_OF_EVENTS };
#undef X
#define X(x, handler) handler
void (*handlers[])(void*) = { LIST_OF_EVENTS };
#undef X
int get_event(void**);
void event_loop(void)
{
for (;;) {
void *data;
int eid = get_event(&data);
handlers[eid](data);
}
}
Macro defitions expand to
enum evID { eid1, eid2, eid3 };
void (*handlers[])(void*) = { handler1, handler2, handler3 };

How to include macro in struct

I am trying to find a way to dynamically access a certain macro in C.
I tried to include the macro in the struct but then I get the "initializer element is not constant" error. Basically I just want to access the correct macro based on an index but I just don't know how. Is there a straight forward way of accomplishing this? Please note the code is not complete but only an illustration of what I want to do.
#define Data_CAN_SES_Enbl() (...)
#define Data_CAN_SAS_Enbl() (...)
#define Data_CAN_PEP_Enbl() (...)
struct CAN_Rx {
const uint8 id;
const uint8 bus;
xx
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,?
},
/* SAS */
{
1,0,?
},
/* PEP */
{
2,1,?
}
};
void run(uint8 index)
{
uint8 enabled = CheckRx[index].xx;
}
Simply put: you won't.
Dont think of macros as code: they're just chunk of text replaced by the preprocessor before compiling your code.
If you need to embed code in a struct, you better look at function pointers.
--- EDIT ---
By the way, why you want to use macro in your code? Looking at it, it seems you cand do the same thing with a simple function returning a struct with a different content based on a parameter, like:
static struct CAN_Rx getCANrx(int index){
switch(index)
{
case '0':
struct CAN_rx res = /* initialize struct */;
return res;
case '1':
/* as previous */
default:
/* manage default result or errors */
}
}
Maybe you can go with function pointers?
#include <stdio.h>
int Data_CAN_SES_Enbl() { return 0; }
int Data_CAN_SAS_Enbl() { return 1; }
int Data_CAN_PEP_Enbl() { return 2; }
struct CAN_Rx {
const int id;
const int bus;
int (*xx)();
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,Data_CAN_SES_Enbl
},
/* SAS */
{
1,0,Data_CAN_SAS_Enbl
},
/* PEP */
{
2,1,Data_CAN_PEP_Enbl
}
};
int run(int index)
{
int enabled = (*CheckRx[index].xx)();
return enabled;
}
int main() {
printf("%d\n",run(0));
}
If you are curious see below macro example.
For your case , macro cant be better than function pointers.
Using macro just for fun at your case.
#include <stdio.h>
#include <stdlib.h>
#define Data_CAN_SES_Enbl(Y,Z) Y+Z
#define Data_CAN_SAS_Enbl(Y,Z) Y*Z
#define Data_CAN_PEP_Enbl(Y,Z) Y-Z
#define Str(X) #X
#define Data_CAN_Enbl(X,Y,Z) Data_CAN_##X##_Enbl(Y,Z);
#define SES 1
#define SAS 2
#define PEP 3
struct CAN_Rx {
int id;
int bus;
int Flag;
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,100,SES
},
/* SAS */
{
70,20,SAS
},
/* PEP */
{
100,50,PEP
}
};
void run(int index)
{
int RRR=0;
switch(CheckRx[index].Flag){
case SES:
RRR=Data_CAN_Enbl(SES,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SES),RRR);
break;
case SAS:
RRR=Data_CAN_Enbl(SAS,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SAS),RRR);
break;
case PEP:
RRR=Data_CAN_Enbl(PEP,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(PEP),RRR);
break;
}
}
int main(){
run(0);
run(1);
run(2);
printf("%d\n",CheckRx[0].Flag);
return 0;
}

How to protect enum assignment

I want to prevent invalid value enum assignment. I know if i even assign value that is not in enum it will work. Example:
enum example_enum
{
ENUM_VAL0,
ENUM_VAL1,
ENUM_VAL2,
ENUM_VAL3
};
void example_function(void)
{
enum example_enum the_enum = ENUM_VAL3; // correct
the_enum = 41; // will work
the_enum = 0xBADA55; // also will work
bar(the_enum); // this function assumes that input parameter is correct
}
Is there easy, efficient way to check if assignment to enum is correct? I could test value by function
void foo(enum example_enum the_enum)
{
if (!is_enum(the_enum))
return;
// do something with valid enum
}
I could resolve this in following way:
static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3 };
int is_enum(int input)
{
for (int i=0;i<4;i++)
if (e_values[i] == input)
return 1;
return 0;
}
For me, my solution is inefficient, how can i write this if i have more enums and more values in enums?
As long as the enum is continuous one can do something like this:
static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3, ENUM_VAL_COUNT };
int is_enum(int input) { return 0 <= input && input < ENUM_VAL_COUNT; }
Another alternative is to not validate the enum value beforehand, but error out once the code detects an invalid value:
switch(input) {
case ENUM_VAL0: ... break;
case ENUM_VAL1: ... break;
...
default:
assert(0 && "broken enum");
break;
}
But there is no way to enforce that the enum value doesn't go out of the range at all in C. The best you can do if you want to secure the enum against fiddling is to hide the value away in a struct and then have functions to manipulate the struct. The function and struct implementation can be hidden away from the user via a forward declaration in the .h file and the implementation in the .c file:
struct example_t {
enum example_enum value;
}
void example_set_val0(example_t* v) { v->value = ENUM_VAL0; }
There is no way of warning about assigning integers that fit into the enum.
Enumerators in C are synonyms for integer types. Assuming the type chosen for enum example_enum is int, then your code is identical to:
void example_function(void)
{
int the_enum = ENUM_VAL3; // correct
the_enum = 12345; // will work
bar(the_enum); // this function assumes that input parameter is correct
}
void foo(int the_enum)
{
if (!is_enum(the_enum))
return;
// do something with valid enum
}
You could use structures, but even that can be circumvented:
struct example_enum_struct e = { 12345 };
e.value = 23456;
Basically if you want to restrict a type to specific values, you will need to perform checks.
If anyone is interested in this topic, here I have some solution which works.
typed_enums.h
#ifndef TYPED_ENUMS_H
#define TYPED_ENUMS_H
#define TYPED_ENUM(name_) \
typedef struct { int v; } name_
#define TYPED_ENUM_VALUE(name_, value_) (name_) { value_ }
#define GET_TYPED_ENUM_VALUE(en_) (en_.v)
#define TYPED_ENUM_EQ(a_, b_) (GET_TYPED_ENUM_VALUE(a_) == GET_TYPED_ENUM_VALUE(b_))
#endif
usb_class.h
#ifndef USB_CLASS_H
#define USB_CLASS_H
#include "typed_enums.h"
TYPED_ENUM(UsbClass);
#define USB_CLASS_BILLBOARD TYPED_ENUM_VALUE(UsbClass, 0x11)
#define USB_CLASS_TYPE_C_BRIDGE TYPED_ENUM_VALUE(UsbClass, 0x12)
#define USB_CLASS_DIAGNOSTIC_DEVICE TYPED_ENUM_VALUE(UsbClass, 0xDC)
#define USB_CLASS_WIRELESS_CONTROLLER TYPED_ENUM_VALUE(UsbClass, 0xE0)
#endif
usb_class_example.c
#include "typed_enums.h"
#include "usb_class.h"
#include <stdio.h>
int main(int argc, char ** argv)
{
UsbClass usbClass = USB_CLASS_WIRELESS_CONTROLLER;
usbClass = 12345; // tadam!!!! throws error
usbClass = USB_CLASS_VIDEO;
if (TYPED_ENUM_EQ(usbClass, USB_CLASS_VIDEO)) {
printf("usbClass = USB_CLASS_VIDEO\n");
}
printf("usb class value: %02X\n", GET_TYPED_ENUM_VALUE(usbClass));
return 0;
}
Pros:
enum value assignment works like struct assignment
enum for pointers also works
enum value can't be changed
Cons:
can't be used in switch
can't be directly compared
can't directly return enum number value
Note: sorry for abusing preprocessor here

How to use global variables on a state machine

I made this state machine :
enum states { STATE_ENTRY, STATE_....} current_state;
enum events { EVENT_OK, EVENT_FAIL,EVENT_REPEAT, MAX_EVENTS } event;
void (*const state_table [MAX_STATES][MAX_EVENTS]) (void) = {
{ action_entry , action_entry_fail , action_entry_repeat }, /*
procedures for state 1 */
......}
void main (void){
event = get_new_event (); /* get the next event to process */
if (((event >= 0) && (event < MAX_EVENTS))
&& ((current_state >= 0) && (current_state < MAX_STATES))) {
state_table [current_state][event] (); /* call the action procedure */
printf("OK 0");
} else {
/* invalid event/state - handle appropriately */
}
}
When I modify a global variable in one state the global variable remain the same , and I need that variable in all the states . Do you now what could be the problem ?
My Global variable is this structure:
#if (CPU_TYPE == CPU_TYPE_32)
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[64];
} BigNumber;
#elif (CPU_TYPE == CPU_TYPE_16)
typedef uint16_t word;
#define word_length 16
typedef struct BigNumber {
word words[128];
} BigNumber;
#else
#error Unsupported CPU_TYPE
#endif
BigNumber number1 , number2;
Here is how I modify:
//iterator is a number from where I start to modify,
//I already modified on the same way up to the iterator
for(i=iterator+1;i<32;i++){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
This is just in case you may want to change your approach for defining the FSM. I'll show you with an example; say you have the following FSM:
You may represent it as:
void function process() {
fsm {
fsmSTATE(S) {
/* do your entry actions heare */
event = getevent();
/* do you actions here */
if (event.char == 'a') fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(A) {
event = getevent();
if (event.char == 'b' || event.char == 'B') fsmGOTO(B);
else fsmGOTO(E);
}
fsmSTATE(B) {
event = getevent();
if (event.char == 'a' ) fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(E) {
/* done with the FSM. Bye bye! */
}
}
}
I do claim (but I believe someone will disagree) that this is simpler, much more readable and directly conveys the structure of the FSM than using a table. Even if I didn't put the image, drawing the FSM diagram would be rather easy.
To get this you just have to define the fsmXXX stuff as follows:
#define fsm
#define fsmGOTO(x) goto fsm_state_##x
#define fsmSTATE(x) fsm_state_##x :
Regarding the code that changese number2:
for(i=iterator+1;i<32;i){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
I can't fail to note that:
i is never incremented, so just one element of the array is changed (iterator+1) over an infinite loop;
even if i would be incremented, only the a portion of the words array it's changed depending on the value of iterator (but this might be the intended behaviour).
unless iterator can be -1, the element words[0] is never changed (again this could be the intended behaviour).
I would check if this is really what you intended to do.
If you're sure that it's just a visibility problem (since you said that when you declare it as local it worked as expected), the only other thing that I can think of is that you have the functions in one file and the main (or where you do your checks) in another.
Then you include the same .h header in both files and you end up (due to the linker you're using) with two different number2 because you did not declare it as extern in one of the two files.
Your compiler (or, better, the linker) should have (at least) warned you about this, did you check the compilation messages?
This is not an answer - rather it is a comment. But it is too big to fit the comment field so I post it here for now.
The code posted in the question is not sufficient to find the root cause. You need to post a minimal but complete example that shows the problem.
Something like:
#include<stdio.h>
#include<stdlib.h>
#include <stdint.h>
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[4];
} BigNumber;
BigNumber number2;
enum states { STATE_0, STATE_1} current_state;
enum events { EVENT_A, EVENT_B } event;
void f1(void)
{
int i;
current_state = STATE_1;
for (i=0; i<4; ++i) number2.words[i] = i;
}
void f2(void)
{
int i;
current_state = STATE_0;
for (i=0; i<4; ++i) number2.words[i] = 42 + i*i;
}
void (*const state_table [2][2]) (void) =
{
{ f1 , f1 },
{ f2 , f2 }
};
int main (void){
current_state = STATE_0;
event = EVENT_A;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
event = EVENT_B;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
return 0;
}
The above can be considered minimal and complete. Now update this code with a few of your own functions and post that as the question (if it still fails).
My code doesn't fail.
Output:
0 1 2 3
42 43 46 51

Anybody written a dictionary (hashmap) in ANSI C?

I just wondered if someone could give me some pointers (no pun intended) how to do this?
I want to set aside 4GB of ram in order to map numbers to memory which saves me traversing a linked list checking if they are there.
So instead of having (1,2,3,4,8,34,543,2343) and traversing 8 elements to verify that '2343' is in the list, i want to be able to look up the key '2343' in O(1) time?
Thanks in advance
If you only need to check if the number exists in the list, the you can try to make a Bitmap.
If the numbers are going to be sparsely spread out over a large range like 100,000 values in the range 0-4billion then a Hashtable would be faster. For a C implementation of a Hashtable take a look at GLib's Hashtable.
A Bitmap could hold numbers 0-4,294,967,295 using only 512Mbytes of ram.
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#define BITMAP_TEST 1
#define BITMAP_32_WORD 1
typedef struct Bitmap Bitmap;
#if BITMAP_32_WORD
#define BITWORD_BITS_SHIFT 5
typedef uint32_t Bitword;
#else
#define BITWORD_BITS_SHIFT 6
typedef uint64_t Bitword;
#endif
#define BITWORD_BITS (sizeof(Bitword) * 8)
#define BITWORD_BITS_MASK (BITWORD_BITS - 1)
#define BITWORD_MULT(bit) ((bit + (BITWORD_BITS_MASK)) & ~(BITWORD_BITS_MASK))
#define BITWORD_TEST(bword, bit) ((bword >> bit) & 1)
#define BITMAP_WORD_COUNT(bit) (BITWORD_MULT(bit) >> BITWORD_BITS_SHIFT)
struct Bitmap {
size_t length;
Bitword *bitmap;
};
extern Bitmap *bitmap_new(size_t len) {
Bitmap *bitmap = malloc(sizeof(Bitmap));
bitmap->length = len;
bitmap->bitmap = calloc(BITMAP_WORD_COUNT(len),sizeof(Bitword));
return bitmap;
}
extern void bitmap_free(Bitmap *bitmap) {
free(bitmap->bitmap);
free(bitmap);
}
extern void bitmap_set(Bitmap *bitmap, size_t bit) {
assert(bit < bitmap->length);
bitmap->bitmap[(bit >> BITWORD_BITS_SHIFT)] |= ((Bitword)1 << (bit & BITWORD_BITS_MASK));
}
extern void bitmap_unset(Bitmap *bitmap, size_t bit) {
assert(bit < bitmap->length);
bitmap->bitmap[(bit >> BITWORD_BITS_SHIFT)] &= ~((Bitword)1 << (bit & BITWORD_BITS_MASK));
}
extern bool bitmap_test(Bitmap *bitmap, size_t bit) {
assert(bit < bitmap->length);
Bitword bword = bitmap->bitmap[(bit >> BITWORD_BITS_SHIFT)];
return BITWORD_TEST(bword, (bit & BITWORD_BITS_MASK));
}
#ifdef BITMAP_TEST
#include <stdio.h>
#define MAX_VALUE (2343 + 1)
static const uint32_t test_values[] = { 1,2,3,4,8,34,543,2343 };
#define test_values_len (sizeof(test_values)/sizeof(uint32_t))
static void set_values(Bitmap *bitmap, const uint32_t *values, int len) {
int i;
for(i=0; i < len; i++) {
bitmap_set(bitmap, values[i]);
}
}
static void unset_values(Bitmap *bitmap, const uint32_t *values, int len) {
int i;
for(i=0; i < len; i++) {
bitmap_unset(bitmap, values[i]);
}
}
static void check_values(Bitmap *bitmap, const uint32_t *values, int len, bool is_set) {
int i;
for(i=0; i < len; i++) {
assert(bitmap_test(bitmap, values[i]) == is_set);
}
}
int main(int argc, char *argv[]) {
Bitmap *bitmap = bitmap_new(MAX_VALUE);
set_values(bitmap, test_values, test_values_len);
check_values(bitmap, test_values, test_values_len, true);
unset_values(bitmap, test_values, test_values_len);
check_values(bitmap, test_values, test_values_len, false);
bitmap_free(bitmap);
return 0;
}
#endif
If the numbers are 32 bits you don't even need hashing, just use an array.
I would advise embedding Lua in your project. Easy to embed and completely ANSI C with one very flexible garbage collected data structure (a Lua table/aka hashmap). You can always strip out the bits that you don't need, but even if you don't Lua is tiny.
Lua has a stack based API which isn't too hard to follow:
lua_State *L = luaL_newstate(); // make a new lua state
lua_newtable(L); // pushes a new table to the top of the stack (position 1)
// storing values
lua_pushinteger(2343); // key: 2343
lua_pushboolean(1); // value: true
lua_settable(L, 1); // pop key/value, store in table at position 1
// retrieving values
lua_pushinteger(2343); // key we're looking for
lua_gettable(L, 1); // get from table at top of stack - 2; pops key
if (lua_toboolean(L, -1)) // is it a true value?
{
// executes; we know 2343 is true as we pushed it just above
}
lua_pop(L, 1); // pop it off the stack; only our table remains
And you can iterate over the values as well, possibly doing away with the need of your linked list (but the order of the iteration is non-determinate). Full manual here.
A hashtable is actually only O(1) when there are no keys that have the same hash.
For an easy short version of a hashtable in C look here:
http://pokristensson.com/strmap.html

Resources