Przeglądaj źródła

Proof of conzept.

Rind 5 lat temu
rodzic
commit
f974ee444d
6 zmienionych plików z 239 dodań i 59 usunięć
  1. 1 1
      Makefile
  2. 35 36
      drvmain.c
  3. 16 21
      kfile.c
  4. 1 1
      kfile.h
  5. 160 0
      kspi.c
  6. 26 0
      kspi.h

+ 1 - 1
Makefile

@@ -2,7 +2,7 @@
 TARGET_MODULE:=gfaspi
 PWD := $(shell pwd)
 
-$(TARGET_MODULE)-objs := drvmain.o kfile.o
+$(TARGET_MODULE)-objs := drvmain.o kfile.o kspi.o
 obj-m := $(TARGET_MODULE).o
 
 

+ 35 - 36
drvmain.c

@@ -8,6 +8,7 @@
 #include <asm/ioctls.h>
 #include <linux/spi/spidev.h>
 #include "kfile.h"
+#include "kspi.h"
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -17,31 +18,25 @@ MODULE_AUTHOR("GfA");
 /////////////////////////////////////////////////////////////////////////////
 
 #define _SPI_DEVICE				"/dev/spidev1.0"
-static struct file *g_fdSpiDev	= NULL;
+static struct file *g_pfSpiDev	= NULL;
 
 /////////////////////////////////////////////////////////////////////////////
 
-static int temp = 0;
 static struct kobject *pKoGfa = NULL, *pKoTiva = NULL;
 
 /////////////////////////////////////////////////////////////////////////////
 
-static ssize_t tivaTempShow(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+static ssize_t firmware_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
-	printk(KERN_ALERT "tivaTemp - Read!!!\n");
-	return sprintf(buf, "%d", ++temp);
-}
-
-static ssize_t tivaTempStore(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
-{
-	printk(KERN_ALERT "tivaTemp - Write!!!\n");
-	sscanf(buf, "%d", &temp);
-	return count;
+	int hw = 0, sw = 0;
+	printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
+	CmdGetFirmwareVersion(g_pfSpiDev, &hw, &sw);
+	return sprintf(buf, "HW: %08X SW: %08X\n", hw, sw);
 }
 
 /////////////////////////////////////////////////////////////////////////////
 
-static struct kobj_attribute tivaTempAtt = __ATTR(temp, 0660, tivaTempShow, tivaTempStore);
+static struct kobj_attribute tivaFirmwareAtt = __ATTR_RO(firmware);
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -56,37 +51,37 @@ static int drv_init(void)
 
 	do
 	{
-		if(!(pKoGfa = kobject_create_and_add("gfa", /*kernel_kobj*/NULL)))
+		if(!(g_pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
 		{
-			printk(KERN_ALERT "kobject_create_and_add failed\n");
+			printk(KERN_ALERT "file_open failed\n");
 			break;
 		}
 
-		if(!(pKoTiva = kobject_create_and_add("tiva", pKoGfa)))
+		/////////////////////////////////////////////////////////////////////
+
+		if(!(pKoGfa = kobject_create_and_add("gfa", /*kernel_kobj*/NULL)))
 		{
 			printk(KERN_ALERT "kobject_create_and_add failed\n");
 			break;
 		}
 
-		/////////////////////////////////////////////////////////////////////
-
-		if(sysfs_create_file(pKoTiva, &tivaTempAtt.attr))
+		if(!(pKoTiva = kobject_create_and_add("tiva", pKoGfa)))
 		{
-			printk(KERN_ALERT "sysfs_create_file failed\n");
+			printk(KERN_ALERT "kobject_create_and_add failed\n");
 			break;
 		}
 
 		/////////////////////////////////////////////////////////////////////
 
-		if(!(g_fdSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
+		if(sysfs_create_file(pKoTiva, &tivaFirmwareAtt.attr))
 		{
-			printk(KERN_ALERT "file_open failed\n");
+			printk(KERN_ALERT "sysfs_create_file failed\n");
 			break;
 		}
 
 		/////////////////////////////////////////////////////////////////////
 
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_MODE, (unsigned long)&mode);
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_MODE, (unsigned long)&mode);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't set spi mode\n");
@@ -94,14 +89,16 @@ static int drv_init(void)
 		}
 
 		mode = 0;
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_MODE, (unsigned long)&mode);
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_MODE, (unsigned long)&mode);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't get spi mode\n");
 			break;
 		}
 
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&bits);
+		/////////////////////////////////////////////////////////////////////
+
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&bits);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't set bits per word\n");
@@ -109,14 +106,16 @@ static int drv_init(void)
 		}
 
 		bits = 0;
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_BITS_PER_WORD, (unsigned long)&bits);
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_BITS_PER_WORD, (unsigned long)&bits);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't get bits per word\n");
 			break;
 		}
 
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed);
+		/////////////////////////////////////////////////////////////////////
+
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't set max speed hz\n");
@@ -124,7 +123,7 @@ static int drv_init(void)
 		}
 
 		speed = 0;
-		ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_MAX_SPEED_HZ, (unsigned long)&speed);
+		ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_MAX_SPEED_HZ, (unsigned long)&speed);
 		if(ret < 0)
 		{
 			printk(KERN_ALERT "can't get max speed hz\n");
@@ -136,19 +135,19 @@ static int drv_init(void)
 		printk(KERN_ALERT "mode:  %hhu\n", mode);
 		printk(KERN_ALERT "bits:  %hhu\n", bits);
 		printk(KERN_ALERT "speed: %u\n", speed);
-		printk(KERN_ALERT "%s\n", __FUNCTION__);
+		printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
 		return 0;
 	}
 	while(0);
 
 	/////////////////////////////////////////////////////////////////////////
 
-	if(g_fdSpiDev)
-		kf_close(g_fdSpiDev);
+	if(g_pfSpiDev)
+		kf_close(g_pfSpiDev);
 
 	if(pKoTiva)
 	{
-		sysfs_remove_file(pKoTiva, &tivaTempAtt.attr);
+		sysfs_remove_file(pKoTiva, &tivaFirmwareAtt.attr);
 		kobject_put(pKoTiva);
 		pKoTiva = NULL;
 	}
@@ -166,19 +165,19 @@ static int drv_init(void)
 
 static void drv_exit(void)
 {
-	if(g_fdSpiDev)
-		kf_close(g_fdSpiDev);
+	if(g_pfSpiDev)
+		kf_close(g_pfSpiDev);
 
 	if(pKoTiva)
 	{
-		sysfs_remove_file(pKoTiva, &tivaTempAtt.attr);
+		sysfs_remove_file(pKoTiva, &tivaFirmwareAtt.attr);
 		kobject_put(pKoTiva);
 	}
 
 	if(pKoGfa)
 		kobject_put(pKoGfa);
 
-	printk(KERN_ALERT "%s\n", __FUNCTION__);
+	printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
 }
 
 /////////////////////////////////////////////////////////////////////////////

+ 16 - 21
kfile.c

@@ -2,8 +2,6 @@
 #include <linux/syscalls.h>
 #include "kfile.h"
 
-static mm_segment_t g_oldfs;
-
 /////////////////////////////////////////////////////////////////////////////
 
 static long _vfs_ioctl(struct file *pf, unsigned int cmd, unsigned long arg)
@@ -26,18 +24,18 @@ static long _vfs_ioctl(struct file *pf, unsigned int cmd, unsigned long arg)
 struct file* kf_open(const char *path, int flags, int rights)
 {
     struct file *pf = NULL;
-//    mm_segment_t oldfs;
+    mm_segment_t oldfs;
     int err = 0;
 
-    g_oldfs = get_fs();
+    oldfs = get_fs();
     set_fs(get_ds());
     pf = filp_open(path, flags, rights);
-//    set_fs(oldfs);
+    set_fs(oldfs);
 
     if(IS_ERR(pf))
     {
         err = PTR_ERR(pf);
-		set_fs(g_oldfs);
+		set_fs(oldfs);
         return NULL;
     }
 
@@ -49,10 +47,7 @@ struct file* kf_open(const char *path, int flags, int rights)
 void kf_close(struct file *pf)
 {
 	if(pf)
-	{
     	filp_close(pf, NULL);
-		set_fs(g_oldfs);
-	}
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -60,14 +55,14 @@ void kf_close(struct file *pf)
 int kf_read(struct file *pf, unsigned long long offset, unsigned char *data, unsigned int size)
 {
 	int ret;
-//	mm_segment_t oldfs;
+	mm_segment_t oldfs;
 
-//	oldfs = get_fs();
-//	set_fs(get_ds());
+	oldfs = get_fs();
+	set_fs(get_ds());
 
 	ret = vfs_read(pf, data, size, &offset);
 
-//	set_fs(oldfs);
+	set_fs(oldfs);
 	return ret;
 }
 
@@ -76,14 +71,14 @@ int kf_read(struct file *pf, unsigned long long offset, unsigned char *data, uns
 int kf_write(struct file *pf, unsigned long long offset, unsigned char *data, unsigned int size)
 {
 	int ret;
-//	mm_segment_t oldfs;
+	mm_segment_t oldfs;
 
-//	oldfs = get_fs();
-//	set_fs(get_ds());
+	oldfs = get_fs();
+	set_fs(get_ds());
 
 	ret = vfs_write(pf, data, size, &offset);
 
-//	set_fs(oldfs);
+	set_fs(oldfs);
 	return ret;
 }
 
@@ -92,14 +87,14 @@ int kf_write(struct file *pf, unsigned long long offset, unsigned char *data, un
 long kf_ioctl(struct file *pf, unsigned int cmd, unsigned long arg)
 {
 	long ret;
-//	mm_segment_t oldfs;
+	mm_segment_t oldfs;
 
-//	oldfs = get_fs();
-//	set_fs(get_ds());
+	oldfs = get_fs();
+	set_fs(get_ds());
 
 	ret = _vfs_ioctl(pf, cmd, arg);
 
-//	set_fs(oldfs);
+	set_fs(oldfs);
 	return ret;
 }
 

+ 1 - 1
kfile.h

@@ -19,7 +19,7 @@ struct file*	kf_open(const char *path, int flags, int rights);
 void			kf_close(struct file *pf);
 int				kf_read(struct file *pf, unsigned long long offset, unsigned char *data, unsigned int size);
 int				kf_write(struct file *pf, unsigned long long offset, unsigned char *data, unsigned int size);
-long			kf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+long			kf_ioctl(struct file *pf, unsigned int cmd, unsigned long arg);
 int				kf_sync(struct file *pf);
 
 /////////////////////////////////////////////////////////////////////////////

+ 160 - 0
kspi.c

@@ -0,0 +1,160 @@
+#include<linux/string.h>
+#include "kspi.h"
+#include "kfile.h"
+
+//uint8_t mode = SPI_MODE_3;
+//uint8_t bits = 8;
+//uint32_t speed = 1000000;
+#define CMD_ACK			0xcc
+#define CMD_NAK			0x33
+
+#define CMD_GET_FIRMWARE_VERSION 0x51
+#define CMD_GET_I2C 0x56
+#define CMD_SET_I2C 0x57
+#define CMD_GET_ADDRESS 0x58
+#define CMD_SET_ADDRESS 0x59
+#define CMD_SET_BACKLIGHT 0x5B
+#define CMD_GET_UPTIME 0x5C
+#define CMD_GET_ADC 0x5A
+
+static unsigned char transfer_1(struct file *pf, unsigned char Tx)
+{
+	int ret;
+	uint8_t tx = Tx;
+	uint8_t rx;
+
+	struct spi_ioc_transfer tr =
+	{
+		.tx_buf = (unsigned long) &tx,
+		.rx_buf = (unsigned long) &rx,
+		.len = 1,
+		.delay_usecs = 0,
+		.speed_hz = 1000000,
+		.bits_per_word = 8,
+	};
+
+	ret = kf_ioctl(pf, SPI_IOC_MESSAGE(1), (unsigned long)&tr);
+
+	if(ret < 0)
+	{
+		printk(KERN_ALERT "transfer_1 failed: %d\n", ret);
+	    return 0;
+	}
+
+    return rx;
+}
+
+static int WaitACK(struct file *pf)
+{
+    unsigned char rcv = 0;
+    int i = 0;
+//    time_t endwait = time(NULL) + 3; // max 3 seconds wait
+
+    // warten auf ACK
+
+    while ((rcv != CMD_ACK) && (rcv != CMD_NAK) && i < 100/*(time(NULL) < endwait)*/)
+    {
+        rcv = transfer_1(pf, 0);
+        ++i;
+    }
+
+    return rcv;
+}
+
+int SendCMD(struct file *pf, unsigned char Cmd, unsigned char DataLen, unsigned char *Data)
+{
+	unsigned char Len = DataLen + 3;
+	unsigned char Chk = Cmd;
+	int i;
+
+	printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
+
+	for (i = 0; i < DataLen; i++)
+	    Chk += *(Data + i);
+
+	transfer_1(pf, Len);
+	transfer_1(pf, Chk);
+	transfer_1(pf, Cmd);
+
+	for (i = 0; i < DataLen; i++) {
+	    transfer_1(pf, *(Data + i));
+	}
+	return WaitACK(pf);
+}
+
+int ReadCmd(struct file *pf, int MaxLen, unsigned char *Data)
+{
+    unsigned char rcv = 0;
+    int i = 0;
+    int len;
+    unsigned char chksum = 0, chkval = 0;
+    int ret = 0;
+
+	printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
+
+    // warten auf längenbyte der Antwort
+    while ((rcv == 0) && (i < 2000))
+    {
+        rcv = transfer_1(pf, 0);
+        ++i;
+    }
+
+    // daten einlesen
+    len = rcv;
+    for(i = 0; i < (len - 1); i++) {
+        rcv = transfer_1(pf, 0);
+        //printf("%2.2X-", rcv);
+        if(i == 0) { //CHKSUM
+            chkval = 0;
+            chksum = rcv;
+        } else {
+            chkval += rcv;
+            if((i - 1) < MaxLen)
+                *(Data + i - 1) = rcv;
+        }
+    }
+
+    if(chksum != chkval) {
+        ret = -1;
+    }
+    else {
+        ret = len - 2;
+    }
+
+    return ret;
+}
+
+int CmdGetFirmwareVersion(struct file *pf, int *Hw, int *Sw)
+{
+    int ret = -1;
+    int len = 0;
+
+	printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
+
+    ret = SendCMD(pf, CMD_GET_FIRMWARE_VERSION , 0, NULL);
+    if(ret == CMD_ACK)
+    {
+        unsigned char Data[255];
+        memset(Data, 0, sizeof(Data));
+
+        if((len = ReadCmd(pf, sizeof(Data), Data)) == 9)
+        {
+            int HW_Version, SW_Version;
+
+            HW_Version = (Data[1] << 24) + (Data[2] << 16) + (Data[3] << 8) + Data[4];
+            SW_Version = (Data[5] << 24) + (Data[6] << 16) + (Data[7] << 8) + Data[8];
+
+            if(Hw != NULL) *Hw = HW_Version;
+            if(Sw != NULL) *Sw = SW_Version;
+            ret = 0;
+        } else {
+
+            printk(KERN_ALERT "LEN = %d\n", len);
+
+        }
+    }
+
+    transfer_1(pf, CMD_ACK); /* Testweise immer ACK */
+
+    return ret;
+}

+ 26 - 0
kspi.h

@@ -0,0 +1,26 @@
+// kspi.h :
+//
+
+#if !defined(AGD_KSPI_H__C0C2E2F9_77AA_4807_9B26_08F970CFD563__INCLUDED_)
+#define AGD_KSPI_H__C0C2E2F9_77AA_4807_9B26_08F970CFD563__INCLUDED_
+
+#include <linux/kernel.h>
+#include <linux/spi/spidev.h>
+#include <linux/syscalls.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// kspi.h - Declarations:
+
+int SendCMD(struct file *pf, unsigned char Cmd, unsigned char DataLen, unsigned char *Data);
+int ReadCmd(struct file *pf, int MaxLen, unsigned char *Data);
+int CmdGetFirmwareVersion(struct file *pf, int *Hw, int *Sw);
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_KSPI_H__C0C2E2F9_77AA_4807_9B26_08F970CFD563__INCLUDED_)