那些从事简单微控制器工作的人知道在不影响微控制器的另一个任务(例如显示和SSD,播放音乐等)中,在像Ubuntu这样的操作系统的多任务环境中播放音乐等的其他任务是多么困难可以创建进程以检查输入引脚的状态,然后在其状态更改时通知主过程。多任务操作系统可以在高速处理器的帮助下一次运行多个流程。这LinuxOperating Systems providesMulti-User-Multitasking。
这Raspberrypiis a mini-computer board which is powerful enough to run large operating systems like Linux, Mac and Windows. The Linux operating systems like Archlinux ARM, OpenELEC, Pidora, Raspbmc, RISC OS and the Raspbian and alsoUbuntuversions are available for the Raspberrypi board. The device which uses the Broadcom controller chip which is a SoC (System on Chip). This SoC has the ARM11 processor which runs on 700 MHz at its core. Linux operating systems especially Ubuntu is preferred for all kind of programming and development.
In a Multitasking environment of an Operating system like Ubuntu several processes executes at the same time and the Signals provide anInter-Process Communication(IPC) method. A separate process can be created for checking the status of input pin and then notify the main process whenever their status changes. The process that has been created for differentinput pins可能会生成相同的信号,但具有不同的值以及它们与他们自己的父进程相同,这实际上是由主过程创建的。主过程的这个单个孩子通过发送消息和信号将输入的值传达给主过程。
[[wysiwyg_imageupload:10654:]]
在这个特定的项目一个家长只创造了啊ne Childs process which will then create its own Child Processes. The Grand Child Processes of the Parent processes are then used to read the status of the four input pins independently. The Child processes are made to send a signal ‘SIGUSR1’ to their own Parent process whenever the status of the input pin changes. Each Child process sends a different价值与信号一起they sent. As soon as their Parent process receives a signal, it reads the value from the signal and sends the status in the form of amessage along with a signalto the original Parent process. This forms a过程系统made up of 4 Grand Child process, a Child Process and a Parent process where the Parent is free to do its work, but the Child can get the attention of the Parent by sending signal. The diagrammatic representation of the Process System is given below:
Fig. 2: Block Diagram Of Process System Using Raspberry Pi
四个分开input readingprocesses has been created as Child process using the叉子 ()每个输入引脚的功能。这个孩子的处理不断读取特定的输入引脚并发送signalto the Parent process using杀死()function whenever the status of the pin changes.
这re are 26 connectors which can be taken out from the connector port of the Raspberrypi board. All the connector pins are taken out using 13*2 pin female connectors and at the other end of their wire 26 pin Burg stick male connectors are attached. The Burg stick male connectors allow each pin out from the Raspberrypi board to be plugged into the holes of a breadboard. There are eight general purpose IO pins on the13*2 pin connectors of the Raspberrypi董事会和其中四个引脚被选为输入,然后将四个引脚作为输出。输入引脚连接到按钮,并使用1K电阻将其拉下。输出引脚连接到LEDs通过另一组1K电阻。在这个项目中,RaspberryPi板上装有Ubuntuand is使用VNC远程访问。To access the pins that coming out of the Broadcom controller the C library “bcm2835” has been做wnloaded and installed。
分开input reading并使用库
在此项目中,使用“ sigaction()”函数为“信号处理程序”设置所需函数编写的函数是'sig_set_handler()’. This function can be used to set a particular function as the Signal Handler for a particular signal number and hence the function has only two arguments, one for the signal number and the other for the function that need to be set as the Signal Handler. The prototype of the function is given below;
void sig_set_handler(int signo,void *handler);
For example to set the following function as the Signal Handler using the ‘sig_set_handler ()’ for a signal ‘SIGUSR1’
void button_signal_handler(int sig,siginfo_t *siginfo,void *context);
这code uses the following statement;
sig_set_handler(sigusr1,&button_signal_handler);
void sig_send_val ( pid_t id, int signo, int val );
这following is the code for a Child process which will send a signal ‘SIGUSR1’ to the Parent along with a value 1, whenever the state of an input pin defined as IN_PIN1 changes with the help of ‘sig_send_val ()’
void signal_on_state_change_pin1 ( void )
{
while ( 1 ) // for continuous read
{
if ( bcm2835_gpio_lev ( IN_PIN1 ) ) // checking if pin is high
{
delay ( 50 );
if(bcm2835_gpio_lev(in_pin1))//延迟后确认高位
{
//将sigusr1信号与一个值1一起发送给父
sig_send_val ( getppid (), SIGUSR1, 1 );
做//循环直到引脚再次变低
{
while ( bcm2835_gpio_lev ( IN_PIN1 ) ) // wait till pin low
delay ( 1 );
delay ( 50 ); // confirm low after this delay
}
while ( bcm2835_gpio_lev ( IN_PIN1 ) );
//将sigusr1信号与一个值1一起发送给父
sig_send_val ( getppid (), SIGUSR1, 1 );
}
else;
}else;
delay ( 1 );
}
}
这four Child Process here are the Grand Child Processes of the original Parent processes and hence the ‘getppid ()’ function call inside the Child Process will return the process-id of its own Parent process and not the process-id of the main process. The Child process发送值以及信号仅针对自己的父母流程,该过程将send a messageto the main process each time it receives a signal form any of its Child Process. When this process calls the ‘getppid ()’ it will return the process-id of the main Parent process.
Project Source Code
###
#include
#include #include #include #include #include #include #define IN_PIN1 RPI_GPIO_P1_07
#define IN_PIN2 RPI_GPIO_P1_22
#define IN_PIN3 RPI_GPIO_P1_18
#define in_pin4 rpi_gpio_p1_16#define OUT_PIN1 RPI_GPIO_P1_15
#define OUT_PIN2 RPI_V2_GPIO_P1_13
#define OUT_PIN3 RPI_GPIO_P1_12
#Define OUT_PIN4 RPI_GPIO_P1_11void set_pins_input ( void );
void set_pins_output(void);
void set_output_pins_low(void);
void button_signal_handler(int sig,siginfo_t *siginfo,void *context);
void signal_on_state_change_pin1 ( void );
void signal_on_state_change_pin2 ( void );
void signal_on_state_change_pin3(void);
void signal_on_state_change_pin4(void);
void sig_set_handler(int signo,void *handler);
void sig_send_val ( pid_t id, int signo, int val );
void sig_send_msg(pid_t id,int signo,char *msg);
void signal_message_on_input_change ( void );
void main_signal_handler ( int sig, siginfo_t *siginfo, void *context );int main(void)
{
pid_t child_id;
如果(!bcm2835_init())
return 1;
set_pins_output();
set_output_pins_low();
set_pins_input ();
delay ( 100 );
sig_set_handler(sigusr1,&main_signal_handler);if ( ! ( child_id = fork () ) )
{
signal_message_on_input_change ();
_exit ( 0 );
}
else;while ( 1 )
delay ( 1 );bcm2835_close();
返回0;
}void signal_message_on_input_change ( void )
{
pid_t child_id [5];sig_set_handler(sigusr1,&button_signal_handler);
if ( ! ( child_id [ 0 ] = fork () ) )
{
signal_on_state_change_pin1 ();
_exit ( 0 );
}
else;if(!(child_id [1] = fork()))
{
signal_on_state_change_pin2 ();
_exit ( 0 );
}
else;if ( ! ( child_id [ 2 ] = fork () ) )
{
signal_on_state_change_pin3();
_exit ( 0 );
}
else;if ( ! ( child_id [ 3 ] = fork () ) )
{
signal_on_state_change_pin4 ();
_exit ( 0 );
}
else;while ( 1 )
delay ( 1 );
}void signal_on_state_change_pin1 ( void )
{
while ( 1 )
{
if ( bcm2835_gpio_lev ( IN_PIN1 ) )
{
delay ( 50 );
if ( bcm2835_gpio_lev ( IN_PIN1 ) )
{
sig_send_val ( getppid (), SIGUSR1, 1 );
做
{
while ( bcm2835_gpio_lev ( IN_PIN1 ) )
delay ( 1 );
delay ( 50 );
}
while ( bcm2835_gpio_lev ( IN_PIN1 ) );sig_send_val ( getppid (), SIGUSR1, 1 );
}
else;
}else;
delay ( 1 );
}
}void signal_on_state_change_pin2 ( void )
{
while ( 1 )
{
if ( bcm2835_gpio_lev ( IN_PIN2 ) )
{
delay ( 50 );
if ( bcm2835_gpio_lev ( IN_PIN2 ) )
{
sig_send_val ( getppid (), SIGUSR1, 2 );
做
{
while(bcm2835_gpio_lev(in_pin2))
delay ( 1 );
delay ( 50 );
}
while(bcm2835_gpio_lev(in_pin2));
sig_send_val ( getppid (), SIGUSR1, 2 );
}
else;
}else;
delay ( 1 );
}
}void signal_on_state_change_pin3 ( void )
{
while ( 1 )
{
if(bcm2835_gpio_lev(in_pin3))
{
delay ( 50 );
if(bcm2835_gpio_lev(in_pin3))
{
sig_send_val(getppid(),sigusr1,3);
做
{
while ( bcm2835_gpio_lev ( IN_PIN3 ) )
delay ( 1 );
delay ( 50 );
}
while(bcm2835_gpio_lev(in_pin3));sig_send_val(getppid(),sigusr1,3);
}
else;
}else;
delay ( 1 );
}
}void signal_on_state_change_pin4 ( void )
{
while ( 1 )
{
if ( bcm2835_gpio_lev ( IN_PIN4 ) )
{
delay ( 50 );
if ( bcm2835_gpio_lev ( IN_PIN4 ) )
{
sig_send_val(getppid(),sigusr1,4);
做
{
while ( bcm2835_gpio_lev ( IN_PIN4 ) )
delay ( 1 );
delay ( 50 );
}
while ( bcm2835_gpio_lev ( IN_PIN4 ) );sig_send_val(getppid(),sigusr1,4);
}
else;
}else;
delay ( 1 );
}
}void main_signal_handler ( int sig, siginfo_t *siginfo, void *context )
{
bcm2835_gpio_write ( OUT_PIN1, *( *( ( char ** ) &siginfo -> si_value ) + 0 ) );
bcm2835_gpio_write(out_pin2, *( *((char **)&siginfo-> si_value) + 1));
bcm2835_gpio_write ( OUT_PIN3, *( *( ( char ** ) &siginfo -> si_value ) + 2 ) );
bcm2835_gpio_write(out_pin4, *( *((char **)&siginfo-> si_value) + 3));
}void button_signal_handler ( int sig, siginfo_t *siginfo, void *context )
{
switch ( *( ( int * ) &siginfo -> si_value ) )
{
情况1:
sig_send_msg ( getppid (), SIGUSR1, "1 " );
break;
案例2:
sig_send_msg ( getppid (), SIGUSR1, " 1 " );
break;
案例3:
sig_send_msg(getppid(),sigusr1,“ 1”);
break;
案例4:
sig_send_msg(getppid(),sigusr1,“ 1”);
break;
};
}void set_output_pins_low(void)
{
bcm2835_gpio_write ( OUT_PIN1, LOW);
bcm2835_gpio_write ( OUT_PIN2, LOW);
bcm2835_gpio_write(out_pin3,low);
bcm2835_gpio_write ( OUT_PIN4, LOW);
}void set_pins_output(void)
{
BCM2835_GPIO_FSEL(OUT_PIN1,BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel (OUT_PIN2, BCM2835_GPIO_FSEL_OUTP );
bcm2835_gpio_fsel ( OUT_PIN3, BCM2835_GPIO_FSEL_OUTP );
bcm2835_gpio_fsel ( OUT_PIN4, BCM2835_GPIO_FSEL_OUTP );
}void set_pins_input ( void )
{
bcm2835_gpio_fsel ( IN_PIN1, BCM2835_GPIO_FSEL_INPT );
bcm2835_gpio_set_pud(in_pin1,bcm2835_gpio_pud_off);bcm2835_gpio_fsel ( IN_PIN2, BCM2835_GPIO_FSEL_INPT );
bcm2835_gpio_set_pud(in_pin2,bcm2835_gpio_pud_off);bcm2835_gpio_fsel(in_pin3,bcm2835_gpio_fsel_inpt);
bcm2835_gpio_fsel(in_pin3,bcm2835_gpio_fsel_inpt);bcm2835_gpio_set_pud(in_pin4,bcm2835_gpio_pud_off);
bcm2835_gpio_set_pud(in_pin4,bcm2835_gpio_pud_off);
}void sig_send_msg(pid_t id,int signo,char *msg)
{
Union Sigval *Sigdata;
sigdata = malloc ( sizeof ( union sigval ) );
sigdata -> sival_ptr = msg;sigqueue ( id, signo, *sigdata );
free ( sigdata );
}void sig_send_val ( pid_t id, int signo, int val )
{
Union Sigval *Sigdata;
sigdata = malloc ( sizeof ( union sigval ) );
sigdata -> sival_int = val;sigqueue ( id, signo, *sigdata );
free ( sigdata );
}void sig_set_handler ( int signo, void *handler )
{
struct sigaction *act;
act = malloc ( sizeof ( struct sigaction ) );
act -> sa_sigaction = handler;
act -> sa_flags = SA_SIGINFO;sigaction ( signo, act, NULL );
}###