I wish to write a Linux device driver which spawns a thread which listens to the comport on /dev/ttyAMA0.
On the comport is an rf device which connects to a host of other devices. I wish I add each rf device as I discover them as if they were physical devices to Linux and upon probing the parameters of each device add files for controlling the device parameters.
I have done quite a bit of searching around this and have already done many of the simple hello world driver tutorials and found how to spawn threads from within a driver.
I already know how to read/write to the comport from user-land c.
My question is; is this approach OK? i.e. a driver which can spawn multiple devices. Should this instead be a service? How about reading/writing to the comport from another device is this ok? What are the best practices? Examples?
N.B. I realise I will have to control access to the comport. I am choosing to ignore that complexity for the moment, but I will achieve this via some sort of semaphore.
This is for a personal project by day I'm mainly a c# developer.
EDIT
I have found this related question, I don't however believe it to be a duplicate. I think recommends not to write drivers over drivers. But I wish to add these external devices as if they were physical devices.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I studied the content from the osdev.org website and built a compiler, launched a test kernel, but I thought, how can I create a primitive text shell for the kernel with commands? Maybe someone can explain to me with an example how to implement this. There is nothing interesting on the site itself, of course there is an article but it is useless for me. I'm a beginner if that.
how can I create a primitive text shell for the kernel with commands?
The correct way is:
Write enough kernel code to manage various resources (memory, IRQs, IO ports, DMA channels, ...). This should include managing time (a scheduler), and should also include some kind of inter-process communication (so that the scheduler can be told "Don't give this task any more CPU time until/unless it receives data from inter-process communication").
Enumerate devices, determine each device's resources, and start drivers for whichever devices you find. Note that this is hierarchical. For example, if you enumerate PCI buses and find 2 USB controllers attached to PCI buses and start their device drivers, then you'll need to enumerate each of the USB controllers to find any USB devices attached to USB buses and might find 3 USB hubs, and then you'll need to enumerate all 3 USB hubs to see what is plugged into them. All of this should be coordinated by some kind of "device manager" which keeps track of a hierarchical tree of devices, so that (e.g.) if a device is unplugged or sent to a power saving state (or if its device driver crashes) you can inform drivers that depended on that device (e.g. if a USB hub is unplugged you can inform all drivers for devices that were attached to that hub).
write keyboard device driver/s. These should decode the data from the device (likely using tables and other information describing a "keyboard layout" that's loaded from file system) and send packets of data using the kernel's inter-process communication (so that any task can say "don't give me any CPU time until I receive data from the keyboard driver"). This will involve designing a standard way that all keyboard drivers (and all software emulating a keyboard - e.g. "on screen keyboard" for people using touchscreens, etc) will behave (e.g. the format of that data packet they send, etc); and probably should involve creating a formal "keyboard device driver interface" specification for your OS to describe whatever you designed (in addition to designing a file format for "keyboard layout files").
write video device driver/s. This will also include designing a suitable video driver interface for your OS (and should including writing a formal specification describing it). However; video is complex and you can cheat by only designing part of the video driver interface and leaving the rest of it (video mode setting, 3D, GPGPU, ...) until later. The same applies to the video driver itself - you will want to start with "generic raw frame buffer driver" (that just uses a frame buffer configured by the boot loader) and probably won't write actual drivers for specific video cards.
(optional) write some kind of upper layer to control which task is the main task for each set of user input/output devices. This allows the user to have multiple virtual consoles and switch between them (e.g. maybe with "control+alt+F1" to "control+alt+F12"), possibly allowing some virtual consoles to be associated with terminals and others to be associated with different GUIs. It can also make it easy to support "multiple seat" (e.g. if there's 2 keyboards and 2 monitors, then you can have 2 completely separate users with each user having one keyboard and one monitor).
create a task with a simple main loop that uses inter-process communication ("don't give me any more CPU time until/unless I receive data from the keyboard") and processes the data it received to build up a current command string, then (if/when the user presses the enter key) parses the command string and does whatever the command says. Note that if you get this far it's tempting to do a tiny little bit of extra work to support user-space, and make it a normal process instead of a kernel task.
The incorrect way is:
don't have a kernel that supports some/most of the things that device drivers and other code must rely on
don't do any kind of device enumeration. Instead, make wild assumptions about which devices are present and which resources they use.
don't put any thought into device driver interfaces. Just slap together whatever seemed convenient (and continually break everything whenever you change any device driver).
don't use tasks (or inter-process communication). Instead, build the "shell" into the keyboard driver's IRQ handler to make sure the entire OS "pauses" when someone enters any time consuming command.
don't continue working on the OS after you get the shell to "work". This will be necessary because the code will be too inflexible and too fragile (any attempt to do anything else will cause you to have to rewrite everything).
Note: In my experience people that ask questions like "how do I write a kernel shell" are likely to have skipped everything that matters (because they'd know how to write a shell if they've done everything that a shell depends on); and are so focused on having a shell that they're very tempted to do it all the incorrect way (and then get stuck later and regret it).
I'm using a LPC178 development board and I want to read a file present on a Windows PC. My dev board only has a RS2323 interface to communicate with.
How can I go about transferring the file from my PC to my MCU using a RS232 (serial) link? I found a reference which explains how to transfer data between a MCU and PC but it isn't about file transfers.
Afaik there is no easy solution for this like calling something like "copy" or "fopen" over RS232. I would be happy to be proven wrong here.
The fastest solution might be to write a little programm running on your Windows Host, which listens to your RS232 communication and pipes your communication into/out of the file based on your communication protocol. This can be done with standard file operations in the language of your choice, for example C, C++ or Python.
Your problem is one of the oldest in the book. How do you transfer files without fancy operating system abstractions. For RS232 (or any other serial method) there exists many file transfer protocols.
One of them is kermit. This is a protocol from 1981 and can transfer binary and text files. It is able to be embedded in a micrcontroller and there exists programs to transfer/receive using kermit.
alternative old site for reference
In the simplest case you would use a file transfer protocol such as XMODEM, YMODEM, ZMODEM or Kermit - these protocols were designed in the days before networking and the Internet were ubiquitous and deal with simple point-to-point transfers between two computers. They are supported bu most terminal emulator tools such as TeraTerm Pro or PuTTY so no specific PC software need be written, just the microcontroller end.
A more complex but flexible solution is to implement a TCP/IP stack and a PPP driver, and an FTP application layer - probabaly only practical if using a third-party TCP/IP stack and application layer. You can then use any FTP client for the PC end, so again no PC software required. While this may be overkill if all you need to do is transfer files, it has the advantage of allowing you to use the the single serial port concurrently for other data streams and application protocols such as Telnet. The disadvantage perhaps is that while Windows does support PPP it is buried within the dial-up networking and to be frank a pain to get working.
Very first step you have to do is ensure serial communication is working fine.
Send a byte continuously from mcu to PC and display it on some io console (for example: HyperTerminal, Dock light )
Receive a byte to mcu from PC and echo it back to PC.
Once you are sure that serial communication is working fine then select some file transfer protocol and implement it.
While you can select any of the available protocols or write your own protocol and implement it.
For purpose of discussion i select Xmodem protocol.
If you consider some other protocol you may stop reading answer here.
XMODEM is a simple file transfer protocol.
Refer http://web.mit.edu/6.115/www/amulet/xmodem.htm for detailed information.
You may implement Xmodem mcu side by reading protocol. Or may consider using open source also ( if available )
PC side i prefer to use HyperTerminal io console as it is compatible with Xmodem.
In HyperTerminal all that i have to do is configure settings and select file for transfer to mcu.
Now transfer any file to mcu using Xmodem protocol from PC.
What you do with received file in mcu is up to you : )
Let's say I have a webcam, and I installed the device driver for this webcam in my Linux OS, now a device file will be created for the device driver (for example: /dev/video0).
Now say I want to create a program in C that wants to access this webcam. How can my program access the device driver for the webcam, should my program use the device file (/dev/video0) to access the device driver, or is there another way?
You asked a general question, and then gave a specific example. I'll try to address both.
When you load a driver, the way to communicate with it from user space is by whatever means this driver defined. Typically, this is through a /dev device created for the driver. If that's the case, yes, that's the only way to communicate with it.
This is not universally true. Many drivers also have entries under the /sys sysfs pseudo file system, and some aspects can be modified through there. In fact, there are whole classes of drivers that are only accessible through the /sys fs. Prominent examples are GPIO and Led devices, that can be turned on and off via access to /sys/class/gpio and similar paths.
Another option, considered deprecated but still sometimes used, is to use the /proc pseudo file system. Again, this is up to the driver to define its communication method. As the user, you will have to follow whatever protocol the driver defined.
Also, some drivers don't have any file system presence at all. The most obvious standard example are network interfaces. The only way to communicate with them is via the networking system calls.
In the particular example you provided, you talked about a video camera that appears as /dev/video0. Such a camera is, usually, a Video4Linux (or v4l) camera, and those are accessed via their character devices.
With that said, the protocol for communicating with the camera might have wrappers that makes life easier. If you open the actual device, you might have to implement a rather complicated handshake with it. Instead, you can use the v4l library to wrap the details of the access.
Make no mistake. You're still talking to the character device in /dev. It's just that it's not your code that does it, but the library's.
I have recently started learning to write Linux device drivers for a specific project that I am working on. Previously most of the work I have done has been with devices running no OS so Linux drivers and development is somewhat new to me.
For the project I am working on I have an embedded system running a Linux based operating system. I have an external device with is controlled via RS232 that I need to write a driver for.
Questions:
1) Is there a way to access serial ports from withing kernel space (and possibly use serial.h, serial_core.h, etc.), how is this usually done, any good examples?
2) From what I found it seems like it would be much easier to access the serial ports in user space by just opening dev/ttyS* and writing to it. When writing a driver for a device like this (RS232 device) is it preferred to do it in user space or is there a way to write a kernel module? How does one decide to write a driver as a kernel module over user space or vise versa?
Are drivers only for generic devices such as UART/serial and then above that is userspace or should this driver be written as a kernel module? I appreciate the help, I have been unable to find much information to answer my questions.
There are a few times when a module that communicates over a serial port may be in the kernel. The pppd (point to point protocol daemon) is one example as Linux has some kernel code devoted to that since it is a high traffic use of serial and it also needs to turn around and put the IP packets into kernel space.
Most other uses would work better from user space since you have a good API that already takes care of a lot of the errors that can happen. This also lessens the chance that your errors will result in massive system failure.
Doing things like this from user space does result in some latency. Reads and writes are buffered, and it's often difficult to tell where in the write operations the hardware actually is, and canceling an already succeeded write call isn't really doable from user space, even if the hardware hasn't yet received the bytes.
I would suggest attempting to do it from user space first and then move to OS driver if necessary. Even if it is necessary to move this into an OS level driver, you'll likely be able to get some progress made from user space.
I am planning to build a micro controller (a switch will be attached to the embedded system which contains this micro controller) and this embedded system will be connected through a wire to mobile phone. My objective is to dial a particular number through the connected mobile phone network when the user presses the switch on the embedded system. ( planning to use AT commands for dialing). After extensive search, I have found that it is possible to do this above task. Some of the questions I have on this :
a) Do we have to install any drivers on the micro controller to communicate with mobile phone (for sending AT commands) i.e., is it sufficient if we simply code the related AT commands in the micro-controller (in C++) ?
b) Many people were using F-bus protocol for this above objective. Is there any other general protocol similar to this which can help for communicating with all mobiles (samsung,nokia,sony..)
I have read extensively in SO also. But, I have not found any question regarding the drivers. I would appreciate any kind of help
Thanks
A driver is nothing more than a software that allows your system to interact other devices, and is usually associated with Operating Systems (the driver might provide an abstraction layer for your communication). Do you plan to use an Operating System at all?
In any case, it is quite obvious that if you want to communicate to another device you need the software to do so. The question is if you write it your self or if you get an "off the shelf" solution.
In many cases, particularly when a device uses a proprietary communication protocol, you have no option but to get a driver to communicate with it, and that most likely will require you to have an Operating System.
If cellular communication is all you need, there are MUCH easier solutions available (particularly if you intend of turning your project into a product). Search for "embedded modems" or M2M solutions. There are lots of available modems to which you connect using RS232, and can send the AT commands directly. Telit and Multitech are two providers I've worked with and are really easy to interface with.