访问GPIO AM335x板作为重置和最低CPU使用率
在我的应用程序中,有一个线程负责重置按钮,该按钮被按下的时间和时间;在此基础上,我们采取行动。 问题在于尽量减少CPU使用: 1.访问GPIO AM335x板作为重置和最低CPU使用率,c,linux,embedded,embedded-linux,gpio,C,Linux,Embedded,Embedded Linux,Gpio,在我的应用程序中,有一个线程负责重置按钮,该按钮被按下的时间和时间;在此基础上,我们采取行动。 问题在于尽量减少CPU使用: 1.popen用法fp=popen(重置GPIO值,“r”)具有75%的CPU消耗 fopenusagefp=fopen(重置GPIO值,“r”)占用了87%的CPU openusagefd=open(仅重置GPIO值)具有95%的CPU消耗 是否有任何方法可以使用大约10-15%的CPU消耗访问GPIO 目前,在我的逻辑中,我通过上述定义方法检查重置GPIO的值,从而持
popen
用法fp=popen(重置GPIO值,“r”)此应用程序的代码>具有75%的CPU消耗
fopen
usagefp=fopen(重置GPIO值,“r”)此应用程序的代码>占用了87%的CPU
open
usagefd=open(仅重置GPIO值)此应用程序的代码>具有95%的CPU消耗
是否有任何方法可以使用大约10-15%的CPU消耗访问GPIO
目前,在我的逻辑中,我通过上述定义方法检查重置GPIO的值,从而持续检查重置GPIO。当按下按钮时,计时器启动并释放,停止计时器并计算时间差。整个操作在无限循环中运行。由于(最初)缺少有关重置\u GPIO\u值的信息,我们可以提供合理的答案
显然,您的µC板支持包为用户空间实现了Linux GPIO Sysfs接口(您应该阅读Linux BSP附带的相关文档)
基本上(如果电路板和驱动程序支持),您可以在用户空间中进行GPIO的触发中断。只需将上升
、下降
或两者都
(字面上)写入/sys/class/gpio/gpioN/edge
,以选择代码想要响应的信号边,然后在打开的文件描述符上对/sys/class/gpio/gpioN/value
执行轮询()
每次值发生相应变化时,此轮询都将返回。由于(最初)缺少有关重置\u GPIO\u值的信息,我们可以提供合理的答案
显然,您的µC板支持包为用户空间实现了Linux GPIO Sysfs接口(您应该阅读Linux BSP附带的相关文档)
基本上(如果电路板和驱动程序支持),您可以在用户空间中进行GPIO的触发中断。只需将上升
、下降
或两者都
(字面上)写入/sys/class/gpio/gpioN/edge
,以选择代码想要响应的信号边,然后在打开的文件描述符上对/sys/class/gpio/gpioN/value
执行轮询()
每次值发生相应变化时,此投票都会返回。好的,因为这有点棘手,我将告诉您需要采取哪些步骤来完成。由于这确实是一个棘手的步骤,许多人不愿意给出适当的答案,但您可以遵循这些步骤
1.你要做的是你可以先写一个内核模块。然后您可以编译它来生成.ko
文件。这是一个可加载的内核模块。编写一个可加载的内核模块,您可以在其中保存一个ISR(中断服务例程),当任何特定GPIO发生中断时,该模块将被执行。请注意,ISR也是一个函数,当接收到特定GPIO的中断时,它会自动执行
在内核模块中保留一条规定,以接受应用层进程ID
,这样一旦GPIO
中断,模块就可以从内核层向应用层发送信号
2.将其复制到您的ARM目标处理器
,然后将模块插入内核。您可以通过键入来插入模块
`insmod <your_module.ko>`
您可以直接获取代码并为此生成.ko文件。只需根据您的要求配置适当的GPIO号即可。我已配置GPIO-54
该代码仅为AM335x
处理器编写。如果您不知道如何创建.ko
文件,那么请保持冷静,谷歌“如何构建内核模块”
,您将很容易获得它
最后,您可以编写一个虚拟应用程序来测试它,该应用程序如下所示:
/********************************************************************************/
/**
* @file userApplication.c
*
* @author Sudipta Kumar Sahoo
*
* @brief An Application layer programm implementation to connect with the
* kernel layer, That receives the interrupt from the kernel space
* once the particular interrupt is received at configured GPIO pin.
*
* NOTE:: Before executing the program first mount the debugfs if it has
* not already mounted to the file system and then execute the application
* to receive the interrupt Signal in applicatio layer.
*
* The copyright notice does not evidence any actual or intended publication.
*/
/********************************************************************************/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#define SIG_TEST 44 /* we define our own signal, hard coded since SIGRTMIN
is different in user and in kernel space */
#define RUNNING 1
/********************************************************************************/
/**
* \fn void signalHandler(int n, siginfo_t *info, void *unused)
*
* @brief The receiveData function
* The function has been registered to the kernel layer debugfs file system
* When GPIO gets the interrupt it intimates to appliation process via
* signalHandler() function and the appropriate action is taken afterwards.
*
* @return NULL
*/
/********************************************************************************/
void signalHandler(int n, siginfo_t *info, void *unused)
{
printf("Application received value %i\n", info->si_int);
/* Do what ever you want to do inside this Function upon the receival of the Interrupt */
}
int main ( int argc, char **argv )
{
int configfd;
char buf[10];
/* setup the signal handler for SIG_TEST
* SA_SIGINFO -> we want the signal handler function with 3 arguments
*/
struct sigaction sig;
sig.sa_sigaction = signalHandler;
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);
/* kernel needs to know our pid to be able to send us a signal ->
* we use debugfs for this -> do not forget to mount the debugfs!
*/
configfd = open("/sys/kernel/debug/signalconfpid", O_WRONLY);
if(configfd < 0)
{
printf("Could not Open the File\n");
perror("open");
return -1;
}
sprintf(buf, "%i", getpid()); //! << Get the process ID.
if (write(configfd, buf, strlen(buf) + 1) < 0) //! << Write the details to Kernel Space.
{
perror("fwrite");
return -1;
}
/*
* Making the Application to run independently
*/
while(RUNNING)
{
printf("Waiting for Interrup Signal...\n");
sleep(1);
}
return 0;
}
/********************************************************************************/
/**
*@file userApplication.c
*
*@作者Sudipta Kumar Sahoo
*
*@brief一个应用层程序实现来连接
*内核层,它接收来自内核空间的中断
*一旦在配置的GPIO引脚接收到特定中断。
*
*注意:在执行程序之前,首先装载debugfs(如果有)
*尚未装载到文件系统,然后执行应用程序
*在应用层接收中断信号。
*
*版权声明不证明任何实际或预期出版。
*/
/********************************************************************************/
#包括
#包括
#包括
#包括
#定义SIG_测试44/*我们定义我们自己的信号,自SIGRTMIN起硬编码
用户空间和内核空间不同*/
#定义运行1
/********************************************************************************/
/**
*\fn void信号处理器(int n,siginfo\u t*info,void*unused)
*
*@简要介绍receiveData函数
*该函数已注册到内核层debugfs文件系统
*当GPIO获得中断时,它通过
*signalHandler()函数,然后执行相应的操作。
*
*@returnnull
*/
/********************************************************************************/
无效信号处理器(int n,siginfo\u t*info,无效*未使用)
{
printf(“应用程序收到值%i\n”,信息->输入);
/*在收到中断后,在该函数内执行您想要执行的操作*/
}
int main(int argc,字符**argv)
{
/********************************************************************************/
/**
* @file userApplication.c
*
* @author Sudipta Kumar Sahoo
*
* @brief An Application layer programm implementation to connect with the
* kernel layer, That receives the interrupt from the kernel space
* once the particular interrupt is received at configured GPIO pin.
*
* NOTE:: Before executing the program first mount the debugfs if it has
* not already mounted to the file system and then execute the application
* to receive the interrupt Signal in applicatio layer.
*
* The copyright notice does not evidence any actual or intended publication.
*/
/********************************************************************************/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#define SIG_TEST 44 /* we define our own signal, hard coded since SIGRTMIN
is different in user and in kernel space */
#define RUNNING 1
/********************************************************************************/
/**
* \fn void signalHandler(int n, siginfo_t *info, void *unused)
*
* @brief The receiveData function
* The function has been registered to the kernel layer debugfs file system
* When GPIO gets the interrupt it intimates to appliation process via
* signalHandler() function and the appropriate action is taken afterwards.
*
* @return NULL
*/
/********************************************************************************/
void signalHandler(int n, siginfo_t *info, void *unused)
{
printf("Application received value %i\n", info->si_int);
/* Do what ever you want to do inside this Function upon the receival of the Interrupt */
}
int main ( int argc, char **argv )
{
int configfd;
char buf[10];
/* setup the signal handler for SIG_TEST
* SA_SIGINFO -> we want the signal handler function with 3 arguments
*/
struct sigaction sig;
sig.sa_sigaction = signalHandler;
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);
/* kernel needs to know our pid to be able to send us a signal ->
* we use debugfs for this -> do not forget to mount the debugfs!
*/
configfd = open("/sys/kernel/debug/signalconfpid", O_WRONLY);
if(configfd < 0)
{
printf("Could not Open the File\n");
perror("open");
return -1;
}
sprintf(buf, "%i", getpid()); //! << Get the process ID.
if (write(configfd, buf, strlen(buf) + 1) < 0) //! << Write the details to Kernel Space.
{
perror("fwrite");
return -1;
}
/*
* Making the Application to run independently
*/
while(RUNNING)
{
printf("Waiting for Interrup Signal...\n");
sleep(1);
}
return 0;
}