Forum Discussion
Altera_Forum
Honored Contributor
14 years agoDevice driver to acess on chip memory as a char device (must be made inside linux2.6/arch/nios2/driver)
# include <linux/fs.h># include <linux/sched.h># include <linux/errno.h># include <linux/types.h># include <linux/cdev.h># include <linux/kernel.h># include <linux/module.h># include <asm/current.h># include <asm/segment.h># include <asm/uaccess.h># include <asm/io.h>
# define DRIVER_NAME "shmem"
# define SHARED_MEM_BASE 0x800# define SHARED_MEM_SPAN 2048
typedef struct {
int32_t mutex;
int32_t reset;
} mutex_t;
typedef struct {
mutex_t *mutex;
unsigned char *buffer;
} shmem_t;
static shmem_t shmem;
int shmem_open(struct inode *inode,struct file *filep)
{
return 0;
}
int shmem_release(struct inode *inode, struct file *filep)
{
return 0;
}
ssize_t shmem_read(struct file *filep ,char *buff, size_t count, loff_t *offp)
{
int retval;
printk(KERN_INFO "read, count %i, off %i\n", count, *offp);
if (*offp >= SHARED_MEM_SPAN) {
return 0;
}
if (count > (SHARED_MEM_SPAN - *offp)) {
count = (SHARED_MEM_SPAN - *offp);
}
retval = copy_to_user(buff, (shmem.buffer+*offp), count);
if (retval != 0) {
printk(KERN_ERR "Kernel to userspace copy failed!\n" );
return retval;
}
*offp += count;
return count;
}
ssize_t shmem_write(struct file *filep,const char *buff,size_t count,loff_t *offp )
{
int retval;
if (*offp >= SHARED_MEM_SPAN) {
return -ENOSPC;
}
if (count > (SHARED_MEM_SPAN - *offp)) {
count = (SHARED_MEM_SPAN - *offp);
}
retval = copy_from_user((shmem.buffer+*offp), buff, count);
if (retval != 0) {
printk(KERN_ERR "Kernel to userspace copy failed!\n" );
return retval;
}
*offp += count;
return count;
}
struct file_operations shmem_fops={
open: shmem_open,
read: shmem_read,
write: shmem_write,
release:shmem_release,
};
static int shmem_init(void) {
printk(KERN_INFO "shmem device driver init\n");
if(register_chrdev(222,DRIVER_NAME, &shmem_fops)){
printk(KERN_ERR "failed to register\n");
goto chrdev_error;
}
shmem.mutex = (mutex_t *)ioremap(MUTEX_BASE, MUTEX_SPAN);
if (shmem.mutex == NULL) {
printk(KERN_ERR "failed to map mutex\n");
goto mutex_error;
}
printk(KERN_INFO "mutex %p\n", shmem.mutex);
shmem.buffer = (unsigned char *)ioremap(SHARED_MEM_BASE, SHARED_MEM_SPAN);
if (shmem.buffer == NULL) {
printk(KERN_ERR "failed to map shared memory\n");
goto buffer_error;
}
printk(KERN_INFO "shmem %p\n", shmem.buffer);
printk(KERN_INFO "shmem: mutex.reset %02x\n", shmem.mutex->reset);
return 0;
buffer_error:
iounmap(shmem.mutex);
mutex_error:
unregister_chrdev(222, DRIVER_NAME);
chrdev_error:
return -ENODEV;
}
static void shmem_cleanup(void)
{
printk(KERN_INFO "shmem device driver unregister.\n");
iounmap(shmem.buffer);
iounmap(shmem.mutex);
unregister_chrdev(222, DRIVER_NAME);
return;
}
module_init(shmem_init);
module_exit(shmem_cleanup);
A program in user land (uclinuxdist/user/program) to read 32 bits per read # include <unistd.h># include <fcntl.h># include <sys/mman.h>
int main()
{
int fd = 0;
int value = 0;
int bytes = 0;
fd = open("/dev/mutex", O_RDWR);
if (fd == NULL)
{
printf("Erro abrindo mutex\n");
return 1;
}
bytes = read(fd, &value, sizeof(value));
if (bytes < 0)
{
printf("Error lendo\n");
return 1;
}
printf("Valor lido: %x\n", value);
bytes = read(fd, &value, sizeof(value));
if (bytes < 0)
{
printf("Error lendo\n");
return 1;
}
printf("Valor lido: %x\n", value);
lseek(fd, 0, SEEK_SET);
bytes = read(fd, &value, sizeof(value));
if (bytes < 0)
{
printf("Error lendo\n");
return 1;
}
printf("Valor lido: %x\n", value);
close(fd);
return 0;
}