当前位置: 编程技术>移动开发
本页文章导读:
▪【C跟指针】#if 0 #end if 【C和指针】#if 0 #end if一,“#if 0/ #if 1 ... #endif” 的作用
1) code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if .........
▪ Core Data浅谈系列之二 : 容易的CURD Core Data浅谈系列之二 : 简单的CURD在上一篇中简单介绍了Core Data Stack,自上而下地对Core Data应用结构有个基本的认识,不过都是理论上的。这里就以上一篇的理论构建起一个可运行的Demo,执.........
▪ imx.536(cotex-a8核)的CAN驱动懂得一(probe) imx.536(cotex-a8核)的CAN驱动理解一(probe)//理解imx536的can驱动还是从probe开始吧,2.6版本内核can驱动是归属于网络驱动
//所以我得先去把网络驱动几个重要结构体先找出来吧。前进吧!年轻人。
s.........
[1]【C跟指针】#if 0 #end if
来源: 互联网 发布时间: 2014-02-18
【C和指针】#if 0 #end if
一,“#if 0/ #if 1 ... #endif” 的作用
1) code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if 0改成#if 1
2) #if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误
#if 1可以让其间的变量成为局部变量。
3) 这个结构表示你先前写好的code,现在用不上了,又不想删除,就用这个方法,比注释方便。
二,例子
#include <iostream> int main(void) { int a = 0; #if 0 a = 1; #endif printf("%d\n",a); return 0; }
[2] Core Data浅谈系列之二 : 容易的CURD
来源: 互联网 发布时间: 2014-02-18
Core Data浅谈系列之二 : 简单的CURD
在上一篇中简单介绍了Core Data Stack,自上而下地对Core Data应用结构有个基本的认识,不过都是理论上的。这里就以上一篇的理论构建起一个可运行的Demo,执行一些简单的增删改查操作。
(图片来自Apple)
首先,我们需要建立如上图的栈结构。因此,在ViewController里添加3个属性:
@interface ViewController : UIViewController @property (nonatomic, retain) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator; @end
根据前文讨论的顺序,我们首先创建managedObjectModel(在那之前需要引入CoreData Framework):
- (NSManagedObjectModel *)managedObjectModel { if (nil != _managedObjectModel) { return _managedObjectModel; } _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; return _managedObjectModel; }
接着创建NSManagedObject的生存环境 —— NSManagedObjectContext:
- (NSManagedObjectContext *)managedObjectContext { if (nil != _managedObjectContext) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; return _managedObjectContext; }
由于Demo会将数据存储到本地文件,所以还需要NSPersistentStoreCoordinator和NSManagedObjectContext配合。
下面是创建Core Data栈结构的完整代码:
#pragma mark - #pragma mark - Core Data Stack - (NSManagedObjectModel *)managedObjectModel { if (nil != _managedObjectModel) { return _managedObjectModel; } _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; return _managedObjectModel; } - (NSManagedObjectContext *)managedObjectContext { if (nil != _managedObjectContext) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; if (self.persistentStoreCoordinator) { [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; } return _managedObjectContext; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (nil != _persistentStoreCoordinator) { return _persistentStoreCoordinator; } NSString *storeType = NSSQLiteStoreType; NSString *storeName = @"cdNBA.sqlite"; NSError *error = NULL; NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:storeName]]; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel]; if (![_persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nilURL:storeURL options:nil error:&error]) { NSLog(@"Error : %@\n", [error localizedDescription]); NSAssert1(YES, @"Failed to create store %@ with NSSQLiteStoreType", [storeURL path]); } return _persistentStoreCoordinator; } #pragma mark - #pragma mark Application's Documents Directory - (NSString *)applicationDocumentsDirectory { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; return basePath; }
在搭建完基础的Core Data栈结构后,就可以写一些简单的CURD代码了:
#pragma mark - #pragma mark - CURD Operations - (BOOL)createTeamWithName:(NSString *)teamName city:(NSString *)teamCity { if (!teamName || !teamCity) { return NO; } NSManagedObject *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext]; [teamObject setValue:teamName forKey:@"name"]; [teamObject setValue:teamCity forKey:@"city"]; return YES; } - (NSArray *)fetchTeamList { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:[NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext]]; NSError *error = NULL; NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; if (error) { NSLog(@"Error : %@\n", [error localizedDescription]); } [fetchRequest release], fetchRequest = nil; return array; }
我们可以把读写的代码放到viewDidLoad函数中:
- (void)viewDidLoad { [superviewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self createTeamWithName:@"Heat"city:@"Miami"]; [self createTeamWithName:@"Lakers"city:@"LA"]; [self saveContext]; NSArray *teamArray = [self fetchTeamList]; if (teamArray) { for (NSManagedObject *teamObject in teamArray) { NSString *teamName = [teamObject valueForKey:@"name"]; NSString *teamCity = [teamObject valueForKey:@"city"]; NSLog(@"Team info : %@, %@\n", teamName, teamCity); } } }
由于在context中创建的对象只是存在于内存中,所以我们还需要显式地把数据保存到sqlite文件里:
#pragma mark - #pragma mark - Save Context - (void)saveContext { NSError *error = NULL; NSManagedObjectContext *moc = self.managedObjectContext; if (moc && [moc hasChanges] && ![moc save:&error]) { NSLog(@"Error %@, %@", error, [error localizedDescription]); abort(); } }
最后,就是跑一下Demo,检验一下结果。
执行过一次程序后,我们可以搜索下cdNBA.sqlite文件,然后查看里面的数据:
同时,控制台也输出了数据:
2013-01-16 14:32:52.638 cdNBA[4717:c07] Team info : Heat, Miami 2013-01-16 14:32:52.639 cdNBA[4717:c07] Team info : Lakers, LA
Brief Talk About Core Data Series, Part 2 : Simple CURD
Jason Lee @ Hangzhou
Blog : http://blog.csdn.net/jasonblog
Weibo : http://weibo.com/jasonmblog
[3] imx.536(cotex-a8核)的CAN驱动懂得一(probe)
来源: 互联网 发布时间: 2014-02-18
imx.536(cotex-a8核)的CAN驱动理解一(probe)
下面看看这个函数的代码,看它们都干了什么?
//理解imx536的can驱动还是从probe开始吧,2.6版本内核can驱动是归属于网络驱动 //所以我得先去把网络驱动几个重要结构体先找出来吧。前进吧!年轻人。 static struct platform_driver flexcan_driver = { .driver = { .name = FLEXCAN_DEVICE_NAME, }, .probe = flexcan_probe, .remove = flexcan_remove, .suspend = flexcan_suspend, .resume = flexcan_resume, };
下面看probe
static int flexcan_probe(struct platform_device *pdev) { //还是熟悉的struct net_device struct net_device *net; //这个函数估计得干大把大把的事吧,什么申请内存,什么初始化struct net_device及网络设备私有数据等 net = flexcan_device_alloc(pdev, flexcan_setup); if (!net) return -ENOMEM; //注册网络设备 if (register_netdev(net)) { flexcan_device_free(pdev); return -ENODEV; } return 0; }probe中主要是调用了flexcan_device_alloc,继续看flexcan_device_alloc
struct net_device *flexcan_device_alloc(struct platform_device *pdev, void (*setup) (struct net_device *dev)) { //can私有数据结构体 struct flexcan_device *flexcan; struct net_device *net; int i, num; //申请内存,初始化net net = alloc_netdev(sizeof(*flexcan), "can%d", setup); if (net == NULL) { printk(KERN_ERR "Allocate netdevice for FlexCAN fail!\n"); return NULL; } //flexcan指向net尾端,即私有数据结构体起始地址 flexcan = netdev_priv(net); memset(flexcan, 0, sizeof(*flexcan)); //互斥锁初始化 mutex_init(&flexcan->mutex); //初始化内核定时器 init_timer(&flexcan->timer); flexcan->dev = pdev; //注册中断,映射虚拟内存 if (flexcan_device_attach(flexcan)) { printk(KERN_ERR "Attach FlexCAN fail!\n"); free_netdev(net); return NULL; } //把板级配置文件中设置的struct flexcan_platform_data中的值,传递给flexcan flexcan_device_default(flexcan); //根据can的波特率去算br_presdiv,br_propseg,br_pseg1,br_pseg2这些变量的值 //因为flexcan->bitrate值未确定,所以在我的板上,这个函数不起效果 flexcan_set_bitrate(flexcan, flexcan->bitrate); //重新计算波特率,保存在flexcan flexcan_update_bitrate(flexcan); //ARRAY_SIZE作用是取数组元素个数 num = ARRAY_SIZE(flexcan_dev_attr); //device_create_file,添加属性文件,我的理解最终会设置文件系统sys目录下一些设备属性文件 //这些设备文件是在调用device_create时生成的。device_create这个函数什么时候调用的呢,这个就需要udev //udev是什么?udev是设备管理器,能自动生成设备节点。 //在dm9000驱动里不知道为什么没看到这个函数? for (i = 0; i < num; i++) { if (device_create_file(&pdev->dev, flexcan_dev_attr + i)) { printk(KERN_ERR "Create attribute file fail!\n"); break; } } //上面操作的反向操作 if (i != num) { for (; i >= 0; i--) device_remove_file(&pdev->dev, flexcan_dev_attr + i); free_netdev(net); return NULL; } //保存net为设备私有数据 dev_set_drvdata(&pdev->dev, net); return net; }flexcan_device_alloc中最重要的几个函数flexcan_device_attach,flexcan_device_default,flexcan_set_bitratef,lexcan_update_bitrate
下面看看这个函数的代码,看它们都干了什么?
static void flexcan_set_bitrate(struct flexcan_device *flexcan, int bitrate) { /* TODO:: implement in future * based on the bitrate to get the timing of * presdiv, pseg1, pseg2, propseg */ int i, rate, div; bool found = false; struct time_segment *segment; rate = clk_get_rate(flexcan->clk); if (!bitrate) bitrate = DEFAULT_BITRATE; //如果时钟正好是波特率的整数倍 if (rate % bitrate == 0) { //根据时钟是波特率的倍数去推算br_presdiv,br_propseg,br_pseg1,br_pseg2 div = rate / bitrate; for (i = TIME_SEGMENT_MID; i <= TIME_SEGMENT_MAX; i++) { if (div % i == 0) { found = true; break; } } if (!found) { for (i = TIME_SEGMENT_MID - 1; i >= TIME_SEGMENT_MIN; i--) { if (div % i == 0) { found = true; break; } } } } if (found) { //time_segments数组中列出了各种br_presdiv,br_propseg,br_pseg1,br_pseg2组合值 //根据以上推算,确定i值,从而确定br_presdiv,br_propseg,br_pseg1,br_pseg2的值 segment = &time_segments[i - TIME_SEGMENT_MIN]; flexcan->br_presdiv = div/i - 1; flexcan->br_propseg = segment->propseg; flexcan->br_pseg1 = segment->pseg1; flexcan->br_pseg2 = segment->pseg2; flexcan->bitrate = bitrate; } else { pr_info("The bitrate %d can't supported with clock \ rate of %d \n", bitrate, rate); } }
static void flexcan_update_bitrate(struct flexcan_device *flexcan) { int rate, div; //板级配置文件中设置的 struct flexcan_platform_data *plat_data; plat_data = flexcan->dev->dev.platform_data; //如果板级配置文件中,struct flexcan_platform_data中root_clk_id配置了 if (plat_data->root_clk_id) rate = clk_get_rate(flexcan->clk); else { //若struct flexcan_platform_data中root_clk_id未被配置,再看br_clksrc是否被配置成1 if (flexcan->br_clksrc) rate = clk_get_rate(flexcan->clk); //在我的imx536项目中,以上两个变量都未被配置,所以会执行以下代码 else { struct clk *clk; clk = clk_get(NULL, "ckih"); if (!clk) return; //获取can时钟频率 rate = clk_get_rate(clk); clk_put(clk); } } if (!rate) return; //计算can传输速率 //其中br_presdiv,br_propseg,br_pseg1,br_pseg2,这些参数都是在板级配置文件中设置的 //所以可以实现由用户自己配置CAN波特率 div = (flexcan->br_presdiv + 1); div *= (flexcan->br_propseg + flexcan->br_pseg1 + flexcan->br_pseg2 + 4); flexcan->bitrate = (rate + div - 1) / div; }
static int flexcan_device_attach(struct flexcan_device *flexcan) { int ret; struct resource *res; struct platform_device *pdev = flexcan->dev; struct flexcan_platform_data *plat_data = (pdev->dev).platform_data; struct clk *can_root_clk; //看到了熟悉的身影了 res = platform_get_resource(flexcan->dev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; //内存映射 flexcan->io_base = ioremap(res->start, res->end - res->start + 1); if (!flexcan->io_base) return -ENOMEM; //咋没直接注册中断? flexcan->irq = platform_get_irq(flexcan->dev, 0); if (!flexcan->irq) { ret = -ENODEV; goto no_irq_err; } ret = -EINVAL; if (plat_data) { if (plat_data->core_reg) { flexcan->core_reg = regulator_get(&pdev->dev, plat_data->core_reg); if (!flexcan->core_reg) goto plat_err; } if (plat_data->io_reg) { flexcan->io_reg = regulator_get(&pdev->dev, plat_data->io_reg); if (!flexcan->io_reg) goto plat_err; } } flexcan->clk = clk_get(&(flexcan->dev)->dev, "can_clk"); //如果板级配置文件中root_clk_id被配置了,can时钟源变成了root_clk_id if (plat_data->root_clk_id) { can_root_clk = clk_get(NULL, plat_data->root_clk_id); clk_set_parent(flexcan->clk, can_root_clk); } flexcan->hwmb = (struct can_hw_mb *)(flexcan->io_base + CAN_MB_BASE); flexcan->rx_mask = (unsigned int *)(flexcan->io_base + CAN_RXMASK_BASE); return 0; //以后得多学学内核纠错处理了 plat_err: if (flexcan->core_reg) { regulator_put(flexcan->core_reg); flexcan->core_reg = NULL; } no_irq_err: if (flexcan->io_base) iounmap(flexcan->io_base); return ret; }
最新技术文章: