Changeset d2ff24c2 in rtems
- Timestamp:
- 11/21/07 06:20:49 (16 years ago)
- Branches:
- 4.10, 4.11, 4.9, 5, master
- Children:
- d371a97
- Parents:
- 381a2f18
- Location:
- cpukit
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/ChangeLog
r381a2f18 rd2ff24c2 1 2007-11-17 Till Straumann <strauman@slac.stanford.edu> 2 3 * libi2c/libi2c.c, libi2c/libi2c.h, libi2c/README_libi2c: 4 Added checks so that use of 'stdio' is avoided (falling 5 back to 'printk') before the system is up. 6 Publish driver entry points so that the libi2c driver could 7 be added to the applications 'device driver table'. 8 This is not fully implemented yet, though, since in addition to 9 initializing libi2c the low-level i2c bus drivers as well 10 as high-level i2c device drivers need to be registered 11 with the library. 12 Updated README_libi2c accordingly. 13 1 14 2007-11-17 Till Straumann <strauman@slac.stanford.edu> 2 15 -
cpukit/libi2c/README_libi2c
r381a2f18 rd2ff24c2 109 109 110 110 Typically the BSP startup code will perform this initialization. 111 112 A proper place for initializing the i2c layer and populating it 113 with busses and device drivers (see 'Bus Registration' and 114 'Device/Driver Registration' below) is the 'predriver_hook' 115 where most facilities (such as malloc, libio) are already 116 available. Note, however, that 'stdio' is not yet functional 117 at this point and all i2c bus and device drivers should carefully 118 avoid using stdio so that other drivers which may build on top 119 of i2c devices may be initialized properly (this may happen 120 just after 'predriver_hook' when stdio is still not available). 121 E.g., drivers listed in the configuration table are initialized 122 during this step. 123 124 Note that while 'libi2c' could be initialized from the rtems 125 configuration table like other drivers there is no easy 126 way of populating the i2c framework with bus- and device- 127 drivers at this point (unless a special 'i2c' configuration 128 table describing the bus layout is implemented in the future). 129 130 For the time being, we must rely on the BSP (predriver_hook) 131 to initialize the i2c system if it is used by other drivers 132 (e.g., the RTC driver may have to use a i2c device). 111 133 112 134 =================== -
cpukit/libi2c/libi2c.c
r381a2f18 rd2ff24c2 64 64 #include <rtems.h> 65 65 #include <rtems/error.h> 66 #include <rtems/bspIo.h> 66 67 #include <rtems/libio.h> 67 68 … … 104 105 rtems_device_major_number rtems_libi2c_major; 105 106 107 static boolean is_initialized = FALSE; 108 106 109 static struct i2cbus 107 110 { … … 133 136 |RTEMS_LOCAL ) 134 137 135 static rtems_id 136 mutexCreate (rtems_name nm) 138 /* During early stages of life, stdio is not available */ 139 140 static void 141 safe_printf (const char *fmt, ...) 142 { 143 va_list ap; 144 145 va_start(ap, fmt); 146 if ( _System_state_Is_up( _System_state_Get() ) ) 147 vfprintf( stderr, fmt, ap ); 148 else 149 vprintk( fmt, ap ); 150 va_end(ap); 151 } 152 153 static rtems_status_code 154 mutexCreate (rtems_name nm, rtems_id *pm) 137 155 { 138 156 rtems_status_code sc; 139 rtems_id rval; 157 140 158 if (RTEMS_SUCCESSFUL != 141 (sc = rtems_semaphore_create (nm, 1, MUTEX_ATTS, 0, &rval))) { 142 rtems_error (sc, DRVNM " unable to create mutex\n"); 143 return 0; 144 } 145 return rval; 159 (sc = rtems_semaphore_create (nm, 1, MUTEX_ATTS, 0, pm))) { 160 if ( _System_state_Is_up( _System_state_Get() ) ) 161 rtems_error (sc, DRVNM " unable to create mutex\n"); 162 else 163 printk (DRVNM " unable to crate mutex (status code %i)\n", sc); 164 } 165 return sc; 146 166 } 147 167 … … 156 176 lock_bus (int busno) 157 177 { 158 struct i2cbus *bus = &busses[busno]; 178 rtems_status_code sc; 179 struct i2cbus *bus = &busses[busno]; 180 159 181 LIBLOCK (); 160 182 if (!bus->waiting) { 183 rtems_id m; 161 184 /* nobody is holding the bus mutex - it's not there. Create it on the fly */ 162 if (! 163 (bus->mutex = 164 mutexCreate (rtems_build_name ('i', '2', 'c', '0' + busno)))) { 185 sc = mutexCreate (rtems_build_name ('i', '2', 'c', '0' + busno), &m); 186 if ( RTEMS_SUCCESSFUL != sc ) { 165 187 LIBUNLOCK (); 166 188 rtems_panic (DRVNM " unable to create bus lock"); 167 } 189 } else { 190 bus->mutex = m; 191 } 168 192 } 169 193 /* count number of people waiting on this bus; only the last one deletes the mutex */ … … 187 211 188 212 /* Note that 'arg' is always passed in as NULL */ 189 staticrtems_status_code190 i2c_init (rtems_device_major_number major, rtems_device_minor_number minor,213 rtems_status_code 214 rtems_i2c_init (rtems_device_major_number major, rtems_device_minor_number minor, 191 215 void *arg) 192 216 { 193 217 rtems_status_code rval; 218 /* No busses or drivers can be registered at this point; 219 * avoid the macro aborting with an error 194 220 DECL_CHECKED_DRV (drv, busno, minor) 195 196 if (0 == drv) { 197 rval = 0; 221 */ 222 223 rval = mutexCreate (rtems_build_name ('l', 'I', '2', 'C'), &libmutex); 224 225 if ( RTEMS_SUCCESSFUL == rval ) { 226 is_initialized = TRUE; 227 rtems_libi2c_major = major; 198 228 } else { 199 /* this is probably never called */ 200 DISPATCH (rval, initialization_entry, RTEMS_SUCCESSFUL); 201 } 202 return rval; 203 } 204 205 static rtems_status_code 206 i2c_open (rtems_device_major_number major, rtems_device_minor_number minor, 229 libmutex = 0; 230 } 231 return rval; 232 } 233 234 rtems_status_code 235 rtems_i2c_open (rtems_device_major_number major, rtems_device_minor_number minor, 207 236 void *arg) 208 237 { … … 218 247 } 219 248 220 staticrtems_status_code221 i2c_close (rtems_device_major_number major, rtems_device_minor_number minor,249 rtems_status_code 250 rtems_i2c_close (rtems_device_major_number major, rtems_device_minor_number minor, 222 251 void *arg) 223 252 { … … 233 262 } 234 263 235 staticrtems_status_code236 i2c_read (rtems_device_major_number major, rtems_device_minor_number minor,264 rtems_status_code 265 rtems_i2c_read (rtems_device_major_number major, rtems_device_minor_number minor, 237 266 void *arg) 238 267 { … … 263 292 } 264 293 265 staticrtems_status_code266 i2c_write (rtems_device_major_number major, rtems_device_minor_number minor,294 rtems_status_code 295 rtems_i2c_write (rtems_device_major_number major, rtems_device_minor_number minor, 267 296 void *arg) 268 297 { … … 293 322 } 294 323 295 staticrtems_status_code296 i2c_ioctl (rtems_device_major_number major, rtems_device_minor_number minor,324 rtems_status_code 325 rtems_i2c_ioctl (rtems_device_major_number major, rtems_device_minor_number minor, 297 326 void *arg) 298 327 { … … 310 339 311 340 /* Our ops just dispatch to the registered drivers */ 312 static rtems_driver_address_tablelibi2c_io_ops = {313 initialization_entry: i2c_init,314 open_entry: i2c_open,315 close_entry: i2c_close,316 read_entry: i2c_read,317 write_entry: i2c_write,318 control_entry: i2c_ioctl,341 rtems_driver_address_table rtems_libi2c_io_ops = { 342 initialization_entry: rtems_i2c_init, 343 open_entry: rtems_i2c_open, 344 close_entry: rtems_i2c_close, 345 read_entry: rtems_i2c_read, 346 write_entry: rtems_i2c_write, 347 control_entry: rtems_i2c_ioctl, 319 348 }; 320 321 349 322 350 int … … 324 352 { 325 353 rtems_status_code sc; 326 static boolean is_initialized = FALSE;327 354 328 355 if (is_initialized) { … … 333 360 } 334 361 335 if (!(libmutex = mutexCreate (rtems_build_name ('l', 'I', '2', 'C')))) 336 return -1; 337 338 sc = rtems_io_register_driver (0, &libi2c_io_ops, &rtems_libi2c_major); 362 /* rtems_io_register_driver does NOT currently check nor report back 363 * the return code of the 'init' operation, so we cannot 364 * rely on return code since it may seem OK even if the driver 'init; 365 * op failed. 366 * Let 'init' handle 'is_initialized'... 367 */ 368 sc = rtems_io_register_driver (0, &rtems_libi2c_io_ops, &rtems_libi2c_major); 339 369 if (RTEMS_SUCCESSFUL != sc) { 340 fprintf (stderr,370 safe_printf( 341 371 DRVNM " Claiming driver slot failed (rtems status code %i)\n", 342 372 sc); 343 rtems_semaphore_delete (libmutex); 373 if ( libmutex ) 374 rtems_semaphore_delete (libmutex); 344 375 libmutex = 0; 376 is_initialized = FALSE; 345 377 return -1; 346 378 } 347 is_initialized = TRUE;348 379 349 380 return 0; … … 364 395 /* check */ 365 396 if ('/' != *nmcpy) { 366 fprintf (stderr, 367 "Bad name; must be an absolute path starting with '/'\n"); 397 safe_printf ( DRVNM "Bad name; must be an absolute path starting with '/'\n"); 368 398 return -RTEMS_INVALID_NAME; 369 399 } 370 400 /* file must not exist */ 371 401 if (!stat (nmcpy, &sbuf)) { 372 fprintf (stderr,"Bad name; file exists already\n");402 safe_printf ( DRVNM "Bad name; file exists already\n"); 373 403 return -RTEMS_INVALID_NAME; 374 404 } … … 381 411 *chpt = tmp; 382 412 if (i) { 383 fprintf (stderr,"Get %s status failed: %s\n",384 nmcpy, strerror(errno));413 safe_printf ( DRVNM "Get %s status failed: %s\n", 414 nmcpy, strerror(errno)); 385 415 return -RTEMS_INVALID_NAME; 386 416 } … … 389 419 390 420 if (!libmutex) { 391 fprintf (stderr,DRVNM " library not initialized\n");421 safe_printf ( DRVNM " library not initialized\n"); 392 422 return -RTEMS_NOT_DEFINED; 393 423 } 394 424 395 425 if (bus->size < sizeof (*bus)) { 396 fprintf (stderr,DRVNM " bus-ops size too small -- misconfiguration?\n");426 safe_printf ( DRVNM " bus-ops size too small -- misconfiguration?\n"); 397 427 return -RTEMS_NOT_CONFIGURED; 398 428 } … … 654 684 655 685 if (!libmutex) { 656 fprintf (stderr,DRVNM " library not initialized\n");686 safe_printf ( DRVNM " library not initialized\n"); 657 687 return -RTEMS_NOT_DEFINED; 658 688 } 659 689 660 690 if (name && strchr (name, '/')) { 661 fprintf (stderr,"Invalid name: '%s' -- must not contain '/'\n", name);691 safe_printf ( DRVNM "Invalid name: '%s' -- must not contain '/'\n", name); 662 692 return -RTEMS_INVALID_NAME; 663 693 } … … 669 699 670 700 if (drvtbl->size < sizeof (*drvtbl)) { 671 fprintf (stderr,DRVNM " drv-ops size too small -- misconfiguration?\n");701 safe_printf ( DRVNM " drv-ops size too small -- misconfiguration?\n"); 672 702 return -RTEMS_NOT_CONFIGURED; 673 703 } … … 699 729 /* note that 'umask' is applied to 'mode' */ 700 730 if (mknod (str, mode, dev)) { 701 fprintf (stderr,731 safe_printf( DRVNM 702 732 "Creating device node failed: %s; you can try to do it manually...\n", 703 733 strerror (errno)); -
cpukit/libi2c/libi2c.h
r381a2f18 rd2ff24c2 60 60 /* Initialize the libary - may fail if no semaphore or no driver slot is available */ 61 61 int rtems_libi2c_initialize (); 62 63 /* Alternatively to rtems_libi2c_initialize() the library can also be 64 * initialized by means of a traditional driver table entry containing 65 * the following entry points: 66 */ 67 rtems_status_code 68 rtems_i2c_init ( 69 rtems_device_major_number major, 70 rtems_device_minor_number minor, 71 void *arg); 72 73 rtems_status_code 74 rtems_i2c_open ( 75 rtems_device_major_number major, 76 rtems_device_minor_number minor, 77 void *arg); 78 79 rtems_status_code 80 rtems_i2c_close ( 81 rtems_device_major_number major, 82 rtems_device_minor_number minor, 83 void *arg); 84 85 rtems_status_code 86 rtems_i2c_read ( 87 rtems_device_major_number major, 88 rtems_device_minor_number minor, 89 void *arg); 90 91 rtems_status_code 92 rtems_i2c_write ( 93 rtems_device_major_number major, 94 rtems_device_minor_number minor, 95 void *arg); 96 97 rtems_status_code 98 rtems_i2c_ioctl ( 99 rtems_device_major_number major, 100 rtems_device_minor_number minor, 101 void *arg); 102 103 extern rtems_driver_address_table rtems_libi2c_io_ops; 104 105 /* Unfortunately, if you want to add this driver to 106 * a RTEMS configuration table then you need all the 107 * members explicitly :-( (Device_driver_table should 108 * hold pointers to rtems_driver_address_tables rather 109 * than full structs). 110 * 111 * The difficulty is that adding this driver to the 112 * configuration table is not enough; you still need 113 * to populate the framework with low-level bus-driver(s) 114 * and high-level drivers and/or device-files... 115 * 116 * Currently the preferred way is having the BSP 117 * call 'rtems_libi2c_initialize' followed by 118 * 'rtems_libi2c_register_bus' and 119 * 'rtems_libi2c_register_drv' and/or 120 * 'mknod' (for 'raw' device nodes) 121 * from the 'pretasking_hook'. 122 */ 123 #define RTEMS_LIBI2C_DRIVER_TABLE_ENTRY \ 124 { \ 125 initialization_entry: rtems_i2c_init, \ 126 open_entry: rtems_i2c_open, \ 127 close_entry: rtems_i2c_close, \ 128 read_entry: rtems_i2c_read, \ 129 write_entry: rtems_i2c_write, \ 130 control_entry: rtems_i2c_ioctl, \ 131 } 62 132 63 133 /* Bus Driver API
Note: See TracChangeset
for help on using the changeset viewer.