LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-01-2012, 02:41 AM   #1
zali
Member
 
Registered: Sep 2005
Distribution: Suse
Posts: 56

Rep: Reputation: 15
read/write in block device driver


Hi
In block device driver, for reading the device I read my device and then copy to buffer array of request structure, but this buffer is defined as char*, what should I do when readed bytes are unsigned char. Is there any way other than request structure for transferring readed bytes to the driver?
Thanks
 
Old 05-04-2012, 06:19 AM   #2
TheIndependentAquarius
Senior Member
 
Registered: Dec 2008
Posts: 4,622
Blog Entries: 29

Rep: Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896Reputation: 896
Size of unsigned char is 1 byte. So, can you pick up
one byte and put in the char*.

Code:
#include <iostream>
int main ()
{
	char          *p    = new char [10];
	unsigned char j [2] = {'1', '2'};
	
	p[0] = j[0];
	p[1] = j[1];
	
	std :: cout << p[0];
	std :: cout << p[1];
}
memcpy etc. would obviously not work here.
 
Old 05-04-2012, 11:52 PM   #3
zali
Member
 
Registered: Sep 2005
Distribution: Suse
Posts: 56

Original Poster
Rep: Reputation: 15
Thanks for your reply, but if we have an unsigned value upper than 128 and cast it to a char variable, then char variable would be corrupted, try below code in linux:

void main(){
char i;
unsigned char j = 0xf1;
i = j;
printf("j=%X,i=%X",j,i);
}

it would print j=f1,i=fffffff1, may be the printed value is corrupted, I don't have any editor to trace it and watch the values in memory.
 
Old 05-05-2012, 03:01 AM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
Quote:
Originally Posted by zali View Post
Thanks for your reply, but if we have an unsigned value upper than 128 and cast it to a char variable, then char variable would be corrupted
No, it is not corrupted.

While the C99 standard (section 6.3.1.3) states that casting an unsigned value to signed results in implementation-defined behaviour, all current architectures use two's complement to represent signed integers, so casts between integer types do not modify the bit pattern at all. Conversion to larger type replicates the high bit to new bits, and conversion to smaller type uses only the low bits. Signedness or unsignedness does not affect integer casts at all. In other words, all architectures running Linux have the same behaviour: use the same actual bit pattern. Thus, no corruption.

(As far as I know, this actually extends to all currently mass-produced CPU architectures. There are some historical ones that used one's complement, and thus have +0 and -0 with differing bit patterns, but they have a lot of other weirdnesses too. You can safely assume all architectures use two's complement signed integers, and that casting between signed and unsigned integer types of the same size does not modify the bit patterns.)

Your example code has a fatal flaw: both i and j are converted to int first. Because usually i is a signed type, for it the new high bits will be duplicates of the old highest bit (the sign bit, in two's complement format). Because j is unsigned, the new high bits will be zero.

Try this code instead:
Code:
#include <stdio.h>
#include <limits.h>

int main(void)
{
    char          c1;
    signed char   s1;
    unsigned char u1, u2;

    u1 = 0xF1; /* 241 in decimal */
    s1 = u1;
    c1 = u1;
    u2 = s1;

    printf("u1 = %d (0x%x)\n", u1, u1);
    printf("c1 = %d (0x%x) when converted to int\n", c1, c1);
    printf("s1 = %d (0x%x) when converted to int\n", s1, s1);
    printf("s1 = %d (0x%x) actual bits\n", s1 & ((1 << CHAR_BIT)-1), s1 & ((1 << CHAR_BIT)-1));
    printf("u2 = %d (0x%x)\n", u2, u2);

    return 0;
}
The output will be
Code:
u1 = 241 (0xf1)
c1 = -15 (0xfffffff1) when converted to int
s1 = -15 (0xfffffff1) when converted to int
s1 = 241 (0xf1) actual bits
u2 = 241 (0xf1)
except that the number of consecutive f's in the c1 and s1 lines depends on the size of int on the architecture (32 bits in Linux, always, as far as I know).

This output will show you that casting does not affect the bit pattern, and that the bit pattern in the signed char is exactly the same as the bit pattern in the unsigned char. Thus, casting between signed and unsigned types in Linux, never changes the actual bits. Only their interpretation.
 
Old 05-05-2012, 03:14 AM   #5
zali
Member
 
Registered: Sep 2005
Distribution: Suse
Posts: 56

Original Poster
Rep: Reputation: 15
Thanks for your complete fully-described reply I got it
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
mount: block device is write-protected, mounting read-only xpucto Linux - Server 6 03-07-2014 02:08 PM
Ultra slow write speed with custom linux "stacking" block device driver Agarwal6 Programming 4 09-02-2011 12:06 PM
Linux Driver - how to read/write a block or character device in kernel space (procfs) stybi Linux - Kernel 1 01-27-2011 06:26 AM
How to write a character device driver to read the processor's GDT kiranshadow Linux - General 1 05-10-2008 11:28 AM
"block device /dev/sda2 is write-protected, mounting read-only" - fstab problem blanks77 Linux - Hardware 1 04-28-2006 06:09 PM


All times are GMT -5. The time now is 12:11 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration