LED 디스플레이를 제어하는 안드로이드 Gpio 용례
GPIO 소개
GPIO는 영어로 모두 범용 IO 포트, 즉 범용 IO 포트라고 합니다.삽입식 시스템은 통상적으로 상대적으로 간단한 외부 설비/회로를 대량으로 가지고 있다.이 장치/회로 중 일부는 CPU가 제어 수단을 제공하고 일부는 CPU가 입력 신호로 사용해야 한다.또한 이러한 장치/회로 중 많은 것들은 한 자리만 필요합니다. 즉, 두 가지 켜기/끄기 상태, 예를 들어 불이 켜지거나 꺼지는 상태만 있으면 됩니다.이러한 장치/회로 제어에는 기존 직렬 또는 병렬 포트가 적합하지 않습니다.
따라서 보통 마이크로컨트롤러 칩에'유니버설 프로그래밍 가능한 IO 인터페이스', 즉 GPIO를 제공한다.
문외한으로 말하자면, 어떤 파이프 발은 고전평과 저전평을 출력하거나, 그것들을 통해 파이프 발의 상태를 읽을 수 있다. 그것이 고전평이든 저전평이든.
커널에서 장치 생성
의 원리
GPIO 포트 문자 장치 드라이버에 대해 다음 단계를 수행해야 합니다.
1 원리도에 해당하는 GPIO 포트를 찾아 출력 디렉터로 구성
GPIO 포트 구성(플랫폼 구성에 따라 다름)은 동일하지만 용도는 같습니다.GPIO 포트 출력 및 기본 로우 레벨 설정, 57개의 핀 연결
<&범위 561 0x1500>
<&range 571 0x1500> gpio 포트로 사용할 57개의 트랙을 나타냅니다. 기본값은 저전압
이 io 포트 레지스터 주소: 0xe46002e4
하지만 디버깅 과정에서
#define gpio_lp 57
gpio_request(gpio_lp,"pos_pwr");
gpio_set_value(gpio_lp,1);
GPIO 호출 요청 보고 오류로 인해 GPIO를 사용할 수 없지만 GPIO 포트를 변경하면 오류가 보고되지 않습니다.이것은 intel의 특수성 때문입니다: gpio가 vmm를 대체하기 위해 호출되어 내부 핵에서 조작할 수 없습니다. (유니버설 플랫폼은 이 조작에 문제가 없습니다)
나중에 나는 다른 방법을 생각해냈다
void _iomem*ldo_mmio_base=ioremap(0xe46002e4,4);
iowrite32(0x1700, ldo mmio 기지)//1700은 레지스터 설정(0xe46002e4)이 GPIO 포트이고 출력이 높음을 나타냅니다.
iowrite32(0x1500, ldo mmio 기)//1500은 레지스터 (0xe46002e4)가 GPIO 포트이고 출력이 낮음을 나타냅니다.
입출력 포트 제어
이루어지다
원본 코드를kenel-3.10/drivers/char 아래에 놓고 시스템에 장치 노드를 생성합니다:/dev/mtgpio. 두 군데에서 수정해야 합니다.
먼저kernel-3.10/drivers/char 디렉터리에 들어가서 새 파일을 추가합니다. 이것을lp6735 스위치라고 명명합니다.c 코드는 다음과 같습니다.
kernel-3.10/drivers/char$vim lp6735 스위치.c
#include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */
#include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/kernel.h> /* For printk/panic/... */
#include <linux/fs.h> /* For file operations */^M
#include <linux/ioport.h> /* For io-port access */
#include <linux/platform_device.h> /* For platform_driver framework */
#include <linux/init.h> /* For __init/__exit/... */
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
#include <linux/io.h> /* For inb/outb/... */
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h> /*kamlloc */
//#include <asm-generic/ioctl.h>
//ioctl
#define CMD_FLAG'i'
#define led_PWR_ON _IOR(CMD_FLAG,0x00000001,__u32)
#define led_PWR_OFF _IOR(CMD_FLAG,0x00000000,__u32)
#define gpio_lp 57
static int major =0;
static struct classclass *led_class;
struct cdev_led {
struct cdev cdev;
};
struct cdev_led *led_dev;
static int led_ioctl(struct file* filp,unsigned int cmd,unsigned long argv)
{
printk(KERN_INFO "entry kernel.... \n");
printk(KERN_INFO "%d\n", led_PWR_ON);
void __iomem *ldo_mmio_base = ioremap(0xe46002e4, 4);
switch(cmd)
{
case led_PWR_ON:
{
#if 0
gpio_set_value(gpio_lp,1); //
printk(KERN_INFO "led on\n");
#endif
iowrite32(0x1700, ldo_mmio_base)
break;
}
case led_PWR_OFF:
{
#if 0
gpio_set_value(gpio_lp,0);
printk(KERN_INFO "led off \n");
#endif
iowrite32(0x1500, ldo_mmio_base);
break;
}
default:
return -EINVAL;
}
return 0;
}
//open
static int led_open(struct inode* i_node,struct file* filp)
{
printk(KERN_INFO "larsonzhong open init.... \n");
int err;
// larsonzhong Content between #if 0 #endif would comment, because there is no actual device
#if 0
err = gpio_request(gpio_lp,"led_pwr");
if(err<0)
{
printk(KERN_INFO "gpio request faile \n");
return err;
}
gpio_direction_output(gpio_lp,1);
#endif
return 0;
}
//close
static void led_close(struct inode* i_node,struct file* filp)
{
printk(KERN_INFO "larsonzhong close init \n");
// larsonzhong Content between #if 0 #endif would comment, because there is no actual device
#if 0
gpio_free(gpio_lp);
#endif
return;
}
/* file operations */
struct file_operations fops={
.owner = THIS_MODULE,
.open = led_open,
.unlocked_ioctl = led_ioctl,
.release = led_close,
};
static int __init led_init(void)
{
printk(KERN_INFO "init .... \n");
dev_t dev_no;
int result,err;
err = alloc_chrdev_region(&dev_no,0,1,"my_led"); //dynamic request device number
if(err<0)
{
printk(KERN_INFO "ERROR\n");
return err;
}
major = MAJOR(dev_no);
led_dev = kmalloc(sizeof(struct cdev_led),GFP_KERNEL);
if(!led_dev)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(led_dev,0,sizeof(led_dev));
cdev_init(&led_dev->cdev,&fops);
led_dev->cdev.owner = THIS_MODULE;
result = cdev_add(&led_dev->cdev,dev_no,1);
if(result <0)
{printk(KERN_INFO "error\n");
goto fail_add;
}
led_class = class_create(THIS_MODULE,"mtgpio"); //in sys/class create sysfs file
device_create(led_class,NULL,MKDEV(major,0),NULL,"mtgpio"); //dynamic create device file /dev/myled
return 0;
fail_add:
kfree(led_dev);
fail_malloc:
unregister_chrdev_region(dev_no,1);
return result;
}
static void __exit led_exit(void)
{
dev_t dev_no=MKDEV(major,0);
unregister_chrdev_region(dev_no,1);
cdev_del(&led_dev->cdev);
kfree(led_dev);
device_destroy(led_class,dev_no);
class_destroy(led_class);
printk(KERN_INFO "exit........ \n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("control_led_power");
MODULE_LICENSE("GPL");
저장하고 종료한 다음 같은 디렉터리의makefile 파일을 수정해야 합니다.kernel-3.10/drivers/char$vim Makefile에 다음과 같은 세그먼트를 추가합니다.
+obj-y+=lp6735 스위치.o
특정 코드는 csd에서 일부 특수 기호를 처리하기 때문에 그림만 업로드할 수 있습니다.
lp6735 스위치를 추가하면Makefile을 수정하면/dev//dev/mtgpio에서 펌웨어 생성 노드가 생성됩니다.
이 노드를 읽기와 쓰기를 하려면 노드의 시스템 소유자와 권한을 수정해야 합니다.이 절차는 init에서 실행됩니다.rc.
제 코드는 시스템/core/rootdir/init입니다.철근 콘크리트
...
# added by [email protected] change my devices mqgpio
chown system system /dev/mtgpio
chmod 0766 /dev/mtgpio
...
실험을 시작하다
우리는 우리가 사용하고자 하는 작은 램프의 장치가 dev/mtgpio##Jni 헤더 파일이라고 가정한다
새 안드로이드 프로젝트를 만들고 새 클래스를 만듭니다. 여기는 Gpio LED입니다.자바.
대상
public class GpioLED {
To
//Control LED power on
public native static void ledPowerOn();
// Control the LED to power off
public native static void ledPowerOff();
}
대상헤드 파일 생성
방법1: 간단하면서도 거칠다
자바 생성을 사용하려면 자바 환경이 설정되어 있음을 주의하십시오. (환경 설정 클래스 경로 설정 포함)
원본 코드에서 bin 디렉터리에 있는classes 디렉터리로 이동하고javah-jni 패키지 이름을 사용합니다.클래스 이름, 여기는javah-jni-com입니다.과반.래드는 간단해.래드피오
우리는 디렉터리에서 헤더 파일을 볼 수 있고 헤더 파일을 열 수 있다.성명을 베껴 넣다.
방법2: 편리함
[컴파일] 버튼 옆에 있는 작은 삼각형, [컴파일] 버튼 옆에 있는 도구상자를 클릭하여 드롭다운 목록을 팝업하고, [외부 도구 구성]을 클릭하여 대화 상자를 팝업하고,
우리는 프로그램을 선택하고 위의 새 단추를 눌렀다.그런 다음 다음과 같이 입력합니다.
기본 카드:
이름:javah
위치:javah가 있는 디렉터리를 선택합니다.C:\Program Files\Java\jdk1입니다.8.0_102\bin\javah.exe
작업 디렉터리: 변수 단추를 누르면 목록을 팝업하고 프로젝트 loc를 선택하여 확인한 다음 끝에\src를 추가합니다. 결과는 ${프로젝트 loc}\src입니다
매개 변수: -classpath${project loc}\bin\classes-d${project loc}\jni-jni${java type name}
카드 새로 고침:
완료 후 리소스 새로 고침 확인
일반 카드:
외부 도구를 선택하고 적용 을 클릭합니다.
jni 구현
새 c 파일과 mk 파일을 만듭니다.만약 eclipse를 사용하고 ndk를 설정했다면 (ndk는 eclipse에서 설정해야 할 뿐만 아니라 환경 변수에서도 설정해야 합니다.) 그렇지 않으면cygpath를 시작할 수 없습니다.Cygwin 오고 있나요?]잘못 1
항목을 마우스 오른쪽 버튼으로 클릭->Android 도구->네이티브 지원 추가
그리고 프로젝트 디렉터리에서 추가 폴더와 두 개의 파일을 볼 수 있습니다. 우리는 방금 복사한 헤더 파일 설명을 붙여 넣습니다.
내가 여기 있는 코드는 다음과 같다:ledcontrol.c
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<jni.h> // Must include this file
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <android/log.h>
//Command code in the driver.
#define CMD_FLAG'i'
#define LED_ON _IOR(CMD_FLAG,0x00000001,__u32)
#define LED_OFF _IOR(CMD_FLAG,0x00000000,__u32)
#define DEVICE_NAME "/dev/mtgpio"
int fd;
static const char *TAG="012";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
/* * Class: Linuxc
* Method: openled
* Signature: ()I
*/
JNIEXPORT void JNICALL Java_com_coban_ledsimple_LEDGpio_ledPowerOn(JNIEnv* env, jclass mc)
{
LOGI("POWER ON BY LARSON");
LOGI("LED_ON:%d LED_OFF:%d",LED_ON,LED_OFF);
fd=open(DEVICE_NAME,O_RDWR);
if(fd<0)
{
LOGI("don't open dev");
}
else
{
ioctl(fd,LED_ON,NULL);
LOGI("open success");
}
}
/* * Class: Linuxc
* Method: clsoeled
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_coban_ledsimple_LEDGpio_ledPowerOff(JNIEnv* env, jclass mc)
{
LOGI("POWER Off BY LARSON");
ioctl(fd,LED_OFF,NULL);
close(fd);
}
여기에서 로그와 다른 헤더 파일을 사용했습니다. 관련 라이브러리를 포함해야 합니다.안드로이드를 수정합니다.mkLOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -lm -llog
LOCAL_MODULE := ledcontrol
LOCAL_SRC_FILES := ledcontrol.c
include $(BUILD_SHARED_LIBRARY)
주의해야 할 것은 LOCAL LDLIBS:=-lm-llog를include$(CLEAR VARS) 앞에 추가해서는 안 된다. 그렇지 않으면 삭제되고 효력을 상실할 것이다.Application.mk
APP_ABI := all
모든 플랫폼의 so 파일을 컴파일한다는 뜻입니다. 컴파일을 지정하려면APP_ABI:=armeabi armeabi-v7a x86
한 공간에 격리되다
so 파일 생성
우리는 소프트웨어를 직접 장치에 전송하거나 구축했다.프로젝트 디렉터리에 추가obj 폴더를 볼 수 있습니다.
libs 아래에 여러 개의 폴더가 있습니다. 이 폴더들은 서로 다른 플랫폼에 대응합니다.
어플리케이션 구현
제가 바로 여기서 코드를 발표할 거예요.
그는 웃었다.활용단어참조
package com.example.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class HelloJniLED extends Activity {
private Button power_on;
private Button power_off;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
power_on = (Button) findViewById(R.id.power_on);
power_off = (Button) findViewById(R.id.power_off);
To
power_on.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("012", "power_on by android\n");
LEDGpio.ledPowerOn();
}
});
power_off.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("012", "power_off by android\n");
LEDGpio.ledPowerOff();
}
});
}
To
}
래드피오.활용단어참조package com.coban.ledsimple;
import android.util.Log;
public class LEDGpio {
static {
try {
Log.i("012", "try to load ledcontrol.so");
System.loadLibrary("ledcontrol");
} catch (UnsatisfiedLinkError ule) {
Log.e("012", "WARNING: Could not load ledcontrol.so");
}
}
public native static void ledPowerOn();
public native static void ledPowerOff();
}
레이아웃 파일 활동 main.xml<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text=" power control "
android:textColor="#ff0000"
android:textSize="25sp" />
<Button
android:id="@+id/power_on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/position"
android:layout_centerHorizontal="true"
android:layout_toLeftOf="@+id/position"
android:text="power_on"
android:textSize="18sp" />
<Button
android:id="@+id/power_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/position"
android:layout_toRightOf="@+id/position"
android:text="power_off"
android:textSize="18sp" />
</RelativeLayout>
Reference
이 문제에 관하여(LED 디스플레이를 제어하는 안드로이드 Gpio 용례), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/larsonzhong/android-gpio-use-cases-by-controlling-led-298d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)