📖 Scenario: You are working on a small embedded system that uses a UART (Universal Asynchronous Receiver/Transmitter) to send messages to a computer. Normally, printf sends output to a console, but your system does not have one. You want to redirect printf output to the UART so you can see messages on your computer.
🎯 Goal: Build a simple program that redirects printf output to the UART by implementing the _write function. This will let you send text messages from your embedded device to a computer through UART.
📋 What You'll Learn
Create a UART transmit function called UART_Transmit that sends a single character.
Create a _write function that printf uses to send characters.
Redirect printf output to UART by calling UART_Transmit inside _write.
Use printf to send a test message through UART.
💡 Why This Matters
🌍 Real World
Embedded systems often lack screens or consoles. Redirecting <code>printf</code> to UART lets developers see debug messages on a computer.
💼 Career
Embedded software engineers frequently redirect standard output to hardware interfaces like UART for debugging and communication.
Progress0 / 4 steps
1
Create UART Transmit Function
Create a function called UART_Transmit that takes a char parameter named ch and sends it. For this example, just write an empty function body to simulate sending.
Embedded C
Hint
This function will send one character over UART. For now, just create the function with an empty body.
2
Add _write Function to Redirect printf
Add a function called _write with parameters int file, char *ptr, and int len. Inside, use a for loop with variable i from 0 to len to call UART_Transmit(ptr[i]) for each character. Return len at the end.
Embedded C
Hint
The _write function is called by printf to send characters. Use a loop to send each character through UART_Transmit.
3
Include and Write main Function
Add #include <stdio.h> at the top. Then write a main function that calls printf("Hello UART!\n") and returns 0.
Embedded C
Hint
The main function runs your program. Use printf to send a test message through UART.
4
Print the Test Message
Run the program and observe the output. The program should print Hello UART! through the UART by calling printf("Hello UART!\n").
Embedded C
Hint
When you run the program, the message Hello UART! should appear on your UART terminal.
Practice
(1/5)
1. What is the main purpose of overriding the fputc function in embedded C when redirecting printf output to UART?
easy
A. To clear the UART receive buffer
B. To change the baud rate of the UART communication
C. To initialize the UART peripheral before use
D. To send each character from printf to the UART hardware for transmission
Solution
Step 1: Understand printf output mechanism
The printf function sends characters one by one to fputc for output.
Step 2: Role of overriding fputc
By overriding fputc, we redirect each character to UART transmit function, sending it out via UART.
Final Answer:
To send each character from printf to the UART hardware for transmission -> Option D
Quick Check:
Overriding fputc redirects output to UART [OK]
Hint: Remember: printf calls fputc for output [OK]
Common Mistakes:
Confusing fputc with UART initialization
Trying to change UART settings inside fputc
Ignoring that printf uses fputc internally
2. Which of the following is the correct prototype for overriding fputc to redirect printf output to UART in embedded C?
easy
A. char fputc(int ch, FILE *f);
B. void fputc(char ch);
C. int fputc(FILE *f, char ch);
D. int fputc(char ch, FILE *f);
Solution
Step 1: Recall standard fputc signature
The standard fputc function prototype is int fputc(int ch, FILE *stream);.
Step 2: Match options with correct signature
char fputc(int ch, FILE *f); matches the correct order and types: returns char (though standard is int), takes int and FILE pointer.
Final Answer:
char fputc(int ch, FILE *f); -> Option A
Quick Check:
Correct fputc prototype returns int and takes int, FILE* [OK]
Hint: Prototype must match standard fputc signature [OK]
Common Mistakes:
Swapping parameter order
Using void return type
Using wrong parameter types
3. Given the following code snippet, what will be the output on the UART terminal?
int fputc(int ch, FILE *f) {
UART_SendChar((char)ch);
return ch;
}
int main() {
printf("Hi\n");
return 0;
}
medium
A. Only 'H' is sent to UART
B. No output because UART_SendChar is not defined
C. Hi followed by a newline on UART terminal
D. Compilation error due to missing UART initialization
Solution
Step 1: Understand fputc role in printf
Each character of "Hi\n" is sent to fputc, which calls UART_SendChar to send it.
Step 2: Output on UART terminal
Characters 'H', 'i', and newline '\n' are sent sequentially, so "Hi" and a newline appear on UART terminal.
Final Answer:
Hi followed by a newline on UART terminal -> Option C
Quick Check:
printf output redirected via fputc to UART [OK]
Hint: Each printf char calls fputc, which sends via UART [OK]
Common Mistakes:
Assuming no output without UART initialization code shown
Thinking only first char is sent
Confusing compile errors with runtime behavior
4. Identify the error in this fputc override code that tries to redirect printf to UART:
int fputc(int ch, FILE *f) {
UART_SendChar(ch);
return 0;
}
medium
A. Returning 0 instead of the character causes incorrect printf behavior
B. Passing ch directly to UART_SendChar causes type mismatch
C. Missing UART initialization before sending characters
D. Function should return void, not int
Solution
Step 1: Check return value of fputc
The fputc function must return the character written on success, or EOF on failure.
Step 2: Analyze the code's return statement
Returning 0 (null char) instead of the character can cause printf to misbehave or stop output prematurely.
Final Answer:
Returning 0 instead of the character causes incorrect printf behavior -> Option A
Quick Check:
Return written char from fputc to keep printf working [OK]
Hint: Always return the character from fputc [OK]
Common Mistakes:
Returning 0 instead of the character
Ignoring return value importance
Assuming void return type is allowed
5. You want to redirect printf output to UART and also support multiple UART ports. Which approach correctly extends fputc to select UART port dynamically?
hard
A. Create separate fputc functions for each UART port and call them manually
B. Use a global variable to store current UART port and send chars accordingly inside fputc
C. Modify printf to accept UART port as parameter
D. Use interrupts to switch UART ports automatically during fputc
Solution
Step 1: Understand fputc limitation
Only one fputc function can be linked, so multiple versions are not possible.
Step 2: Use global variable for UART selection
By storing the current UART port in a global variable, fputc can send characters to the selected UART dynamically.
Step 3: Evaluate other options
Modifying printf is complex; interrupts do not switch ports automatically; multiple fputc functions cause conflicts.
Final Answer:
Use a global variable to store current UART port and send chars accordingly inside fputc -> Option B
Quick Check:
Global UART selector enables dynamic port choice in fputc [OK]
Hint: Use global UART variable to select port inside single fputc [OK]
Common Mistakes:
Trying multiple fputc functions
Changing printf signature
Relying on interrupts to switch UART ports
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.