Function Pointer in C Using ARM
Function Pointer in C Using ARM
Function pointers in C are variables that can store the memory address of functions and can be used in a
program to create a function call to functions pointed by them. Declaration of function pointers in C
includes the return type and data type of different function arguments.
Syntax of Function Pointer in C:
return_type (* pointer_name) (datatype_arg_1, datatype_arg_1, ...);
Suppose we declare a function and its pointer as given below.
To call the function areaSquare, we can create a function call using any of the three ways:
int length = 5;
int area = areaSquare(length); // 1. using function name
Preliminary Example:
#include <stdio.h>
Int Compare(int a, int n){
If(a>b) return 1;
Else return -1;
}
void MSort(int A[], int n, int (*compare)(int,int){
int I,j,temp;
for(i=0; i<n; i++)
for(j=0; j<n; j++){
if(compare(A[j],A[j+1])>0){
temp =A[i];
A[i]=A[j];
A[j]=temp;
}
}
1
Example: Array of function pointers
Arrays are data structure that stores collection of identical data types. Like any other data types, we
can create an array to store function pointers in C. Function pointers can be accessed from their indexes
like we access normal array values arr[i]. This way we are creating an array of function pointers, where
each array element stores a function pointer pointing to different functions. This approach is useful
when we do not know in advance which function is called, as shown in the example.
#include<stdio.h>
float add(int, int);
float multiply(int,int);
float divide(int,int);
float subtract(int,int);
int main() {
int a, b;
float (*operation[4])(int, int);
operation[0] = add;
operation[1] = subtract;
operation[2] = multiply;
operation[3] = divide;
printf("Enter two values ");
scanf("%d%d", &a, &b);
float result = (*operation[0])(a, b);
printf("Addition (a+b) = %.1f\n", result);
result = (*operation[1])(a, b);
printf("Subtraction (a-b) = %.1f\n", result);
result = (*operation[2])(a, b);
printf("Multiplication (a*b) = %.1f\n", result);
result = (*operation[3])(a, b);
printf("Division (a/b) = %.1f\n", result);
return 0;
}
2
}
Practical Application:
unsigned int Cnt_Task =0;
void(* G_User_API)(void);
void Task1(){
GPIOD_ODR.B0 =1;
GPIOD_ODR.B1 =0;
GPIOD_ODR.B2 =0;
GPIOD_ODR.B3 =0;
}
void Task2(){
GPIOD_ODR.B0 =0;
GPIOD_ODR.B1 =1;
GPIOD_ODR.B2 =0;
GPIOD_ODR.B3 =0;
}
void Task3(){
3
GPIOD_ODR.B0 =0;
GPIOD_ODR.B1 =0;
GPIOD_ODR.B2 =1;
GPIOD_ODR.B3 =0;
}
void Task4(){
GPIOD_ODR.B3 =1;
GPIOD_ODR.B1 =0;
GPIOD_ODR.B2 =0;
GPIOD_ODR.B0 =0;
}
void SetUserAPI(void(* Fun_Ptr)(void)) {
G_User_API= Fun_Ptr;
}
void TIM2_IRQHandler() iv IVT_INT_TIM2 ics ICS_OFF {
// Interrupt service routine code
G_User_API();
TIM2_SR &=~TIM2_SR.UIF;
TIM2_CNT &= 0x0 ;
Cnt_Task++;
Cnt_Task %= 4;
void InitTimer2(void){
TIM2_PSC=32000;
TIM2_ARR =250;
TIM2_DIER.UIE=1;
TIM2_CR1.CEN=1;
TIM2_CR1 |= 1<<0; //Counter enabled
4
TIM2_CR1 |= 1<<7; // Auto reload preload enable is buffered
TIM2_SR &= 0<<0;
TIM2_CNT &= 0x0 ;
EnableInterrupts();
NVIC_IntEnable(IVT_INT_TIM2);
}
void main() {
RCC_APB1ENR.TIM2EN=1;
RCC_APB2ENR.IOPDEN=1;
GPIOD_CRL=0x44442222;
GPIOD_CRH=0x44444444;
//GPIO_Digital_Output(&GPIOD_ODR,_GPIO_PINMASK_2);
InitTimer2();
while(1){
switch(Cnt_Task){
case 0: {SetUserAPI(Task1); break; }
case 1: {SetUserAPI(Task2); break; }
case 2: {SetUserAPI(Task3); break; }
case 3: {SetUserAPI(Task4); break; }
default: break;
}
}
}