Why no effect of calling functions with void keyword?

1

I need to write quite simple program which makes LED diode flashes using processor ARM AT91SAM9263. I need to run this code using QEMU emulator, which is installed on my Ubuntu machine. I am trying to write a program with 4 functions, which are initializing LED ports and Buttons ports, which are flashing LED diodes and checks the Buttons status (if it is pulled or not).
I have defined base registers, although I have a problem with making LED diodes to switch them on/off and to check buttons status. Simply, nothing happens. Below is my code:

#include <stdio.h>
#include "AT91SAM9263-EK.h"
#include "AT91SAM9263.h"
#include "project.h"
#include <stdint.h>
#include <stdbool.h>
#define AT91B_LED1     AT91C_PIO_PB8   /* DS1 */
#define AT91B_LED2    AT91C_PIO_PC29  /* DS2 */
#define AT91B_NB_LEB         2
#define AT91D_BASE_PIO_LED1  (AT91C_BASE_PIOB)
#define AT91D_BASE_PIO_LED2  (AT91C_BASE_PIOC)
#define AT91D_ID_PIO_LED1    (AT91C_ID_PIOB)
#define AT91D_ID_PIO_LED2    (AT91C_ID_PIOC)
#define AT91B_BP1       AT91C_PIO_PC5  // Left click#
#define AT91B_BP2       AT91C_PIO_PC4  // Right click
#define AT91D_BASE_PIO_BP    AT91C_BASE_PIOC
#define AT91D_ID_PIO_BP      AT91C_ID_PIOCDE

void LedPortInit()
{
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOCDE ); // peripheral clock enable register (port C, D, E)/* Set the PIO line as input */
AT91D_BASE_PIO_LED1->PIO_ODR = 0x0000000F;
AT91D_BASE_PIO_LED1->PIO_PER = AT91C_PIO_PB8;
AT91D_BASE_PIO_LED2->PIO_OER = AT91C_PIO_PC29 ;
AT91D_BASE_PIO_LED2->PIO_PER = 0xFFFFFFFF;// 1 – Enable PIO to control the pin
AT91C_BASE_PIOE->PIO_PER = AT91C_PIO_PB31;/* Disable pull-up */
AT91C_BASE_PIOA->PIO_PPUDR = 0xFFFF0000;
}
void ButonPortInit()
{
  AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOCDE ); // peripheral clock enable register (port C, D, E)/* Set the PIO line as input */
  AT91C_BASE_PIOD->PIO_ODR = 0x0000000F;
  AT91C_BASE_PIOD->PIO_PER = AT91C_PIO_PC5;
  AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PC4 ;
  AT91C_BASE_PIOD->PIO_PER = 0xFFFFFFFF;// 1 – Enable PIO to control the pin
  AT91C_BASE_PIOE->PIO_PER = AT91C_PIO_PB31;/* Disable pull-up */
  AT91C_BASE_PIOA->PIO_PPUDR = 0xFFFF0000;
}
void LedSwitch()
{

while(1)
{
  AT91B_LED1->AT91C_PIO_PB8  ^= 1;
}
AT91C_PIO_PC29  << 29 ;

}
void ButtonTest()
{
AT91C_PIO_PC5  << 5;
AT91C_PIO_PC4  << 4;
}
int main(void)
{
LedPortInit();
void ButonPortInit();
void LedSwitch();
void ButtonTest();

}
c
ubuntu
arm
qemu
atmel
asked on Stack Overflow Dec 23, 2020 by wiki11ful • edited Dec 23, 2020 by Yunnosch

5 Answers

3

These lines are mistaken by the compiler to be prototypes, i.e. function declarations without a runtime effect:

void ButonPortInit();
void LedSwitch();
void ButtonTest();

Turn them into function calls like this:

ButonPortInit();
LedSwitch();
ButtonTest();

To demonstrate I offer this MRE with a lot less environment-specific and embedded stuff. The problem and the solution are the same.

#include <stdio.h>

void test1()
{   printf("test 1!\n");}
void test2()
{   printf("test 2!\n");}

int main()
{
    printf("Hello, World!\n");
    
    void test1();
    test2();

    return 0;
}

Output:

Hello, World!
test 2!

You can see that as in your problem description, "Simply, nothing happens." for void test1(); but there is an output for test2();.

answered on Stack Overflow Dec 23, 2020 by Yunnosch • edited Dec 23, 2020 by Yunnosch
1

Notice that keywords that are used behind the function names refers to the return value type.

But here you just want to call the function and this operation doesn't pertain to the return value type(I mean just the calling).

So just use:

ButonPortInit(); LedSwitch(); ButtonTest();

answered on Stack Overflow Dec 23, 2020 by Darcy
1

Why no effect of calling functions with void keyword?

void ButonPortInit();
void LedSwitch();
void ButtonTest();

Because these are not function calls. Expressions in this form are function prototypes. To turn them into function calls you need to remove the void keyword.

However,

(void) ButonPortInit();

is a valid function call. (void) in this case is not the return type, but a type conversion operator. It means to cast the return value of ButtonPortInit() to void. It is often used to explicitly specify that the return value of a function should be discarded.

answered on Stack Overflow Dec 25, 2020 by John Doe
0
extern void x ( unsigned int );
void one ( void )
{
    x(1);
}
void two ( void )
{
    x(2);
}
int test0 ( void )
{
    void one();
    void two();
    return(0);
}
int test1 ( void )
{
    one();
    two();
    return(0);
}


Disassembly of section .text:

00000000 <one>:
   0:   e92d4010    push    {r4, lr}
   4:   e3a00001    mov r0, #1
   8:   ebfffffe    bl  0 <x>
   c:   e8bd4010    pop {r4, lr}
  10:   e12fff1e    bx  lr

00000014 <two>:
  14:   e92d4010    push    {r4, lr}
  18:   e3a00002    mov r0, #2
  1c:   ebfffffe    bl  0 <x>
  20:   e8bd4010    pop {r4, lr}
  24:   e12fff1e    bx  lr

00000028 <test0>:
  28:   e3a00000    mov r0, #0
  2c:   e12fff1e    bx  lr

00000030 <test1>:
  30:   e92d4010    push    {r4, lr}
  34:   e3a00001    mov r0, #1
  38:   ebfffffe    bl  0 <x>
  3c:   e3a00002    mov r0, #2
  40:   ebfffffe    bl  0 <x>
  44:   e3a00000    mov r0, #0
  48:   e8bd4010    pop {r4, lr}
  4c:   e12fff1e    bx  lr
answered on Stack Overflow Dec 25, 2020 by old_timer
0

I have found full solution, I just needed to activate additional registers PIO_SODR and PIO_CODR as below:

void LED1_SwitchOn(){
    *PIOB_CODR = AT91B_LED1;
}

void LED2_SwitchOn(){
    *PIOC_CODR = AT91B_LED2;
}

void LED1_SwitchOff(){
    *PIOB_SODR = AT91B_LED1;
}

void LED2_SwitchOff(){
    *PIOC_SODR = AT91B_LED2;
}

int BP1_Status(){
    return  (((*PIOC_PDSR) >> BP1 ) & 1);
}

int BP2_Status(){
    return  (((*PIOC_PDSR) >> BP2 ) & 1);
}

void delay(long long int time_delay){
    for (volatile long long int i = 0; i < 100000 * time_delay; i++);
}

int main(void) {
    LED1Port_Init();
    LED2Port_Init();
    enable_PMC();
    Button1Port_Init();
    Button2Port_Init();
  long long int time_delay=0;
    while (1)
    {

        LED1_SwitchOn();

        for (volatile long long int i = 0; i < DELAY; i++)
        {

            if (BP1_Status() == 0) //button1 switches on diode
                LED2_SwitchOn();
        delay(time_delay);
            if (BP2_Status() == 0) //button2 switches off diode
                LED2_SwitchOff();

        }

        LED1_SwitchOff();
    }


    return 0;
}
answered on Stack Overflow Jan 18, 2021 by wiki11ful

User contributions licensed under CC BY-SA 3.0