Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Declaring a callback function in `usart.h`, using it in `usart.c` but defining it in `main.c`

Post

Declaring a callback function in usart.h, using it in usart.c but defining it in main.c

+4
−0

I have written a generic device driver for a uart peripheral with a source file usart.c and a header file usart.h. I don't want a user of these files have to tamper with them.

I want to use the usart peripheral in an interrupt driven fashion, where I store the incoming byte in a ring-buffer, but I'm a unsure of the correct way to do it. I am thinking of doing it like below, by declaring the callback function in the header file, using it in the source file, and then defining what the callback function does in main.c.

/* usart.h */
...
void usart_callback();
...
/* usart.c */
#include "usart.h"

uint8_t usart_recieve()
{
    /* ... */
}

ISR(USART_RX_vect) //Interrupt automatically issued when new byte in UDR0 register
{
    usart_callback();
}
/* main.c */
#include "usart.h"

#define RB_SZ 32
volatile bool usart_semaphore = false;

static struct usart_rb_t
{
    uint8_t buf[RB_SZ];
    volatile uint8_t head;
    volatile uint8_t tail;
} usart_rb;

void rb_put(uint8_t val);

void usart_callback()
{
    rb_put(UDR0); //Insert byte into ring-buffer.
}

int main(void)
{
    for(;;)
    {
        /* Program execution */
    }
}

But I have a gut feeling that this is wrong. It feels wrong that I handle an intrinsic uart construct UDRE0 in main.c when it feels like it belongs in usart.c. It also feels weird to me to define a function in main.c but the place it is called is in usart.c. Almost like spaghetti. I have also prematurely defined a semaphore construct to guard against a possible race condition but have not yet figured out how to apply that correctly either.

History

1 comment thread

Why callback function? (1 comment)
Why callback function?
Olin Lathrop‭ wrote 7 days ago

What do you need a callback function for in the first place? What asynchronous thing do you want the UART to notify the application of? What's wrong with the usual UART_PUT and UART_GET (and a few others) routines for the application to call?