Using Printf to display on serial port of an ARM microcontroller - embedded

I would like to use printf to diplay text on a serial port of an ARM microcontroller. I am unable to do so. Any help is appreciated.
My init_serial looks like this
void init_serial (void)
{
PINSEL0 = 0x00050000; /* Enable RXD1 TxD1 */
U1LCR = 0x00000083; /*8 bits, 1 Stop bit */
U1DLL = 0x000000C2; /*9600 Baud Rate #12MHz VPB Clock */
U1LCR = 0x00000003; /* DLAB=0*/
}
which is obviously wrong.

For microcontollers, you typically have to define your own putc function to send bytes to whichever UART you're using. print will then call your putc.
Check the documentation for the libraries supplied with your compiler.
Note that this is entirely unrelated to how you intialise your UART. All that matters is which UART you're using.
(On an unrelated issue, rather than saying:
PINSEL0 = 0x00050000; /* Enable RXD1 TxD1 */
U1LCR = 0x00000083; /*8 bits, 1 Stop bit */
there are typically #defines for registers which (usually) aid readability, provide a link to the bit names in the documentation, and reduce the need for comments to be added and maintained on every line like these. For example:
PINSEL0 = PICSEL0_RXD1EN | PICSEL0_TXD1EN;
U1LCR = U1LCR_8BITS | U1LCR_1STOPBIT;
..and so on.)

To make printf(), puts() etc work on an embedded platform, you need to implement some hooks that work with the C library. This is typically dependent on the C libraries provided with your compiler, so is probably compiler-dependent. But in many cases the library just requires you to provide a putc() function (or similar name), which takes a character (generated by the printf() library function) and sends it to your chosen output device. That could be a memory buffer, serial port, USB message, whatever.
From the point of view of the C library, the putc() function would be run-to-completion, so it's up to you whether you implement it to be a simple blocking function (waiting until the serial port is free and sending the character), or non-blocking (putting it into a buffer, to be sent by a background interrupt task; but the buffer might fill up if you output enough bytes fast enough, and then you have to either block or discard characters). You can also make it work properly with your RTOS if you have one, implementing a blocking write that sleeps on a semaphore until the serial port is available.
So, in summary, read the documentation for your compiler and its C library, and it should tell you what you need to do to make printf() work.
Example links for AVR micro with GCC compiler:
AVR libc stdio docs
a blog post
ARM GCC compiler using newlib C library:
Newlib C library docs
Defining host interface - syscalls - write() function

I'm not sure about ARM in particular...
For some chips, within the IDE, you need to specify that you need a heap to use the printf, and how big it should be. The programmer won't automatically put one on.
Check in the menus of your programmer/IDE and see if there is a place to specify the heap size.
And I agree with Steve, this is only if you can actually use the printf, otherwise write your own little snippet.

Related

STM8S UART TX Interrupt Enable/Disable Issue

Thanks to everyone who gives an answer. But the problem is related to the compiler. I used Cosmos and STVD, it does not bind the interrupt function. When I immigrate the project to IAR, The problem is solved.
I am dealing with STM8S103F3P6 IC. I try to send a message using TX interrupt but I have never succeeded.
I have checked the example of the UART interrupt. Also, I tried to develop the same code. However, I got still zero. I took the interrupt vector function from STM8 examples. Where is my mistake? How can I figure out?
Here my init, main, and interrupt vector function;
void init_handler(void){
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
UART1_DeInit();
UART1_Init((uint32_t)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
UART1_ITConfig(UART1_IT_TXE,ENABLE);
enableInterrupts();
UART1_Cmd(ENABLE);
}
main(){
init_handler();
while(1);
}
INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17){
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
UART1_SendData8('a');
while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
}
It sends nothing. I do not have any logic analyzer, I have only checked using terminal applications.
You asked where your mistake is: that's hard to tell if you use library functions that mask the usage of peripheral configuration registers and flags by making them "readable". If you don't have a logic analyzer, pin debugging helps most of the time (e.g. toggle a GPIO when entering the ISR).
My advise is to look at the actual register manipulations and to compare those with the descriptions in the STM8S Reference Manual (even if it doesn't provide concise guidance on how to initialize, start, spin down and end a transmission).
In order to make that a little easier, I'd like to share what I learned about using a UART ISR:
Sending the contents of a buffer with UART TXE and TC interrupt events turns out not to work like in e.g. MCS51: most of it has to be done with the interrupt enable flags TIEN and TCIEN in UART_CR2.
This is what worked for me:
both TIEN and TCIEN should be normally disabled
after setting up buffers and pointers, enable TIEN to start a transmission
in the ISR, during the transmission, writing to UART_DR clears the interrupt event
in the ISR, when the buffer is empty, disable TIEN and enable TCIEN to spin down the ISR chain
in the ISR, read UART_SR to check if TC is set. If that's the case, clear TCIEN
The advantage of this procedure is that media access control, e.g. for RS485, can be done in the last step of the chain.
An example in STM8 eForth is here.
SPL and opinions about that have nothing to do with the problem. As the SPL code is open sourced you can have a look and even copy it.
UART1_IT_TXE occurs after the UART has transmitted something.
Since you don't send anything (yet) the IRQ is not triggered.
You can send a series of characters using the UART1_IT_TXE IRQ by sending the first character using the UART1_SendData and then let the IRQ handle the remaining ones.

What is the significance of the "volatile" key word with respect to Embedded Systems?

I have been recently working on learning embedded systems programming on my own. I have observed a fairly high usage of the keyword volatile qualifier when declaring variables?
What is the significance of volatile when declaring a variable in Embedded System programming?
Basically when the should the key word be used. I did read something about compiler optimization and use of the keyword. Also something related to memory mapping registers.
For example, I read this StackOverflow post but I didn't understand how it applied in an embedded environment. More specifically, I don't understand when the key word should be used. I did read something about compiler optimization and use of the keyword. Also something related to memory mapping registers, but I don't understand when to use it.
Let's have a look at an example. When you look at C header files for PIC microcontrollers, you will see that many elements are declared volatile:
extern volatile unsigned char PORTB # 0x006;
As you have read, the volatile keyword disables compiler optimization. Suppose you write a program that does the following:
PORTB = 0x00; // set all of port B low
while (PORTB == 0x00); // wait for any pin to get high
// do something else
When the compiler optimises this code, it will recognise the second line as an infinite loop: the condition is true and never gets false within its body. Therefore, everything after the infinite loop does not need to be compiled as it will never be ran. Hence, the compiler may decide to not include that part of the code in the generated assembly code.
However, this PORTB is actually linked to a physical port. It is a hardware port whose value may be altered by the external circuitry. This means that although the loop seems to be infinite, it doesn't have to be. The compiler can't possibly know this.
That's where volatile comes in. When PORTB is declared volatile, the compiler won't do any optimisation based on reasoning about PORTB. It will assume that its value may be changed at any time by external factors.
In the embedded systems world, one of the key aspects of the volatile key-word is that it denotes a variable that may change at any time (eg an external/hardware data input - eg an ADC) and therefore the compiler must not optimise use.
But specifically, when used with a control register, it indicates that a read access may in fact change the data!
As a general rule of thumb, I would recommend the use of the volatile qualifier in all of the following:
All hardware register accesses(read and write)
All variables that are accessible in multiple threads (especially interrupt handlers)
Note: accessing a volatile is not necessarily atomic, so it is imperative that you know your hardware and your code structure.
The volatile keyword is primarily used tell the compiler the value of the variable may change anytime. It also tells the compiler the not to apply optimization on the variable. I am not too much of an expert on this but below is good reference that I have referred in the past.
volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time-without any action being taken by the code the compiler finds nearby. The implications of this are quite serious. However, before we examine them, let's take a look at the syntax.
Reference:
Introduction to the volatile keyword
Let me put it in other perspective it is exactly opposite of const keyword.
When compiler encounters const qualifier for any variable it checks if any function or statement is modified it once initialized. Hence flag error.
Volatile is exactly opposite, this variable can be changed by any function. Hence compiler does not apply optimization.
You see this mostly in embedded system programming due to use of interrupts and some programming logic constructs seems redundant.
While the statements about optimization are correct, they seem a little unclear to me. Here is what is really going on.
If you don't use the volatile keyword C may optimize that variable into a register it isn't using at the time. This will make for fewer assembly instructions and the code will execute faster.
For example, consider the following...
extern int my_port; // my_port is defined in a different module somewhere
// presumably a memory mapped hardware port
while (my_port > 0) {so stuff}
The compiler may decide to read my_port into a register only once before the actual while statement, then each time to test my_port it will look at the register not the memory location.
If, however, my_port is a hardware port, the port may change but register won't and the while conditional will not change.
The loop variable (the register) will be "out of phase" with the actual variable (my_port).
Thus the need for the keyword volatile.
Volatile tells C, "Don't optimize this variable into a reg, but read it each and every time you need it."
More instructions are generated, code is a bit slower, but it is always accurate.

How do I debug unexpected resets in a STM32 device?

I'm doing some development in C with a STM32F107 chip and, at some point, the device began to reset when I call a specific function. I don't have a debugger and my debugging is just plain text over a serial port.
I've used some other microcontrollers in which I was able to access a register to see the cause of the reset, but I can't seem to find an equivalent for this device. I'm aware of the hardware exceptions of the Cortex-M3, but I don't know if one of them is being triggered since I can't seem to send text over usart when I'm inside those handlers (maybe because my TX functions use interruptions?).
So, I decided to ask people with more experience than I in this device: what is usually done to debug situations like these?
EDIT
One of the developers activated the WWDG watchdog and it was reseting the hardware before I could get my info from the fault handlers. It was a Hard Fault due to calling a function by a pointer that was pointing to the wrong place. However, I will keep this question in the hope that someone will give more details (or material about it) for pointing back to C code from the registers saved in, lets say, a Hard Fault (#dwelch idea).
The Cortex M3 has excellent fault handling features that will make your life easier. On hitting a fault, it automatically stacks several registers like PC and LR, and fault status registers will tell you things like address of bus fault, etc.
You should implement a good fault handler (for example, the hard fault handler here: http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/) to print out the stacked registers and debug fault status registers.
You should use the UART for printing, just write your own simple custom version of printf for use from your fault handler that doesn't depend on interrupts. Just write bytes directly to uart Tx data register and poll for byte completion.
Aside from what has been mentioned about the interrupt handlers for debugging, some ST micros also have a reset source register that you can read on power-up (that is after a reset). For the cortex M family (m0/m3/m4) the register is RCC_CSR. http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf
Unfortunately you wouldn't be able to know whether the specifics, such as hard fault but it would tell you if the watchdog (window or independent) had tripped.
Given that you don't have a debugger, I would suggest that you find some peripheral on the microcontroller to help you. Perhaps you have an LED you can toggle or a simple GPIO pin that isn't being used that you can hook up to an oscilloscope. If you toggle a GPIO pin slowly enough (no faster than 1 Hz and maybe more slowly depending on the meter) you can use a volt meter instead of a scope. Put the code to toggle the LED or GPIO pin in each of the exception handlers one at a time until you track it down. If you have more than one GPIO pin available you can speed up the process. You can also write a wrapper for the specific function that is causing the reset. The wrapper function would send a list of interrupts that are enabled just before the breaking function is executed. This way you don't have to waste time testing the ones that are not enabled.
One advantage of GPIO pins in this case is they don't require an interrupt. It is best to stay away from anything that requires an interrupt (like your USART in this case). If the reset is being caused by a higher priority exception your debugging code will never execute.
It is also common that the reset is caused by an uninitialized pointer. A function pointer set to zero would cause execution to look a lot like a reset. If this is the case, the USART initialization code is probably being executed before a byte can be fully transmitted by the USART which would render the USART useless as a debugging tool in this instance.
When you say reset I think in terms of you hit the reset vector, not one of the interrupts or handlers. Are you saying that it does indeed reset the chip and start your software over again or are you saying that it is hanging somewhere? or do you have the vector table all point at the reset vector?
How to proceed depends on what you are really seeing, you need to be more clear or specific, or maybe you want help figuring that out.
Normally I map the unused vectors to a simple hang line of code which branches to itself. Later I may remap some of them to real code.
the cortex-m is very nice in that you can point at C code. If you think you are getting an exception have it point at a routine that grabs something that helps you figure out what mode you are in, the link register might have that info, or a csr somewhere, print that out and go into an infinite loop. Fill up the unused portions of the vector table with the address to this generic debug function.
From there you need to figure out why you are hitting that exception, it could be something like an unaligned access for example. It could be that you have generated an interrupt when trying to initalize a device before completely setting up the handler, who knows.
edit your question with more answers or information as you work through this.
You can use below code for debugging.
void HardFault_Handler(void)
{
__asm volatile
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
);
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
Also add this as well.
void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )
{
/* These are volatile to try and prevent the compiler/linker optimising them
away as the variables never actually get used. If the debugger won't show the
values of the variables, make them global my moving their declaration outside
of this function. */
volatile uint32_t r0;
volatile uint32_t r1;
volatile uint32_t r2;
volatile uint32_t r3;
volatile uint32_t r12;
volatile uint32_t lr; /* Link register. */
volatile uint32_t pc; /* Program counter. */
volatile uint32_t psr;/* Program status register. */
r0 = pulFaultStackAddress[ 0 ];
r1 = pulFaultStackAddress[ 1 ];
r2 = pulFaultStackAddress[ 2 ];
r3 = pulFaultStackAddress[ 3 ];
r12 = pulFaultStackAddress[ 4 ];
lr = pulFaultStackAddress[ 5 ];
pc = pulFaultStackAddress[ 6 ];
psr = pulFaultStackAddress[ 7 ];
/* When the following line is hit, the variables contain the register values. */
for( ;; );
}
I am using this to get any value of the register before going into hardfault. You can also add more registers if you like.
The "right" thing to do, is, unfortunately not practical with an STM32. That would be to put in a big exception handler that has knowledge of the source code, and can unwind the stack and give you the full call stack and line number that cause the fault. This would require adding all the debug information from your application into the flash memory of the STM32, and that's not practical.
There are ways of tricking your IDE to sometimes give you the call stack. I'd give details but I forgot to write them down, so I've forgotten. I think it has to manually changing the stack pointer from one shadow register to another.
What I usually do is to put a breakpoint at the hard fault exception vector, and then look at all the registers when the break point hits. Consider them forensic evidence from a murder, done with plastic explosives. The values of the registers will give you ideas. Register values that start with 0x20000000 are RAM addresses. Register values that start with 0x08000000 are Flash addresses. Open up the disassembler and type in those addresses. It will probably go straight to the variable or function at those memory locations. If that doesn't help, then look at the stack pointer. Look at the memory locations at the stack pointer, and do the same trick. I have always found enough shrapnel to location the function where the exception was happening.

How to do Binary instrumentation of syscall brk ? (x86-64 Linux) (maybe valgrind?)

I'd like to instrument syscall brk (and other calls but this in first order, it's most important to me) in given binary (preferably on actual syscall/sysenter level (x86-64 and x86) of making sys_brk call).
Main goal:
A part of sandbox which gives fixed amount of memory to jailed process
So, I'd like to get rid of brk system calls (and most preferably others in next order) and simulate memory allocations under fixed limit. Fixed limit is memory space, available to program. (You can think about it like making a kind of sandbox with fixed amount of available memory)
How to implement (one of) some example possible solutions (or yours solution):
just changing instructions to NOP
As brk returns 0 on success, simulate it's successes with setting operations that sets memory (register) state , as brk would be called with success.
More complex... instrument with code (or function call) which simulates success memory allocations under fixed limit.
Most flexible (maybe overkill in my case) to change this syscall into function call and add provided function to binary.
Given binary is code that can be malicious in one of two (most preferably both :) ) forms:
shared library - here I can setup environment before function call (for example do brk call in controlled way)
program binary - in this case we need to give program fixed amount of memory (by caller, or on begining of program "one syscall"), cause it can not allocate. Example of calling such program should be included in answer.
As problem is highly connected with many other aspects, I tried do my best in separating it as question, but please give me advice if I should specify something more or less.
Answers with implementation, links to resources (books, tutorials) are welcome.
(I am most interested in Linux, and solution that is reliable, so that people preparing binaries, even in assembler, would not have to worry about execution of their code)
LD_PRELOAD will trap C calls to brk(), but it won't trap the actual system call (int/syscall instruction). There's no portable way to trap those, but on Linux, ptrace will do it. Memory can also be allocated to a program by mmap(), so you'll need to intercept that call too.
Of course, what it seems you're really looking for is rlimit().
Yeah, I don't think you want valgrind for this.
You can use LD_PRELOAD or linker tricks to capture brk(2): see these other discussions:
Function interposition in Linux without dlsym
Overriding 'malloc' using the LD_PRELOAD mechanism
Code might look like this:
#include <unistd.h>
#include <dlfcn.h>
/* prototype int brk(void *addr); */
static int (*real_brk)(void *addr) = NULL;
int brk(void * addr) {
real_brk = dlsym(RTLD_NEXT, "brk");
if (real_brk == NULL) {
fprintf(stderr, "error mapping brk: %s\n", dlerror());
return -1;
}
printf("calling brk(2) for %p\n", addr);
return (real_brk (addr));
}`
and then LD_PRELOAD that to intercept brk(2)

passing args in interrupt handler

consider we're writing a firmware for a baremetal MCU, i.e. no OS. I'm told it's not possible (illegal?) to pass arguments to interrupt handler function?
I can't precisely understand why it is so? What's wrong with this?
PS. is it possible to do in some RTOS-es, embedded Linux etc. or it si fundamentally wrong ?
Interrupts. do just that...interrupt. Imagine the doorbell at your home, interrupting you at any particular random time day or night. Can you be expected to at any moment have all the right items in your hand for any particular interrupt that can occur. You have to be able to cook dinner, take a shower, fold the laundry but just BEFORE the doorbell rings you must have exactly the correct items in both hands depending on the person ringing the bell, without any way of knowing they are there or are coming or are about to ring the bell. Not really possible. Same deal here, interrupts come at any particular time, for most processors immediately after the currently executing instruction, the interrupt handler is called, which means every single instruction would have to be trying to perform the foreground application while keeping all the parameters for the interrupt handler, and do all of this in one instructions time.
Now what is possible is with an operating system, or rtos or call it what you will, some layer. To have the real interrupt handler that knows nothing going in and has to figure it out, once it figures out what the interrupt is about to gather info and then call a high level interrupt handler that is passed parameters. Certainly possible and most/many operating systems do it this way.
No parameters can be explicitly passed to an interrupt handler because it is designed to be called by the hardware. Each architecture imposes a particular stack frame when it is called, typically including the saved state of the CPU.
If you also intend to call the interrupt handler from elsewhere in the code, you have either a design flaw, or there is some common code which could be factored out to be shared between the interrupt handler and the algorithmic code.
The only other thing I'll point out (that hasn't been mentioned so far) is the concept of a "software interrupt" (sometimes called a "trap"), which most processors support.
The idea is that a special instruction causes an exception to take place, and often with a software interrupt, either the opcode causing the exception, or registers set up prior to the exception, can contain values/arguments.
For example, in ARM processors, look up "SWI" or "SVC", depending on your architecture. I believe with the SWI instruction, the lower 8 bits are not part of the opcode - you can fill in whatever you want & pass a value from 0-255 (memory a little fuzzy here).
Unlike a hardware-initiated interrupt, which is totally asynchronous to the code running on the CPU, a software interrupt is synchronous - it occurs when the initiating instruction is executed (barring interrupt masking, nesting, etc.)
An interrupt handler is called by the hardware. It is "passed" whatever "arguments" the hardware passes it.
That's all there is.
when you setup an interrupt handler using the call below, it looks like the interrupt handler takes some args and returns irqreturn_t. Is this not the same interrupt handler OP is talking about?
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
You can use shared variables set during normal code flow to affect the behaviour of an interrupt handler the next time it runs. But because you do not call the ISR directly, you cannot pass arguments. It is not a matter of legality, but rather technicality.
eg:
volatile enum
{
DO_NOTHING,
DO_A,
DO_B,
DO_C
} isr_action ;
__interrupt (SOME_IRQ) myISR()
{
switch isr_action
{
case DO_A :
{
// A
}
break ;
case DO_B :
{
// B
}
break ;
case DO_C :
{
// C
}
break ;
}
}
int main()
{
// Make ISR do A on next SOME_IRQ
isr_action = DO_A ;
for(;;)
{
// wait for interrupt
}
}