I have ran into very strange behavior of my code, the basic flow of code is
main () parses a file and sets global variables accordingly.. such as
int frame_size, version;
typedef struct//file parsing variables
{
int frame,
int version; } configuration;
***//the function init_parse calls***
static int handler(void* user, const char* section, const char* name,
const char* value)
{
configuration* pconfig = (configuration*)user;
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
if (MATCH("protocol", "version")) {
pconfig->version = atoi(value);
}
else if (MATCH("basic", "frames")) {
pconfig->frames= atoi(value);
frame_size=pconfig->frames;
}
else {
return 0; /* unknown section/name, error */
}
return 1;
}
main (){
configuration config;
if (ini_parse("test.ini", handler, &config) < 0) {
printf("Can't load 'test.ini'\n");
getchar();
iret = pthread_create(&hThread,NULL, pcapreader, NULL);
if(iret)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret);
exit(EXIT_FAILURE);
}
}
Now, the line followed by main()'s parsing line, everything seems set, but as soon as thread is started , the value frame_size changes to something 6345720:/
I have double checked code for possible replicated variable. thread only uses frame_size in for loop to check the limit.
the only problem was with initialization, once initialized, everything worked like a charm :)
I think it might never initialize the frame_size variable and never reached MATCH("basic", "frames") statement too.
Related
I once managed to return the function, and with that when I run the test it passed I Have this function on utils.c:
int (util_sys_inb)(int port, uint8_t *value) {
uint32_t val;
if(sys_inb(port, &val) != OK) return 1;
*value = (uint8_t)val;
return 0;
}
This one is just for wrapping up the function sys_inb(), because of the format of the argument.
Then I need to get right the number of times that this is called.
I have this other file : keyboard.c with a global variable, extern int count.
with this function:
int sys_inb_count(int port, uint8_t *value) {
if(util_sys_inb(port,value)!=OK){ return 1;}
count++;
return count;
}
I got this right once, returning the value on the first function, but then I did something differently, and the tests were not able to pass anymore.
Appreciate if you can help, me, I've been pulling my hair out.
I tried, put the counter straight on the first function and it worked, but then I tried to do it again, and then I could not anymore.
It compiles and runs but I get this:
https://imgur.com/a/YZsd1Ok
The problem was that I was only adding to the counter when the function worked as expected, if it was called and gave an error, it would not count I just added the counter to the util_sys_inb:
uint32_t count = 0;
int (util_sys_inb)(int port, uint8_t *value) {
uint32_t val;
if(sys_inb(port, &val) != OK) return 1;
*value = (uint8_t)val;
count++;
return count;
}
I'm trying to use static structs as a buffer for incoming messages, in order to avoid checking the buffer on the MCP2515-external unit. An ISR enters the function with a can_message* value 255 to actually read new messages from my MCP2515.
Other applications register an ID in the message passed as argument, in order to check if the buffer holds any messages with the same value.
This returns wrong IDs, and the rest of the datafields are 0 and uninitialized. What is wrong?
can_message struct:
typedef struct
{
uint8_t id;
uint8_t datalength;
uint8_t data[8];
}can_message;
int CAN_message_receive(can_message* message)
{
static volatile can_message* buffers = (volatile can_message*)0x18FF;
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS; i++)
{
//These structs gets addresses outside SRAM
buffers[i] = (can_message){0,0,0};
}
birth = 0;
}
if (message == CAN_UPDATE_MESSAGES)
{
/* Sorts messages <3 */
can_message currentMessage;
//These functions are working:
CAN_message_get_from_MCP_buf(¤tMessage, 0);
buffers[currentMessage.id] = currentMessage;
CAN_message_get_from_MCP_buf(¤tMessage, 1);
buffers[currentMessage.id] = currentMessage;
return 0; //returns nothing !
}
if(buffers[message->id].id != 0)
{
printf("test\n");
//This copy gives wrong id and data:
memcpy(message, &buffers[message->id], sizeof(can_message));
buffers[message->id].id = 0;
return 0;
}
return -1;
}
Edit 1:
I did however notice that any buffers[i]-struct gets a totally different address than expected. It does not use the addresses following 0x18FF on the SRAM. Is there any way to change this?
Edit 2:
This is my main-loop:
while (1) {
//printf("tx buf ready: %d\n", MCP2515_TX_buf_empty(0));
//CAN_Loopback_test();
_delay_ms(500);
value = USART_ReadByte(0);
CAN_message_receive(&msg);
printf("CAN_receive: ID: %d, datalength: %d, data: \n",msg.id);
for (int k; k < msg.datalength; k++)
{
printf("%d, ",msg.data[k]);
}
printf("\n");
}
Edit 3: Changing the buffer-pointer to array solved the issue. (It does no longer use the SRAM, but whatever floats my boat)
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
Solved!
Pointer to buffers changed to buffer-array:
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
I would strongly suggest to decouple the ISR logic with the programs own message cache logic. Also the initializing logic with the birth variable looks unnecessary.
I would setup some ring buffer that the ISR can write messages to and from that the main code reads the data into the ID-lookup-buffer.
This would ensure that message updates does not interfere with readouts (at least if you check the read/write indices to your ring buffer) and also eliminates the need to put Mutexes around your whole message buffer.
Currently it smells very badly because of missing read/write synchronization.
// global
#define CAN_MESSAGE_UNIQUE_IDS 50
static can_message g_can_messagebuffers[CAN_MESSAGE_UNIQUE_IDS];
#define MAX_RECEIVEBUFFER 8
static volatile can_message g_can_ringbuffer[MAX_RECEIVEBUFFER];
static volatile int g_can_ringbufferRead = 0;
static volatile int g_can_ringbufferWrite = 0;
// called from ISR
void GetNewMessages()
{
// todo: check ring buffer overflow
can_message currentMessage;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 0);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 1);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
}
// called from main loop
void handleNewMessages()
{
while(g_can_ringbufferRead != g_can_ringbufferWrite){
const can_message* currentMessage = &g_can_ringbuffer[g_can_ringbufferRead];
if(currentMessage->id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[currentMessage->id] = *currentMessage;
}
g_can_ringbufferRead = (g_can_ringbufferRead + 1) % MAX_RECEIVEBUFFER;
}
}
// called from whoever wants to know
// todo:
// really required a by value interface?
// would it not be sufficient to return a pointer and
// provide an additional interface to mark the message as used?
int getMsg(can_message* message)
{
if(buffers[message->id].id != 0)
{
printf("test\n");
*message = &g_can_messagebuffers[message->id];
g_can_messagebuffers[message->id].id = 0;
return 0;
}
return -1;
}
// alternative to above
const can_message* getMsg(int id)
{
if( (id < CAN_MESSAGE_UNIQUE_IDS)
&& (g_can_messagebuffers[id] != 0))
{
return &g_can_messagebuffers[id].id;
}
return NULL;
}
void invalidateMsg(int id)
{
if(id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[id] = 0;
}
}
edit:
after your changes to an message array instead some strange pointer, there is also no need for the setup routine for this code.
edit:
if your micro controller already has a buffer for received messages, then may be it is unnecessary at all to register a ISR and you could empty it from the mainloop directly into your own id-lookup buffer (assuming the mainloop is fast enough)
I have a function which does some initialization and calls other functions, each of which returns an error code. I want to be able to return from this function after the first detected error like this:
int error_code = FirstFunction();
if (error_code != 0) {
return error_code;
}
error_code = SecondFunction();
if (error_code != 0) {
return error_code;
}
// etc...
However, not only does this look rather cumbersome, it also has multiple return statements, and for compliance reasons at my company this is not allowed.
How can I rearrange this so that there is only one return statement, but still stop after the first error code? The only way I can think of is to do nested if statements:
int error_code = FirstFunction();
if (error_code == 0) {
error_code = SecondFunction();
if (error_code == 0) {
error_code = ThirdFunction();
// etc...
}
}
return error_code;
But this could get unreasonable pretty fast. Is there another way to do this?
EDIT: In my program, return code of 0 means success (OK) and non-zero means failure/error (NOT OK)
You don't have to nest all the function calls, the code below do the job as well and should comply with your code writing rules:
error_code = FirstFunction();
if (error_code == 0) {
error_code = SecondFunction();
}
if (error_code == 0) {
error_code = ThirdFunction();
}
// etc...
return error_code;
Here is another lean method that can return different error codes depending on which function fails:
int func(void)
{
int code;
int error_code = (code = FirstFunction()) ? code :
(code = SecondFunction()) ? code :
(code = ThirdFunction()) ? code : 0;
/* ... */
return error_code;
}
Lean and clean (like this one, but avoiding the disliked gotos):
int foo(void)
{
int error_code;
do {
if (0 != (error_code = FirstFunction()))
{
break;
}
if (0 != (error_code = SecondFunction()))
{
break;
}
...
} while (0);
return error_code;
}
This, BTW, follows the more common pattern: 0 is OK, everything else isn't. Adjust as needed)
You could even obfuscate this using a macro:
#define RUN_AND_BREAK_ON_ERROR(rc, f, ...) \
if (0 != (rc = f(__VA_ARGS__))) \
{ \
break; \
}
int foo(void)
{
int error_code;
do {
RUN_AND_BREAK_ON_ERROR(error_code, FirstFunction, <args go here>);
RUN_AND_BREAK_ON_ERROR(error_code, SecondFunction, <args go here>);
...
} while (0);
return error_code;
}
if( (error_code = FirstFunction()) || (error_code = SecondFunction()) || ... ){
return error_code ;
}
return error_code; //denoting no error.
This would return only the first function which returns nonzero. The idea is that for if statement the first function that returns nonzero would short-circuit the whole evaluation and returns the error_code from the function which returned non-zero error_code. Also another thing is value of an assignment statement is the value assigned. That's why this works.
A more easier way would be to sequential if-else
if( error_code = FirstFunction() ) {}
else if( error_code = SecondFunction() ) {}
...
return error_code;
If all these functions take the same type of parameters and have the same return type, you could put them in a function array and iterate over it. When an error is found, it simply breaks out of the loop and returns.
int (*function_array[max_array])();
/*Fill the array with the functions you need*/
for(i=0;i<max_array;i++){
if((error_code=function_array[i]())!=OK){
break;
}
}
return error_code;
(OK is whatever the success return value is for these functions)
Well, there's the one used e.g. in the Linux kernel:
int somefunc(whatever)
{
if (do_something()) {
ret = -EINVAL;
goto err;
}
if (do_something_else()) {
ret = -EPERM;
goto err;
}
/* ... */
ret = 0;
err:
some_mandatory_cleanup();
return ret;
}
But I suspect that's going to be even less well received. (Before you scream, the whole point of that is the mandatory cleanup in the end. The goto arranges it to be executed always, but still puts it out of way.)
Really, I think the code in your first snippet is fine, and the issue is with your guidelines. Even if we only write return error_code; in one place, it's not enough to guarantee that the error code saved in variable is always correct, or that the function completes all cleanup that might be required. (Consider something that allocates memory, and has to release it in any case.)
In my project I'm using a global variable but it's not working as expected because it is initialized everytime it's executed and honestly I don't know what could be going on.
The variable is cookingSignalReceived.
The program is structured as follows:
//File Controller.c:
while (1)
{
Controller_Run_State_Machine();
}
void Controller_Run_State_Machine(void)
{
/* start of activity code */
Inputs_ReadSensors();
Comms_CheckReceivedData();
Controller_UpdateSTM();
}
The problem is inside Comms file:
//File Comms.c
uint8_t cookingSignalReceived = 0;
void Comms_CheckReceivedData(void)
{
/* start of activity code */
uint8_t uartDataAvailable = Comms_R_UART0_checkIfDataAvailable();
if (uartDataAvailable == 1)
{
Comms_ParseReceivedCommand();
}
}
void Comms_ParseReceivedCommand(void)
{
/* start of activity code */
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92}:YjMeKqu95e */
uint8_t CRC_check_OK = 0;
uint8_t* buffer;
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92} */
Comms_R_UART0_resetFlag_dataAvailable();
buffer = Comms_R_UART0_getBuffer();
CRC_check_OK = Comms_crcCheck(buffer);
if (CRC_check_OK == 1)
{
Comms_processMessage(buffer); //<-- Variable is used in this function
}
}
Global variable is used inside Comms_processMessage(). The issue is that every time that the function is called, the global variable is set to the initial value. Do you find anything strange here?
EDITED:
void Comms_processMessage(uint8_t* buffer)
{
/* UserCode{BCB3B791-2DF9-492b-B53B-6FEB24BD8F77}:eyCoSfmCKb */
uint8_t message = buffer[0];
uint8_t param1 = buffer[1];
uint8_t param2 = buffer[2];
//---------------------------------------------------------------------
// START COOKING 1ST STEP REQUEST
//---------------------------------------------------------------------
if (message == MSG_COOK_1ST && param1 == START_PARAM)
{
// Wait for second frame
cookingSignalReceived = 1;
#ifdef DEBUG
R_UART0_Send("Cook 1st step!!", sizeof(char) * 15);
#endif
}
//---------------------------------------------------------------------
// START COOKING 2ND STEP REQUEST
//---------------------------------------------------------------------
else if (message == MSG_COOK_2ND && param1 == START_PARAM)
{
// Wait for second frame
if (cookingSignalReceived == 1)
{
Controller_signalsBufferEnqueue(cookingSignal);
}
#ifdef DEBUG
R_UART0_Send("Cook 2nd step!!", sizeof(char) * 15);
#endif
}
}
Note that my original idea was to use a local static variable but I was having the same issue so I tried with a global variable.
In certain cases the MCUs restart because unrecoverable errors or bad hardware settings. This should be the problem! A cause of this MCUs behaviour may be also bad pointers management.
Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !