Added a skeleton for character driver.

This commit is contained in:
Serge Vakulenko
2015-02-05 19:05:59 -08:00
parent f5bbefc222
commit 9b9f6392dc
4 changed files with 221 additions and 25 deletions

45
sys/include/skel.h Normal file
View File

@@ -0,0 +1,45 @@
/*
* Ioctl definitions for skeleton driver.
*
* Copyright (C) 2015 Serge Vakulenko
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
*/
#ifndef _SKEL_H
#define _SKEL_H
#include <sys/ioctl.h>
#define SKELCTL_SETMODE _IO ('?', 0) /* set driver mode mode */
#define SKELCTL_IO(n) _ION('?', 3, n) /* transfer n bytes */
#ifdef KERNEL
#include "conf.h"
extern const struct devspec skeldevs[];
int skeldev_open (dev_t dev, int flag, int mode);
int skeldev_close (dev_t dev, int flag, int mode);
int skeldev_read (dev_t dev, struct uio *uio, int flag);
int skeldev_write (dev_t dev, struct uio *uio, int flag);
int skeldev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag);
#endif
#endif

4
sys/pic32/cfg/skel.dev Normal file
View File

@@ -0,0 +1,4 @@
always
file skel.o
define SKEL_ENABLED YES
end always

View File

@@ -23,39 +23,39 @@
extern int strcmp(char *s1, char *s2);
#ifdef UARTUSB_ENABLED
#include "usb_uart.h"
# include "usb_uart.h"
#endif
#ifdef GPIO_ENABLED
#include "gpio.h"
# include "gpio.h"
#endif
#ifdef ADC_ENABLED
#include "adc.h"
# include "adc.h"
#endif
#ifdef SPI_ENABLED
#include "spi.h"
# include "spi.h"
#endif
#ifdef GLCD_ENABLED
#include "glcd.h"
# include "glcd.h"
#endif
#ifdef OC_ENABLED
#include "oc.h"
# include "oc.h"
#endif
#ifdef PICGA_ENABLED
#include "picga.h"
# include "picga.h"
#endif
#ifdef PTY_ENABLED
#include "pty.h"
# include "pty.h"
#endif
#ifdef HX8357_ENABLED
#include "hx8357.h"
# include "hx8357.h"
#endif
/*
@@ -117,13 +117,16 @@ const struct bdevsw bdevsw[] = {
const int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]) - 1;
// The RetroDisks require the same master number as the disk entry in the
// rdisk.c file. A bit of a bind, but it means that the RetroDisk
// devices must be numbered from master 0 upwards.
/*
* The RetroDisks require the same master number as the disk entry in the
* rdisk.c file. A bit of a bind, but it means that the RetroDisk
* devices must be numbered from master 0 upwards.
*/
const struct cdevsw cdevsw[] = {
const struct cdevsw cdevsw[] = {
// Static drivers - every system has these:
/*
* Static drivers - every system has these:
*/
{ /* cn = 0 */
cnopen, cnclose, cnread, cnwrite,
@@ -155,18 +158,21 @@ const struct cdevsw cdevsw[] = {
nostrategy, 0, 0, swapcdevs
},
// Optional drivers from here on:
/*
* Optional drivers from here on:
*/
#ifdef LOG_ENABLED
{ /* log = 3 */
{
logopen, logclose, logread, norw,
logioctl, nulldev, 0, logselect,
nostrategy, 0, 0, logdevs
},
#endif
#if defined(UART1_ENABLED) || defined(UART2_ENABLED) || defined(UART3_ENABLED) || defined(UART4_ENABLED) || defined(UART5_ENABLED) || defined(UART6_ENABLED)
#if defined(UART1_ENABLED) || defined(UART2_ENABLED) || \
defined(UART3_ENABLED) || defined(UART4_ENABLED) || \
defined(UART5_ENABLED) || defined(UART6_ENABLED)
{
uartopen, uartclose, uartread, uartwrite,
uartioctl, nulldev, uartttys, uartselect,
@@ -251,13 +257,12 @@ const struct cdevsw cdevsw[] = {
},
#endif
// End the list with a blank entry
{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
},
/*
* End the list with a blank entry
*/
{ 0 },
};
const int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]) - 1;
/*

142
sys/pic32/skel.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* Skeleton for a character device driver.
*
* Copyright (C) 2015 Serge Vakulenko
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
*/
#include "param.h"
#include "conf.h"
#include "user.h"
#include "ioctl.h"
#include "systm.h"
#include "uio.h"
#include "skel.h"
/*
* List of device names and minor numbers.
* Assume we have five ports.
*/
const struct devspec skeldevs[] = {
{ 0, "skel1" },
{ 1, "skel2" },
{ 2, "skel3" },
{ 3, "skel4" },
{ 4, "skel5" },
{ 0, 0 }
};
#define NSKEL 5 /* Ports 1...5 */
/*
* To enable debug output, uncomment the first line.
*/
#define PRINTDBG printf
#ifndef PRINTDBG
# define PRINTDBG(...) /*empty*/
#endif
/*
* Open /dev/skel# device.
*/
int skeldev_open(dev_t dev, int flag, int mode)
{
int unit = minor(dev);
if (unit >= NSKEL)
return ENXIO;
if (u.u_uid != 0)
return EPERM;
// TODO: initialize the port.
PRINTDBG("--- %s() unit=%u, flag=%d, mode=%d\n", __func__, unit, flag, mode);
return 0;
}
/*
* Close device.
*/
int skeldev_close(dev_t dev, int flag, int mode)
{
int unit = minor(dev);
if (u.u_uid != 0)
return EPERM;
// TODO: disable the port.
PRINTDBG("--- %s() unit=%u, flag=%d, mode=%d\n", __func__, unit, flag, mode);
return 0;
}
/*
* Read data from device.
*/
int skeldev_read(dev_t dev, struct uio *uio, int flag)
{
int unit = minor(dev);
// TODO: read data from port to user program.
PRINTDBG("--- %s() unit=%u, flag=%d\n", __func__, unit, flag);
return 0;
}
/*
* Write data to device.
*/
int skeldev_write(dev_t dev, struct uio *uio, int flag)
{
int unit = minor(dev);
// TODO: write data from user program to port.
PRINTDBG("--- %s() unit=%u, flag=%d\n", __func__, unit, flag);
return 0;
}
/*
* Control operations:
* SKELCTL_SETMODE - set device mode
* SKELCTL_IO(n) - perform R/W transaction of n bytes
*/
int skeldev_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag)
{
int unit = minor(dev);
int nbytes;
PRINTDBG("--- %s() unit=%u, cmd=0x%08x, addr=0x%08x, flag=%d\n", __func__, unit, cmd, addr, flag);
switch (cmd & ~(IOCPARM_MASK << 16)) {
default:
return ENODEV;
case SKELCTL_SETMODE:
// TODO: set device mode.
PRINTDBG("--- SETMODE 0x%x\n", (unsigned) addr);
return 0;
case SKELCTL_IO(0): /* transfer n bytes */
nbytes = (cmd >> 16) & IOCPARM_MASK;
if (baduaddr(addr) || baduaddr(addr + nbytes - 1))
return EFAULT;
// TODO: transfer nbytes from device to addr.
PRINTDBG("--- Transfer nbytes=%u to addr=0x%08x\n", addr);
break;
}
return 0;
}