Post

Replies

Boosts

Views

Activity

Reply to bInterfaceNumber for multiple interface usb-cdcacm device
Hi Kevin, As you know serial ports can be opened, configured and read/write operations can be performed using open(), tcsetattr(), read() and write() system calls, as in the below sample code. Here tcsetattr() in turn calls ioctl() system call, I think. But all these tcsetattr()/ioctl()/read()/write() corresponding calls to the driver are implemented in the base class and are not exposed as virtual functions in derived IOUserUSBSerial() class. So if I need to call/send any specific custom request to the driver with a special IOCTL code, what are the options available to the user is my question. This is the sample user app code which uses system calls to access the serial ports. BEGIN--> const char *portname = "/dev/cu.usbserial-YOURDEVICEID"; int serial_port = open(portname, O_RDWR | O_NOCTTY | O_SYNC); // Check for errors opening the serial port if (serial_port < 0) { printf("Error %i from open: %s\n", errno, strerror(errno)); return 1; } // Configure the serial port settings struct termios tty; if (tcgetattr(serial_port, &tty) != 0) { printf("Error %i from tcgetattr: %s\n", errno, strerror(errno)); return 1; } cfsetospeed(&tty, B9600); // Set output baud rate (e.g., 9600) cfsetispeed(&tty, B9600); // Set input baud rate tty.c_cflag |= (CLOCAL | CREAD); // Enable receiver, ignore modem control lines tty.c_cflag &= ~PARENB; // No parity tty.c_cflag &= ~CSTOPB; // One stop bit tty.c_cflag &= ~CSIZE; // Clear all size bits tty.c_cflag |= CS8; // 8 data bits tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Raw input tty.c_oflag &= ~OPOST; // Raw output // Apply the settings if (tcsetattr(serial_port, TCSANOW, &tty) != 0) { printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); return 1; } // Write data to the serial port char msg[] = "Hello, serial port!\n"; write(serial_port, msg, strlen(msg)); // Read data from the serial port (example) char read_buf[256]; int num_bytes = read(serial_port, read_buf, sizeof(read_buf) - 1); if (num_bytes < 0) { printf("Error %i from read: %s\n", errno, strerror(errno)); } else if (num_bytes > 0) { read_buf[num_bytes] = '\0'; // Null-terminate the string printf("Received: %s\n", read_buf); } close(serial_port); // Close the serial port <--END So, my requirement is if I need to call ioctl(serial_port, MY_IOCTL_REQUEST, &myargs,...) what is the corresponding code/method that needs to be overridden in my driver (.dext) whose IOClass is IOUserSerial and the driver's base class is IOUserUSBSerial. Thanks in advance.
Jul ’25
Reply to IOCTL in MacOS drivers (DriverKit/DEXT)
Hi Kevin, I think I am not able to convey the issue properly. I am accessing the serial ports from the client/user application which is developed using C/C++. I am not using SwiftUI. So I am using open/read/write/ioctl/close() system calls and accessing the the serial port handle specifying the TTY name of the port (such as open("/dev/cu.usbserial123", O_RDWR | O_NOCTTY | O_SYNC) ). https://developer.apple.com/documentation/driverkit/communicating-between-a-driverkit-extension-and-a-client-app The above sample does not work for me as I have to use tcsetattr() function to set the uart parameters after getting the handle to the serial port using open() system function and the IOUserSerial class of DriverKit supports this architecture. If I have to use IOServiceOpen method then I have to get handles for two sets in the user/client app (one to the port using open() and another for custom calls using IOServiceOpen) which is not preferred or appropriate solution in our case. I know this is quite an unusual request or complicated, but this is a necessary requirement for me. Any suggestions/help is very much appreciated. Thanks.
Jul ’25
Reply to USBSendSetLineCoding failing in DeviceRequest with error code 0xe0005000
HI Kevin, My problem is very simple. How do you package arguments when you call DeviceRequest to set the BaudRate and character formats of the UART? Basically I am looking for the implementation part of IOUserUSBSerial::HwProgramUART() function. In other words, I am looking for an equivalent code of previous version of AppleUSBCDCACMDriver's USBSendSetLineCoding() function: lineParms->bCharFormat = StopBits - 2; lineParms->bParityType = TX_Parity - 1; lineParms->bDataBits = CharLength; OSWriteLittleInt32(lineParms, dwDTERateOffset, BaudRate); MER = (IOUSBDevRequest*)IOMalloc(sizeof(IOUSBDevRequest)); if (!MER) { XTRACE(this, 0, 0, "USBSendSetLineCoding - allocate MER failed"); return; } bzero(MER, sizeof(IOUSBDevRequest)); // now build the Management Element Request MER->bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBInterface); MER->bRequest = kUSBSET_LINE_CODING; MER->wValue = 0; MER->wIndex = fCommInterfaceNumber; MER->wLength = lcLen; MER->pData = lineParms; fMERCompletionInfo.parameter = MER; rc = fControlInterface->GetDevice()->DeviceRequest(MER, &fMERCompletionInfo); This is all I need. How to do this using the latest Driver Kit architecture? Once again, I am looking for the code snippet of latest USBSerialDriverKit's IOUserUSBSerial::HwProgramUART() Thanks.
Topic: App & System Services SubTopic: Drivers Tags:
Aug ’25