FreeRTOS example for nRF9160

I found another way to set the stack and heap sizes by using the preprocessor defines. These arm_startup_nrf9160.s files are generated by uVision. I suspect it comes from the device family pack that I installed for the nRF9160.

Great - so both the issues are resolved or MPU demo is still not working?

Yes. It’s working for both demos now. I moved on to other projects using the nRF9160 and Keil uVision. I’m having issues now with printf() and redirecting I/O either through one of the UARTs or using the ITM. On Segger’s Embedded Studio, it was kind of built in and all you had to do was include stdio.h. Any ideas?

Depends on the printf implementation but it usually calls some write/put function which you can implement to redirect output to UART.

Try to define int _write(int file, char *ptr, int len) function and put a breakpoint and see if it is getting called by printf.

Yes, I tried that by using the RTE manager and redirecting I/O to user. This created a file, stdout_user.c, where a putc() function stub could be found. This function is implemented by the user (I would send out through one of the UARTs) and is ultimately called by printf. However, when I do that and include stdio.h, the nonsecure boot is interrupted. It never gets to main(). I’m not sure why this is happening. If I implement this functionality by directly sending characters out of the intended UART myself, it works. As soon as I try to get uVision to help, it never gets to main().

Any ideas?

This happens even with the empty/stub definition of putc? Can you find out why the control is not reaching to main?

Looks like it needed a little heap space from the start up file. I defined __HEAP_SIZE=128 and it started at main(). I tried to use the ITM, but I don’t see any output in the debug window. I can set up for custom user output to use the UART instead, but that will require some code. Also, the RTE doesn’t seem to set up a USART interface for the nRF9160.

Great. Now what happens if you try to define the put function in stdout_user.c to output on UART?

Yes, I can get it to print out of the UART but there is a catch. The printf() function works as is when outside a task (e.g. in main before the scheduler starts). If I try to execute it inside of a task, nothing is sent over the UART. If I set the privileged bit when I start a task that uses printf, then I see output from the UART. I can’t make every task that uses the printf function, privileged. How do I set this up? Here’s the code:

/**
 * @brief Implements the task which will blink the LEDs.
 *
 * @param pvParameters[in] Parameters as passed during task creation.
 */
void vStartBlinkyDemo( void )
{
    uint16_t i;
    static StackType_t xBlinkyTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) );
    TaskParameters_t xBlinkyTaskParameters =
    {
        .pvTaskCode     = prvBlinkyTask,
        .pcName         = "Blinky",
        .usStackDepth   = configMINIMAL_STACK_SIZE,
        .pvParameters   = NULL,
        .uxPriority     = tskIDLE_PRIORITY | portPRIVILEGE_BIT,
        .puxStackBuffer = xBlinkyTaskStack,
        .xRegions       =
        {
            { ( void *)NRF_P0_NS,   sizeof( NRF_GPIO_Type ), tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
            { 0,                    0,                       0                                                      },
        }
    };

In the meantime, I’m still interested in printing debug messages using the ITM.

You need to make UART accessible to the unprivileged task which is calling printf. You can post all the messages that you want to output to a queue and have one task which read all the messages from the queue and output them. That way only the task reading from the queue needs to call printf.

Does this work before starting FreeRTOS?

You need to make UART accessible to the unprivileged task which is calling printf. You can post all the messages that you want to output to a queue and have one task which read all the messages from the queue and output them. That way only the task reading from the queue needs to call printf.

I did this and it works. I used the same code I used for SES.

In the meantime, I’m still interested in printing debug messages using the ITM.

Does this work before starting FreeRTOS?

It does not. The code compiles with no errors, the function that is called to use the trace modules returns with no errors. However, I see no output on the printf (debug) window. All instructions to set up the debugger (JLink in my case) to use the trace module (SWO pin) is set up.

Any ideas?

Can you step through this function and see if it is writing to the relevant registers? If it does not work without FreeRTOS, then it is probably not related to FreeRTOS and may be a good question for Nordic.